update resources

This commit is contained in:
Grant Hunter
2026-10-23 17:23:29 -06:00
parent efd1e7146f
commit dba0272f81
26 changed files with 214 additions and 62 deletions
+3 -3
View File
@@ -15,11 +15,11 @@ readinessProbe:
resources: resources:
requests: requests:
cpu: 10m cpu: 10m
ephemeral-storage: 50Mi # Ephemeral storage is intentionally NOT requested: with Talos's single-EPHM
# layout every request here competes for the same small filesystem that
# holds container images, and the LimitRange default covers us.
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m
ephemeral-storage: 2Gi
memory: 224Mi memory: 224Mi
persistence: persistence:
size: 1Gi size: 1Gi
+1 -1
View File
@@ -10,7 +10,7 @@ Like the cloud but local.
- just (https://just.systems/man/en/ ) - just (https://just.systems/man/en/ )
## Talos Cluster ## Talos Cluster
### Hardware ### Hardware
- HP ProDesk 400 G3 (x3) - HP ProDesk 400 G3 16Gib (x3)
- Seagate Iron Wolf 2Tb (x2) - Seagate Iron Wolf 2Tb (x2)
- Western Digital Red Pro 2Tb - Western Digital Red Pro 2Tb
- Sabrent HDD Docking Station (3x) - Sabrent HDD Docking Station (3x)
+8
View File
@@ -2,6 +2,14 @@ image:
tag: 2.37.1 tag: 2.37.1
env: env:
TZ: America/Edmonton TZ: America/Edmonton
# k8s-home-lab common lib: resources is top-level
resources:
requests:
cpu: 20m
memory: 128Mi
limits:
memory: 1Gi
ingress: ingress:
main: main:
enabled: true enabled: true
+8
View File
@@ -1,6 +1,14 @@
env: env:
TZ: America/Edmonton TZ: America/Edmonton
DOCKER_MODS: linuxserver/mods:universal-calibre DOCKER_MODS: linuxserver/mods:universal-calibre
# k8s-home-lab common lib: resources is top-level (see charts/common/templates/lib/controller/_container.tpl)
resources:
requests:
cpu: 20m
memory: 128Mi
limits:
memory: 768Mi
ingress: ingress:
main: main:
enabled: true enabled: true
+48
View File
@@ -7,6 +7,10 @@
# If the Rook operator is installed in a namespace other than rook-ceph, replace # If the Rook operator is installed in a namespace other than rook-ceph, replace
# "rook-ceph" in the driver names below with your operator namespace. # "rook-ceph" in the driver names below with your operator namespace.
# NOTE: driver.yaml renders `nodePlugin.resources.<container> | default dict`, so
# omitting a container emits an explicit `{}` into the CR, which can wipe the
# operator's built-in sidecar defaults. Every container is therefore listed
# explicitly so the requests are deterministic and visible to the scheduler.
operatorConfig: operatorConfig:
namespace: rook-ceph # namespace:operator namespace: rook-ceph # namespace:operator
driverSpecDefaults: driverSpecDefaults:
@@ -14,8 +18,52 @@ operatorConfig:
name: rook-csi-operator-image-set-configmap name: rook-csi-operator-image-set-configmap
nodePlugin: nodePlugin:
priorityClassName: system-node-critical priorityClassName: system-node-critical
resources:
registrar:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
liveness:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
logRotator:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
addons:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
plugin:
requests: {cpu: 20m, memory: 64Mi}
limits: {memory: 512Mi}
controllerPlugin: controllerPlugin:
priorityClassName: system-cluster-critical priorityClassName: system-cluster-critical
resources:
attacher:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
snapshotter:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
resizer:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
provisioner:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
omapGenerator:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
liveness:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
logRotator:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
addons:
requests: {cpu: 5m, memory: 16Mi}
limits: {memory: 64Mi}
plugin:
requests: {cpu: 50m, memory: 64Mi}
limits: {memory: 256Mi}
drivers: drivers:
rbd: rbd:
@@ -1,5 +1,12 @@
groupName: acme.hetzner.com groupName: acme.hetzner.com
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
certManager: certManager:
namespace: cert-manager namespace: cert-manager
serviceAccountName: cert-manager serviceAccountName: cert-manager
-3
View File
@@ -5,7 +5,6 @@ resources:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 1
memory: 128Mi memory: 128Mi
webhook: webhook:
@@ -14,7 +13,6 @@ webhook:
cpu: 10m cpu: 10m
memory: 32Mi memory: 32Mi
limits: limits:
cpu: 1
memory: 64Mi memory: 64Mi
cainjector: cainjector:
@@ -23,5 +21,4 @@ cainjector:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 1
memory: 128Mi memory: 128Mi
+16
View File
@@ -41,6 +41,15 @@ gitea:
strategy: strategy:
type: Recreate type: Recreate
# Requests make the pod visible to the scheduler; without them gitea is
# BestEffort and is the first candidate for eviction under node pressure.
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 1Gi
ingress: ingress:
enabled: true enabled: true
hosts: hosts:
@@ -61,6 +70,13 @@ service:
valkey: valkey:
enabled: true enabled: true
primary:
resources:
requests:
cpu: 10m
memory: 48Mi
limits:
memory: 256Mi
valkey-cluster: valkey-cluster:
enabled: false enabled: false
postgresql: postgresql:
+7
View File
@@ -105,3 +105,10 @@ releases:
createNamespace: true createNamespace: true
values: values:
- ../k8up-backup/values.yaml.gotmpl - ../k8up-backup/values.yaml.gotmpl
# Namespace guardrails (default requests/limits for pods that declare none).
# Listed last so the namespaces it targets already exist; it only affects pod
# admission from here on. Run `just update` to refresh the lock file.
- name: resource-defaults
namespace: default
chart: ../resource-defaults
+14 -6
View File
@@ -17,19 +17,27 @@ immich:
library: library:
existingClaim: immich-data existingClaim: immich-data
# NOTE: immich 0.12.0 embeds valkey as a bjw-s "common" library template
# (templates/valkey.yaml), not as a Bitnami subchart. The old `valkey.master.*`
# block was silently dropped: it set a 32Mi limit under a 64Mi request (an
# impossible pair that would have OOMKilled the container) and never reached the
# pod. The correct path is controllers.main.containers.main.*.
valkey: valkey:
enabled: true enabled: true
master:
persistence: persistence:
data:
annotations: annotations:
k8up.io/backup: 'false' k8up.io/backup: 'false'
controllers:
main:
containers:
main:
resources: resources:
requests: requests:
cpu: 10m cpu: 10m
memory: 64Mi memory: 48Mi
limits: limits:
cpu: 1 memory: 256Mi
memory: 32Mi
server: server:
enabled: true enabled: true
@@ -43,7 +51,8 @@ server:
cpu: 10m cpu: 10m
memory: 256Mi memory: 256Mi
limits: limits:
cpu: 1 # No CPU limit: limits do not change scheduler bin-packing and
# only cause CFS throttling. Memory limit is what protects the node.
memory: 1Gi memory: 1Gi
ingress: ingress:
main: main:
@@ -70,7 +79,6 @@ machine-learning:
cpu: 10m cpu: 10m
memory: 128Mi memory: 128Mi
limits: limits:
cpu: 1
memory: 2Gi memory: 2Gi
+3 -2
View File
@@ -8,8 +8,9 @@ resources:
cpu: 10m cpu: 10m
memory: 32Mi memory: 32Mi
limits: limits:
cpu: 500m # limit == request (32Mi) left no headroom for the nginx worker; CPU limit
memory: 32Mi # removed - it does not affect scheduling, only throttles.
memory: 96Mi
ingress: ingress:
enabled: true enabled: true
+1 -2
View File
@@ -12,5 +12,4 @@ resources:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m memory: 256Mi
memory: 128Mi
+4 -2
View File
@@ -11,5 +11,7 @@ k8up:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m # memory limit == request meant any spike (e.g. a reconcile of many
memory: 64Mi # Schedules) OOMKilled the controller. Leave headroom; CPU is uncapped
# because CPU limits do not affect scheduling and only throttle.
memory: 192Mi
+3 -3
View File
@@ -15,11 +15,11 @@ readinessProbe:
resources: resources:
requests: requests:
cpu: 10m cpu: 10m
ephemeral-storage: 50Mi # Ephemeral storage is intentionally NOT requested: with Talos's single-EPHM
# layout every request here competes for the same small filesystem that
# holds container images, and the LimitRange default covers us.
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m
ephemeral-storage: 2Gi
memory: 350Mi memory: 350Mi
persistence: persistence:
+4 -4
View File
@@ -8,9 +8,9 @@ primary:
resources: resources:
requests: requests:
cpu: 50m cpu: 50m
ephemeral-storage: 50Mi
memory: 96Mi memory: 96Mi
limits: limits:
cpu: 1 # ephemeral-storage request removed - see ghost values note; the LimitRange
ephemeral-storage: 2Gi # default/max covers it. Memory limit raised: 192Mi was tight for a 5Gi
memory: 192Mi # dataset with the default key buffer + per-connection buffers.
memory: 512Mi
+3 -2
View File
@@ -9,5 +9,6 @@ resources:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m # memory limit was equal to the request (64Mi) - no headroom for the
memory: 64Mi # registration flow. CPU limit removed: it has no effect on scheduling.
memory: 192Mi
+1 -3
View File
@@ -4,8 +4,7 @@ controller:
cpu: 10m cpu: 10m
memory: 32Mi memory: 32Mi
limits: limits:
cpu: 500m memory: 128Mi
memory: 64Mi
speaker: speaker:
resources: resources:
@@ -13,5 +12,4 @@ speaker:
cpu: 10m cpu: 10m
memory: 48Mi memory: 48Mi
limits: limits:
cpu: 500m
memory: 96Mi memory: 96Mi
-1
View File
@@ -6,5 +6,4 @@ resources:
cpu: 10m cpu: 10m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 500m
memory: 160Mi memory: 160Mi
+3 -1
View File
@@ -9,7 +9,9 @@ instances:
cpu: 100m cpu: 100m
memory: 192Mi memory: 192Mi
limits: limits:
cpu: 2 # No CPU limit: the operator's instanceCPU: 2 is what the scheduler and
# the operator's own sizing logic use; a CFS limit here only throttles
# autovacuum and checkpointing without changing pod placement.
memory: 1Gi memory: 1Gi
dataVolumeClaimSpec: dataVolumeClaimSpec:
accessModes: accessModes:
+27 -7
View File
@@ -6,34 +6,54 @@ cephClusterSpec:
count: 3 count: 3
allowMultiplePerNode: false allowMultiplePerNode: false
# A 3-node homelab does not need an active+standby mgr pair. Each mgr costs
# 256Mi request / 704Mi limit (plus mgr-sidecar), which is pure fixed overhead
# per node and the first thing that blocks co-scheduling on small nodes.
mgr:
count: 1
storage: storage:
useAllNodes: true useAllNodes: true
useAllDevices: false useAllDevices: false
deviceFilter: "^sda" deviceFilter: "^sda"
config: config:
osd_memory_target: "1073741824" # 1GB per OSD to maintain 70% node capacity # osd_memory_target must match the osd request/limit below: the OSD is a
# long-running cache-filling process, so an under-sized request lets the
# scheduler overpack the node and an over-sized limit lets it OOM siblings.
osd_memory_target: "1073741824" # 1GB per OSD
resources: resources:
mgr: mgr:
requests: requests:
cpu: 50m cpu: 50m
memory: 256Mi memory: 256Mi
limits: limits:
cpu: "1"
memory: 704Mi memory: 704Mi
mon: mon:
requests: requests:
cpu: 100m cpu: 100m
memory: 256Mi memory: 256Mi
limits: limits:
cpu: "1" # 3 mons with ~zero load; the previous 2Gi limit was 8x the request and
memory: 2Gi # made the worst-case per-node footprint look 1.75Gi worse than it is.
memory: 1Gi
osd: osd:
# Guaranteed QoS (request == limit) so the scheduler reserves what the
# OSD will actually use. CPU is left unlimited: CPU limits don't change
# bin-packing and only throttle the OSD during backfill.
requests: requests:
cpu: 100m cpu: 100m
memory: 896Mi memory: 1Gi
limits: limits:
cpu: "1" memory: 1Gi
memory: 1280Mi # crashcollector is a DaemonSet (one pod per node) and was previously
# inherited from the chart with a 100m CPU request, which is a large share
# of a ProDesk's 4 cores for a pod that only reads /var/lib/rook/crash.
crashcollector:
requests:
cpu: 10m
memory: 60Mi
limits:
memory: 60Mi
ingress: ingress:
dashboard: dashboard:
+4 -3
View File
@@ -1,7 +1,8 @@
resources: resources:
requests: requests:
cpu: 100m cpu: 50m
memory: 512Mi # Operator is control-plane-ish: it mostly idles between reconcile loops.
# 512Mi of reservation was the single largest non-OSD request in the cluster.
memory: 128Mi
limits: limits:
cpu: 1
memory: 1Gi memory: 1Gi
+4 -2
View File
@@ -18,8 +18,10 @@ synapse:
cpu: 10m cpu: 10m
memory: 128Mi memory: 128Mi
limits: limits:
cpu: '1' # No CPU limit (throttling only, no scheduling effect). Synapse is
memory: 512Mi # memory-hungry on room joins/backfill; 512Mi was the tightest limit in
# the cluster for a stateful service.
memory: 1Gi
config: config:
macaroonSecretKey: {{ requiredEnv "GOATCHAT_SYNAPSE_MACAROON_SECRET_KEY" }} macaroonSecretKey: {{ requiredEnv "GOATCHAT_SYNAPSE_MACAROON_SECRET_KEY" }}
+3
View File
@@ -3,6 +3,9 @@ kind: Connector
metadata: metadata:
name: home-cidr name: home-cidr
spec: spec:
# Applies the resource requests/limits defined in proxyclass-home.yaml to the
# proxy StatefulSet this Connector creates.
proxyClass: fog
tags: tags:
- "tag:k8s" - "tag:k8s"
hostname: home-cidr hostname: home-cidr
+8 -4
View File
@@ -2,14 +2,18 @@ operatorConfig:
extraEnv: extraEnv:
- name: PROXY_PRIORITY_CLASS_NAME - name: PROXY_PRIORITY_CLASS_NAME
value: critical value: critical
resources:
resources:
requests: requests:
cpu: 10m cpu: 10m
memory: 48Mi memory: 48Mi
limits: limits:
cpu: 500m memory: 128Mi
memory: 64Mi
# Make the fog ProxyClass the default for proxies created from Ingress and
# LoadBalancer services so they don't land as BestEffort pods. Connectors do not
# honour this and need spec.proxyClass (see connector.yaml).
proxyConfig:
defaultProxyClass: fog
oauth: oauth:
clientId: {{ requiredEnv "TAILSCALE_OAUTH_CLIENT_ID" }} clientId: {{ requiredEnv "TAILSCALE_OAUTH_CLIENT_ID" }}
+21 -1
View File
@@ -1,9 +1,29 @@
machine: machine:
install: install:
image: ghcr.io/siderolabs/installer:v1.13.0 image: ghcr.io/siderolabs/installer:v1.13.12
kubelet: kubelet:
extraArgs: extraArgs:
rotate-server-certificates: true rotate-server-certificates: true
# Reserve capacity so the scheduler, not kubelet's eviction manager,
# decides how many pods a node carries. Without this, kubelet advertises
# the node's full allocatable and only protects the OS/system pods once
# memory is already critical (default: memory.available < 100Mi), which
# on a ProDesk means OOM-killing workloads. With reservations the node
# reports a smaller allocatable, so pods pack to a sustainable density.
extraConfig:
maxPods: 110
systemReserved:
cpu: 100m
memory: 256Mi
ephemeral-storage: 1Gi
kubeReserved:
cpu: 250m
memory: 512Mi
ephemeral-storage: 2Gi
evictionHard:
memory.available: 200Mi
nodefs.available: 10%
imagefs.available: 15%
udev: udev:
rules: rules:
# set all disks to `none` scheduler (optimal setting for Ceph and ZFS) # set all disks to `none` scheduler (optimal setting for Ceph and ZFS)
+3 -2
View File
@@ -6,8 +6,9 @@ resources:
cpu: 50m cpu: 50m
memory: 64Mi memory: 64Mi
limits: limits:
cpu: 1 # No CPU limit: limits do not affect scheduler placement and only throttle
memory: 128Mi # the proxy under load. Memory is what protects the node.
memory: 256Mi
updateStrategy: updateStrategy:
type: RollingUpdate type: RollingUpdate