Skip to main content
RunBook Academy

KubernetesCVI · Package Management Anti-PatternsPackage management anti-patterns

Package management anti-patterns — the most common mistakes

Advanced⏱ ~16 minhelmkustomize

What you'll learn

  • Identify the most common package management anti-patterns
  • Explain why each anti-pattern is a problem
  • Apply the fixes for each anti-pattern
  • Build the operational discipline of avoiding package management anti-patterns

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Package management anti-patterns are the most common mistakes that Kubernetes operators make when using Helm and Kustomize. This lesson walks the anti-patterns, the fixes, and the operational discipline.

Anti-pattern 1: Giant values files

# Anti-pattern: a single 500-line values file
replicaCount: 3
image:
  repository: myapp
  tag: "1.0.0"
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
# ... 480 more lines of configuration

The intent is centralisation; the result is unreviewable. A 500-line file cannot be reviewed effectively in a PR.

The fix is to split into smaller, focused files:

# values/01-image.yaml
image:
  repository: myapp
  tag: "1.0.0"

# values/02-service.yaml
service:
  type: ClusterIP
  port: 80

# values/03-resources.yaml
resources:
  requests:
    cpu: 100m
    memory: 128Mi

Each file is small and reviewable. The -f flag can take multiple files:

helm install myrelease mychart/ \
  -f values/01-image.yaml \
  -f values/02-service.yaml \
  -f values/03-resources.yaml \
  -f values-prod.yaml

Anti-pattern 2: Unpinned charts

# Anti-pattern: no version pin
helm install myrelease bitnami/postgresql

The intent is “always the latest”; the result is unpredictable upgrades. A chart upgrade between staging and production may break production.

The fix:

helm install myrelease bitnami/postgresql --version 12.1.0

Always pin the chart version. The version is in version control (or in the CI pipeline) and is auditable.

Anti-pattern 3: Blindly installing public charts

# Anti-pattern: install without review
helm install myrelease random-chart-from-internet

The intent is “use what’s available”; the result is a security risk. A public chart may include privileged workloads, broad RBAC, or backdoors.

The fix:

flowchart TD
    A[Public chart] --> B{Reviewed?}
    B -->|No| C[Do not install]
    B -->|Yes| D[Pin version]
    D --> E["Render: helm template"]
    E --> F[Review output]
    F --> G{Acceptable?}
    G -->|No| C
    G -->|Yes| H[Install]

The discipline is to review every public chart before installing: render with helm template, inspect the manifests, verify the security implications.

Anti-pattern 4: Configuration drift

flowchart LR
    A[Helm release v1] --> B["Secret: sh.helm.release.v1"]
    C["Cluster: actual"] --> D["Drift: kubectl edit"]
    D --> A

The intent is “Helm manages the release”; the result is that the cluster’s actual state diverges from Helm’s view.

The fix is to enable Argo CD selfHeal (if using GitOps) or to alert on drift and revert manual changes.

Anti-pattern 5: Secrets in values files

# Anti-pattern: secret in values.yaml
database:
  password: "supersecretpassword"

The values file is in Git (or wherever the chart is stored). The secret is exposed to anyone with access to the repository.

The fix is to use external secrets: Vault, sealed- secrets, External Secrets Operator. Reference them from values via env or existingSecret.

Anti-pattern 6: Too many Helm releases for one workload

# Anti-pattern: 5 Helm releases for one app
helm install myapp-base mychart/
helm install myapp-config mychart/
helm install myapp-sidecar mychart/
helm install myapp-monitor mychart/
helm install myapp-secret mychart/

The intent is separation of concerns; the result is operational complexity. Five releases must be upgraded, rolled back, and monitored independently.

The fix is one release with subcharts or components:

# Use a parent chart with subcharts
dependencies:
  - name: myapp-base
    version: 1.0.0
  - name: myapp-config
    version: 1.0.0

Or use Kustomize overlays for the same workload.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the common thread in most package-management anti-patterns?

  2. Q2. If a deployment cannot be reproduced from the repository, the repository is not the source of truth.

  3. Q3. Undo a configuration change on a workload split across five Helm releases, then consolidate it.

    `helm list -n prod-app` shows five releases for one application: `myapp-base`, `myapp-config`, `myapp-sidecar`, `myapp-monitor` and `myapp-secret`. A change to `myapp-config` at 14:02 broke request routing. `helm rollback myapp-config 6 -n prod-app` reports success and nothing observable changes, because the ConfigMap it manages is mounted by a Deployment that belongs to `myapp-base` and whose Pod template did not move.

  4. Q4. A chart needs a database password. Where does the value live, and what does the values file contain instead?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

Package management anti-patterns in production rest on five non-negotiable elements:

  • Small, focused values files. Each file is reviewable.
  • Pin chart versions. Always.
  • Review public charts. Render and inspect before installing.
  • Detect and revert drift. selfHeal or alerts.
  • External secrets. Vault, sealed-secrets, ESO.

Package management is production deployment. Treat the anti-patterns with the same rigour as any other production concern.