fix: right-size service memory after PVE RAM upgrade (142→272GB)
- MySQL InnoDB: 2Gi/4Gi → 3Gi/6Gi (was at 97% of limit) - Redis HAProxy: 16Mi/16Mi → 32Mi/64Mi (OOMKilled) - Plotting-book: 64Mi/64Mi → 128Mi/256Mi (OOMKilled) - Tandoor: 256Mi/256Mi → 384Mi/512Mi (60 OOM restarts), re-enabled - Navidrome: 128Mi/128Mi → 256Mi/384Mi - Matrix: add explicit 256Mi/512Mi resources - Trading-bot workers: 64Mi/64Mi → 128Mi/256Mi, re-enabled - Tier 3-edge defaults: 96Mi/192Mi → 128Mi/256Mi - Fallback tier defaults: 128Mi/128Mi → 128Mi/192Mi, max 2→4Gi - Mailserver: disable rspamd-redis, fix Roundcube IPv6/IMAP, bump dovecot connections
This commit is contained in:
parent
825adc4a67
commit
4da8f0242f
10 changed files with 113 additions and 98 deletions
|
|
@ -35,8 +35,8 @@ resource "kubernetes_resource_quota" "dbaas" {
|
||||||
spec {
|
spec {
|
||||||
hard = {
|
hard = {
|
||||||
"requests.cpu" = "8"
|
"requests.cpu" = "8"
|
||||||
"requests.memory" = "27Gi"
|
"requests.memory" = "32Gi"
|
||||||
"limits.memory" = "27Gi"
|
"limits.memory" = "32Gi"
|
||||||
pods = "30"
|
pods = "30"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,11 +228,11 @@ resource "helm_release" "mysql_cluster" {
|
||||||
name = "mysql"
|
name = "mysql"
|
||||||
resources = {
|
resources = {
|
||||||
requests = {
|
requests = {
|
||||||
memory = "2Gi"
|
memory = "3Gi"
|
||||||
cpu = "250m"
|
cpu = "250m"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "4Gi"
|
memory = "6Gi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|
|
||||||
|
|
@ -315,14 +315,14 @@ resource "kubernetes_manifest" "generate_limitrange_by_tier" {
|
||||||
{
|
{
|
||||||
type = "Container"
|
type = "Container"
|
||||||
default = {
|
default = {
|
||||||
memory = "192Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
defaultRequest = {
|
defaultRequest = {
|
||||||
cpu = "50m"
|
cpu = "50m"
|
||||||
memory = "96Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
max = {
|
max = {
|
||||||
memory = "4Gi"
|
memory = "8Gi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -433,14 +433,14 @@ resource "kubernetes_manifest" "generate_limitrange_by_tier" {
|
||||||
{
|
{
|
||||||
type = "Container"
|
type = "Container"
|
||||||
default = {
|
default = {
|
||||||
memory = "128Mi"
|
memory = "192Mi"
|
||||||
}
|
}
|
||||||
defaultRequest = {
|
defaultRequest = {
|
||||||
cpu = "50m"
|
cpu = "50m"
|
||||||
memory = "128Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
max = {
|
max = {
|
||||||
memory = "2Gi"
|
memory = "4Gi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,10 @@ resource "kubernetes_config_map" "mailserver_config" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
# Increase max IMAP connections per user+IP - all Roundcube connections come from same pod IP
|
||||||
|
"dovecot.cf" = <<-EOF
|
||||||
|
mail_max_userip_connections = 50
|
||||||
|
EOF
|
||||||
fail2ban_conf = <<-EOF
|
fail2ban_conf = <<-EOF
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
|
|
@ -286,12 +290,12 @@ resource "kubernetes_deployment" "mailserver" {
|
||||||
sub_path = "fetchmail.cf"
|
sub_path = "fetchmail.cf"
|
||||||
read_only = true
|
read_only = true
|
||||||
}
|
}
|
||||||
# volume_mount {
|
volume_mount {
|
||||||
# name = "config"
|
name = "config"
|
||||||
# mount_path = "/tmp/docker-mailserver/dovecot.cf"
|
mount_path = "/tmp/docker-mailserver/dovecot.cf"
|
||||||
# sub_path = "dovecot.cf"
|
sub_path = "dovecot.cf"
|
||||||
# read_only = true
|
read_only = true
|
||||||
# }
|
}
|
||||||
# volume_mount {
|
# volume_mount {
|
||||||
# name = "user-patches"
|
# name = "user-patches"
|
||||||
# mount_path = "/tmp/user-patches.sh"
|
# mount_path = "/tmp/user-patches.sh"
|
||||||
|
|
|
||||||
|
|
@ -20,30 +20,40 @@ module "nfs_roundcube_enigma" {
|
||||||
nfs_path = "/mnt/main/roundcubemail/enigma"
|
nfs_path = "/mnt/main/roundcubemail/enigma"
|
||||||
}
|
}
|
||||||
|
|
||||||
# If you want to override settings mount this in /var/roundcube/config
|
resource "kubernetes_config_map" "roundcubemail_config" {
|
||||||
# more info in https://github.com/roundcube/roundcubemail-docker?tab=readme-ov-file
|
metadata {
|
||||||
# resource "kubernetes_config_map" "roundcubemail_config" {
|
name = "roundcubemail.config"
|
||||||
# metadata {
|
namespace = "mailserver"
|
||||||
# name = "roundcubemail.config"
|
|
||||||
# namespace = "mailserver"
|
|
||||||
|
|
||||||
# labels = {
|
labels = {
|
||||||
# app = "mailserver"
|
app = "roundcubemail"
|
||||||
# }
|
}
|
||||||
# annotations = {
|
annotations = {
|
||||||
# "reloader.stakater.com/match" = "true"
|
"reloader.stakater.com/match" = "true"
|
||||||
# }
|
}
|
||||||
# }
|
}
|
||||||
|
|
||||||
# data = {
|
data = {
|
||||||
# # if you want to override things see https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php
|
# Disable TLS peer verification for internal service name connections
|
||||||
# "imap.php" = <<-EOF
|
# The mailserver cert is issued for mail.viktorbarzin.me, not the k8s service name
|
||||||
# <?php
|
"custom.php" = <<-EOF
|
||||||
# $config['imap_host'] = 'ssl://mail.viktorbarzin.me:993';
|
<?php
|
||||||
# ?>
|
$config['imap_conn_options'] = [
|
||||||
# EOF
|
'ssl' => [
|
||||||
# }
|
'verify_peer' => false,
|
||||||
# }
|
'verify_peer_name' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$config['smtp_conn_options'] = [
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
resource "kubernetes_persistent_volume_claim" "roundcube_html_proxmox" {
|
resource "kubernetes_persistent_volume_claim" "roundcube_html_proxmox" {
|
||||||
|
|
@ -122,15 +132,14 @@ resource "kubernetes_deployment" "roundcubemail" {
|
||||||
container {
|
container {
|
||||||
name = "roundcube"
|
name = "roundcube"
|
||||||
image = "roundcube/roundcubemail:1.6.13-apache"
|
image = "roundcube/roundcubemail:1.6.13-apache"
|
||||||
# Uncomment me to mount additional settings
|
volume_mount {
|
||||||
# volume_mount {
|
name = "roundcube-config"
|
||||||
# name = "imap-config"
|
mount_path = "/var/roundcube/config/custom.php"
|
||||||
# mount_path = "/var/roundcube/config/imap.php"
|
sub_path = "custom.php"
|
||||||
# sub_path = "imap.php"
|
}
|
||||||
# }
|
|
||||||
env {
|
env {
|
||||||
name = "ROUNDCUBEMAIL_DEFAULT_HOST"
|
name = "ROUNDCUBEMAIL_DEFAULT_HOST"
|
||||||
value = "ssl://mail.viktorbarzin.me" # tls cert must be valid!
|
value = "ssl://mailserver" # internal k8s service name
|
||||||
}
|
}
|
||||||
env {
|
env {
|
||||||
name = "ROUNDCUBEMAIL_DEFAULT_PORT"
|
name = "ROUNDCUBEMAIL_DEFAULT_PORT"
|
||||||
|
|
@ -138,7 +147,7 @@ resource "kubernetes_deployment" "roundcubemail" {
|
||||||
}
|
}
|
||||||
env {
|
env {
|
||||||
name = "ROUNDCUBEMAIL_SMTP_SERVER"
|
name = "ROUNDCUBEMAIL_SMTP_SERVER"
|
||||||
value = "tls://mail.viktorbarzin.me" # tls cert must be valid!
|
value = "tls://mailserver" # internal k8s service name
|
||||||
}
|
}
|
||||||
|
|
||||||
env {
|
env {
|
||||||
|
|
@ -210,12 +219,12 @@ resource "kubernetes_deployment" "roundcubemail" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# volume {
|
volume {
|
||||||
# name = "imap-config"
|
name = "roundcube-config"
|
||||||
# config_map {
|
config_map {
|
||||||
# name = "roundcubemail.config"
|
name = kubernetes_config_map.roundcubemail_config.metadata[0].name
|
||||||
# }
|
}
|
||||||
# }
|
}
|
||||||
|
|
||||||
volume {
|
volume {
|
||||||
name = "html"
|
name = "html"
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,15 @@ resource "kubernetes_deployment" "matrix" {
|
||||||
name = "extra-packages"
|
name = "extra-packages"
|
||||||
mount_path = "/extra-packages"
|
mount_path = "/extra-packages"
|
||||||
}
|
}
|
||||||
|
resources {
|
||||||
|
requests = {
|
||||||
|
cpu = "25m"
|
||||||
|
memory = "256Mi"
|
||||||
|
}
|
||||||
|
limits = {
|
||||||
|
memory = "512Mi"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
volume {
|
volume {
|
||||||
name = "data"
|
name = "data"
|
||||||
|
|
|
||||||
|
|
@ -172,10 +172,10 @@ resource "kubernetes_deployment" "navidrome" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "15m"
|
cpu = "15m"
|
||||||
memory = "128Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "128Mi"
|
memory = "384Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,11 +156,11 @@ resource "kubernetes_deployment" "plotting-book" {
|
||||||
}
|
}
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,9 +109,9 @@ resource "helm_release" "redis" {
|
||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use the existing service name so clients don't need changes
|
# Disable the Helm chart's ClusterIP service — we manage our own
|
||||||
# Sentinel-enabled Bitnami chart creates a headless service
|
# that points to HAProxy (master-only routing). The headless service
|
||||||
# and a regular service pointing at the master
|
# is still needed for StatefulSet pod DNS resolution.
|
||||||
nameOverride = "redis"
|
nameOverride = "redis"
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
|
|
@ -209,10 +209,10 @@ resource "kubernetes_deployment" "haproxy" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "16Mi"
|
memory = "32Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "16Mi"
|
memory = "64Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
liveness_probe {
|
liveness_probe {
|
||||||
|
|
@ -236,28 +236,24 @@ resource "kubernetes_deployment" "haproxy" {
|
||||||
depends_on = [helm_release.redis]
|
depends_on = [helm_release.redis]
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "kubernetes_service" "redis" {
|
# The Helm chart creates a `redis` Service that selects all nodes (master + replica),
|
||||||
metadata {
|
# causing READONLY errors when clients hit the replica. We patch it post-Helm to
|
||||||
name = "redis"
|
# route through HAProxy instead, which health-checks and routes only to the master.
|
||||||
namespace = kubernetes_namespace.redis.metadata[0].name
|
# This runs on every apply to ensure the Helm chart's service is always corrected.
|
||||||
}
|
resource "null_resource" "patch_redis_service" {
|
||||||
spec {
|
triggers = {
|
||||||
selector = {
|
always = timestamp()
|
||||||
app = "redis-haproxy"
|
|
||||||
}
|
|
||||||
port {
|
|
||||||
name = "tcp-redis"
|
|
||||||
port = 6379
|
|
||||||
target_port = 6379
|
|
||||||
}
|
|
||||||
port {
|
|
||||||
name = "tcp-sentinel"
|
|
||||||
port = 26379
|
|
||||||
target_port = 26379
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
depends_on = [kubernetes_deployment.haproxy]
|
provisioner "local-exec" {
|
||||||
|
command = <<-EOT
|
||||||
|
kubectl --kubeconfig=${abspath("${path.module}/../../../../config")} \
|
||||||
|
patch svc redis -n redis --type='json' \
|
||||||
|
-p='[{"op":"replace","path":"/spec/selector","value":{"app":"redis-haproxy"}}]'
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [helm_release.redis, kubernetes_deployment.haproxy]
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nfs_backup" {
|
module "nfs_backup" {
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,7 @@ resource "kubernetes_deployment" "tandoor" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
replicas = 1
|
||||||
replicas = 0
|
|
||||||
strategy {
|
strategy {
|
||||||
type = "Recreate"
|
type = "Recreate"
|
||||||
}
|
}
|
||||||
|
|
@ -212,10 +211,10 @@ resource "kubernetes_deployment" "tandoor" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "25m"
|
cpu = "25m"
|
||||||
memory = "256Mi"
|
memory = "384Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "256Mi"
|
memory = "512Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -231,8 +231,7 @@ resource "kubernetes_deployment" "trading-bot-frontend" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
replicas = 1
|
||||||
replicas = 0
|
|
||||||
strategy {
|
strategy {
|
||||||
type = "RollingUpdate"
|
type = "RollingUpdate"
|
||||||
rolling_update {
|
rolling_update {
|
||||||
|
|
@ -335,8 +334,7 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
replicas = 1
|
||||||
replicas = 0
|
|
||||||
strategy {
|
strategy {
|
||||||
type = "Recreate"
|
type = "Recreate"
|
||||||
}
|
}
|
||||||
|
|
@ -384,10 +382,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -456,10 +454,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -492,10 +490,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -528,10 +526,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -564,10 +562,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
||||||
resources {
|
resources {
|
||||||
requests = {
|
requests = {
|
||||||
cpu = "10m"
|
cpu = "10m"
|
||||||
memory = "64Mi"
|
memory = "128Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
limits = {
|
||||||
memory = "64Mi"
|
memory = "256Mi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue