From b34450b22ec0bbb9335e028289334c9aceacc334 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Thu, 20 Aug 2026 06:30:23 +0200 Subject: [PATCH] fix: make small scratch emptyDirs RAM-backed instead of node-disk Follow-up to the trmnl renderer finding. An `emptyDir` without `medium: Memory` is NODE STORAGE, which is easy to read as "ephemeral, therefore free" -- it is ephemeral, but every byte still hits the node's disk. Survey of the repo: 23 emptyDir declarations, only 2 RAM-backed. This converts 12 of the remaining ones. HONEST SCOPE: this buys almost no write reduction. Ranking every pod by OS-disk writes over 6h shows trmnl-renderer at 67 GB/day (fixed separately) and then nothing emptyDir-driven -- the rest of the top of that list is Ceph mons (hostPath, not emptyDir), kube-apiserver, and container logs from databases. Every volume converted here measured 8.0K in the running pod: /var/lib/code-server 8.0K /mosquitto/auth 8.0K /state (z2m guards) 8.0K So the value is correctness and, for mosquitto, keeping credential material off the node's filesystem: that volume holds the generated passwd/acl files. Each converted volume gets an explicit sizeLimit (16Mi where none existed), so tmpfs cannot silently consume a container's memory limit. All are orders of magnitude above measured usage. Behaviour is unchanged otherwise: an emptyDir persists for the pod's lifetime on either medium, so the mosquitto shim's assumption that the passwd file survives a container restart still holds. DELIBERATELY NOT CONVERTED: - kubernetes/talos/cilium.yaml and talos/patches/cilium-cni.yaml -- vendored and generated from the chart; a hand edit would be lost on upgrade. - trmnl/renderer.yaml -- converted separately, where the actual 34 GB/day was. Cost: this rolls the affected pods once. Refs #434 Co-Authored-By: Claude Opus 5 (1M context) --- kubernetes/apps/audiobookshelf/deployment.yaml | 4 +++- kubernetes/apps/home-assistant/deployment.yaml | 8 ++++++-- kubernetes/apps/home-assistant/mosquitto-deployment.yaml | 4 +++- .../apps/home-assistant/zigbee2mqtt-deployment.yaml | 8 ++++++-- kubernetes/apps/immich/server.yaml | 4 +++- kubernetes/apps/monitoring/pve-exporter-deployment.yaml | 4 +++- kubernetes/apps/paperless/paperless.yaml | 4 +++- kubernetes/infrastructure/netbird-ingress/daemonset.yaml | 4 +++- kubernetes/infrastructure/rook-ceph-cluster/toolbox.yaml | 4 +++- .../infrastructure/velero/restore-test-cronjob.yaml | 4 +++- 10 files changed, 36 insertions(+), 12 deletions(-) diff --git a/kubernetes/apps/audiobookshelf/deployment.yaml b/kubernetes/apps/audiobookshelf/deployment.yaml index 88a0675b..2e4f98b5 100644 --- a/kubernetes/apps/audiobookshelf/deployment.yaml +++ b/kubernetes/apps/audiobookshelf/deployment.yaml @@ -121,7 +121,9 @@ spec: persistentVolumeClaim: claimName: audiobookshelf-books - name: le-ca - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi --- apiVersion: v1 kind: Service diff --git a/kubernetes/apps/home-assistant/deployment.yaml b/kubernetes/apps/home-assistant/deployment.yaml index 81b13ee3..eccbf9aa 100644 --- a/kubernetes/apps/home-assistant/deployment.yaml +++ b/kubernetes/apps/home-assistant/deployment.yaml @@ -279,9 +279,13 @@ spec: # Writable emptyDir for the nginx entrypoint's envsubst output # (/etc/nginx/conf.d/default.conf rendered from the .template). - name: proxy-conf-d - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi # code-server's settings/extensions cache. Not on the config PVC # so installed extensions don't pollute HA's /config listing. # Trade-off: extensions reset across pod restarts. - name: vscode-state - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi diff --git a/kubernetes/apps/home-assistant/mosquitto-deployment.yaml b/kubernetes/apps/home-assistant/mosquitto-deployment.yaml index e3af8233..fe6ee85b 100644 --- a/kubernetes/apps/home-assistant/mosquitto-deployment.yaml +++ b/kubernetes/apps/home-assistant/mosquitto-deployment.yaml @@ -313,7 +313,9 @@ spec: configMap: name: mosquitto-config - name: auth - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi - name: tls secret: secretName: mosquitto-tls diff --git a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml index d463a7e8..84a1eebc 100644 --- a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml +++ b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml @@ -344,9 +344,13 @@ spec: configMap: name: zigbee2mqtt-interview-watch-script - name: interview-watch-state - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi - name: discovery-guard-script configMap: name: zigbee2mqtt-discovery-guard-script - name: discovery-guard-state - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi diff --git a/kubernetes/apps/immich/server.yaml b/kubernetes/apps/immich/server.yaml index a024f4d1..224ef715 100644 --- a/kubernetes/apps/immich/server.yaml +++ b/kubernetes/apps/immich/server.yaml @@ -147,7 +147,9 @@ spec: - key: immich-config.json path: immich-config.json - name: le-ca - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi --- apiVersion: v1 kind: Service diff --git a/kubernetes/apps/monitoring/pve-exporter-deployment.yaml b/kubernetes/apps/monitoring/pve-exporter-deployment.yaml index 4c8ee909..dbb3de57 100644 --- a/kubernetes/apps/monitoring/pve-exporter-deployment.yaml +++ b/kubernetes/apps/monitoring/pve-exporter-deployment.yaml @@ -64,7 +64,9 @@ spec: secret: secretName: pve-exporter-config - name: tmp - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi --- apiVersion: v1 kind: Service diff --git a/kubernetes/apps/paperless/paperless.yaml b/kubernetes/apps/paperless/paperless.yaml index af7d7fca..762d2e29 100644 --- a/kubernetes/apps/paperless/paperless.yaml +++ b/kubernetes/apps/paperless/paperless.yaml @@ -218,7 +218,9 @@ spec: persistentVolumeClaim: claimName: paperless-consume - name: bridge-cert - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi --- apiVersion: v1 kind: Service diff --git a/kubernetes/infrastructure/netbird-ingress/daemonset.yaml b/kubernetes/infrastructure/netbird-ingress/daemonset.yaml index 5cded1d4..d5e38bbc 100644 --- a/kubernetes/infrastructure/netbird-ingress/daemonset.yaml +++ b/kubernetes/infrastructure/netbird-ingress/daemonset.yaml @@ -156,4 +156,6 @@ spec: # each pod enrolls its own peer and a restart re-enrolls cleanly # (the old peer is reaped). - name: state - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi diff --git a/kubernetes/infrastructure/rook-ceph-cluster/toolbox.yaml b/kubernetes/infrastructure/rook-ceph-cluster/toolbox.yaml index 99cd3dd5..6d62dd3c 100644 --- a/kubernetes/infrastructure/rook-ceph-cluster/toolbox.yaml +++ b/kubernetes/infrastructure/rook-ceph-cluster/toolbox.yaml @@ -164,7 +164,9 @@ spec: name: rook-config-override optional: true - name: ceph-config - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" diff --git a/kubernetes/infrastructure/velero/restore-test-cronjob.yaml b/kubernetes/infrastructure/velero/restore-test-cronjob.yaml index 42cc9658..ae438dfe 100644 --- a/kubernetes/infrastructure/velero/restore-test-cronjob.yaml +++ b/kubernetes/infrastructure/velero/restore-test-cronjob.yaml @@ -85,4 +85,6 @@ spec: name: restore-test-script defaultMode: 0755 - name: tmp - emptyDir: {} + emptyDir: + medium: Memory + sizeLimit: 16Mi -- 2.54.0