Kubernetes Resource Management#
Cozystack models resource management around three interlocking concerns:
- Allocation ratios β platform-wide oversubscription multipliers that derive
requestsfrom user-suppliedlimits cozy-libtemplate helpers β Helm library functions that apply those ratios consistently across every package- VPA bounds β
minAllowed/maxAllowedpolicies expressed through those same helpers to ensure valid milliCPU values
Allocation Ratios#
Three ratios are defined in cozy-lib and read from the cozystack-values Secret at render time:
| Resource | Key | Default |
|---|---|---|
| CPU | cpu-allocation-ratio | 10 |
| Memory | memory-allocation-ratio | 1 |
| Ephemeral storage | ephemeral-storage-allocation-ratio | 40 |
The platform chart writes all three into _cluster of the cozystack-values Secret , so every downstream package picks up operator-configured values instead of hardcoded defaults. This propagation was restored in PR #2296 after a Package CRD bundle restructure broke it.
The CPU ratio default of 10 means a pod requesting 2 vCPUs as its limit will have a CPU request of 200m β allowing ten such pods to be scheduled on a node with 2 physical cores before hitting the scheduler's bin-packing ceiling.
cozy-lib Resource Helpers#
All helpers live in packages/library/cozy-lib/templates/_resources.tpl.
cozy-lib.resources.sanitize#
The core helper . Accepts a flat resource map (no nested requests:/limits: sections β a render-time error is raised if those are present) and emits a fully-expanded requests/limits block:
- CPU: request =
limit / cpuAllocationRatio, rounded up to the nearest whole milliCPU and emitted with themsuffix (e.g.,36m). The rounding prevents sub-milliCPU fractions that the VPA admission webhook rejects. - Memory: request =
limit / memoryAllocationRatio(default 1, so requests == limits) - Ephemeral storage: request =
limit / ephemeralStorageAllocationRatio - All other resources (GPU device plugins, etc.): requests == limits
Usage:
{{ include "cozy-lib.resources.sanitize" (list .Values.resources $) }}
cozy-lib.resources.defaultingSanitize#
A wrapper that fills missing cpu, memory, or ephemeral-storage from a named resource preset (e.g., "t1.nano") before calling sanitize. Useful for packages with optional per-component resource overrides.
cozy-lib.resources.flatten#
Converts the sanitized requests/limits map into the flat requests.cpu, limits.memory key format required by Kubernetes ResourceQuota objects .
cozy-lib.resources.javaHeap#
Derives JVM heap flags from a sanitized resource map : -Xmx = 75% of memory limit, -Xms = lesser of request or 25% of limit.
cozy-lib.resources.toFloat#
Unit-aware string-to-float converter used internally. Understands both binary (Ki, Mi, Gi, β¦) and SI (m, k, M, β¦) suffixes.
VPA Resource Policy Configuration#
VPA bounds (minAllowed/maxAllowed) must satisfy the same milliCPU constraint as pod requests. The idiomatic Cozystack pattern routes the bound values through cozy-lib.resources.sanitize and extracts the requests section β this automatically applies the allocation ratio and rounds to whole milliCPU.
Example β etcd VPA :
resourcePolicy:
containerPolicies:
- containerName: etcd
minAllowed: # computed from {cpu: "250m", memory: "256Mi"} via sanitize β requests
maxAllowed: # computed from {cpu: "5000m", memory: "8Gi"} via sanitize β requests
The etcd VPA uses updateMode: Initial (not Auto) because Auto would evict running etcd members to apply recommendations, risking quorum disruption and triggering a Cilium IP-reuse leak. Initial sets requests only at pod creation .
Dedicated CPU Quota#
For dedicatedCPUPlacement workloads (KubeVirt cx* instance types and Guaranteed QoS pods), pinned cores cannot be oversubscribed. An optional dedicatedCPU key in tenant resourceQuotas is added 1:1 to both limits.cpu and requests.cpu, bypassing cpuAllocationRatio .
Example: cpu: 10, dedicatedCPU: 2 with default ratio 10 β limits.cpu=12, requests.cpu=3.
VM Pod Resources#
Worker node VM pods use cozy-lib.resources.sanitize for their pod-level ephemeral storage request (hardcoded to 2Gi limit, since persistent DataVolumes are not counted as pod ephemeral storage) . VM domain cpu.cores and memory.guest are set directly from resources.cpu/resources.memory values without going through the sanitizer, because KubeVirt manages VM sizing independently of the pod scheduler's bin-packing .
Key Files#
| File | Purpose |
|---|---|
packages/library/cozy-lib/templates/_resources.tpl | All resource helper templates |
packages/core/platform/templates/apps.yaml | Writes allocation ratios into cozystack-values Secret |
packages/extra/etcd/templates/vpa.yaml | Reference VPA implementation using sanitize for bounds |
packages/apps/kubernetes-nodes/templates/nodegroup.yaml | VM pod resource usage |