Kubernetes Package Validation Practice
Ensuring package integrity in Kubernetes involves validating manifests, dependencies, and configurations to prevent runtime failures and security risks.
Kubernetes Package Validation Practice is the layered testing discipline applied to a package itself, distinct from reviewing any single rendered output, spanning static linting, template unit testing, values-matrix testing across multiple configurations, and full integration testing against a real cluster, forming a test pyramid that catches different classes of packaging defect at progressively higher cost and confidence.
The Validation Test Pyramid
Layered Confidence at Increasing Cost
Integration (install in a real/kind cluster) — slowest, highest confidence
Values-matrix rendering (many configurations)
Unit tests (template logic in isolation)
Static lint (structure and syntax) — fastest, lowest confidence
Each layer catches a different class of defect: lint catches structural and syntax errors, unit tests catch template logic errors for specific inputs, values-matrix testing catches configuration-combination-specific rendering failures, and integration testing catches failures that only appear once real Kubernetes admission, defaulting, and controller behavior are involved.
Static Linting
Structural and Syntax Checks
helm lint ./mychart
kustomize build overlays/production > /dev/null
helm lint checks a chart's structure (required Chart.yaml fields, valid template syntax) without needing any specific values, while running kustomize build and discarding output serves the equivalent purpose for a Kustomize overlay, catching gross errors, a malformed YAML file, an unresolvable resource reference, at the cheapest possible point in the pyramid.
Template Unit Testing
Testing Template Logic in Isolation
# tests/deployment_test.yaml (helm-unittest)
suite: test deployment
templates:
- deployment.yaml
tests:
- it: should set replica count from values
set:
replicaCount: 3
asserts:
- equal:
path: spec.replicas
value: 3
helm unittest ./mychart
Tools such as helm-unittest render specific templates against specific input values and assert on the resulting structure without touching a cluster at all, giving fast, deterministic feedback on template logic correctness, conditional blocks, computed values, named template output, exactly analogous to unit testing application code.
Values-Matrix Rendering
Exercising Multiple Realistic Configurations
for values in test-values/*.yaml; do
helm template ./mychart -f "$values" > /dev/null || echo "FAILED: $values"
done
Rendering a chart or overlay against a representative matrix of values files, minimal defaults, a full-featured production configuration, an edge-case configuration with every optional feature disabled, catches rendering failures specific to particular value combinations that a single default-values render would never exercise, particularly important for charts with many conditional blocks whose interactions are easy to overlook.
# test-values/minimal.yaml
autoscaling:
enabled: false
ingress:
enabled: false
# test-values/full-featured.yaml
autoscaling:
enabled: true
ingress:
enabled: true
tls:
enabled: true
Integration Testing Against a Real Cluster
The chart-testing (ct) Tool
ct install --chart-dirs charts --config ct.yaml
chart-testing, commonly run in CI against an ephemeral kind cluster, performs a real helm install (or upgrade from the chart's previous version) and verifies the resulting resources actually become ready, catching failures that only manifest once real admission control, defaulting, and controller reconciliation are involved, categories of failure entirely invisible to any purely rendering-based test.
# ct.yaml
chart-dirs:
- charts
target-branch: main
Testing Upgrade Paths, Not Just Fresh Installs
ct install --upgrade
Testing an upgrade from the previous published chart version, not only a fresh install, is necessary to catch upgrade-specific failures (an immutable field change, a migration hook error) that a fresh-install-only test suite would never exercise, since these failures depend on the transition between two states rather than either state in isolation.
Contract Testing for Chart Consumers
Verifying Downstream Assumptions Continue to Hold
# a downstream consumer's expectation
expectedConfigMapName: "{{ .Release.Name }}-app-config"
For a shared or platform-provided chart consumed by many independent teams, contract-style tests that verify specific fields, resource names, exposed values, service selectors, remain stable across chart versions catch a class of breaking change (a rename that the chart's own tests pass but silently breaks every downstream consumer relying on the old name) that testing the chart in isolation cannot detect on its own.
Relationship to Package Render Review and the Packaging Model
Validation practice is the systematic, automated counterpart to the manual render review discipline covered separately, and it operationalizes correctness verification across every layer of the broader packaging model: where render review focuses on inspecting a specific change's rendered diff, validation practice establishes an ongoing, repeatable test suite, lint, unit, values-matrix, integration, that runs on every change regardless of whether a human reviewer happens to notice a specific issue, providing the systematic safety net that ad hoc review alone cannot guarantee.