Kubernetes Packaging Model
Kubernetes Packaging Model defines how apps are structured, bundled, and deployed in Kubernetes for consistent, scalable operations.
Kubernetes Packaging Model is the underlying conceptual structure shared by every Kubernetes packaging tool, regardless of specific implementation: a package is the combination of a versioned, parameterized template, a set of environment-specific input values, and a deterministic rendering step that together produce a concrete set of manifests, with an optional release record tracking what was actually installed and when.
The Three-Part Structure of a Package
Template, Values, and Rendering
Every packaging approach, whatever its syntax, separates a reusable template (the structure of the manifests, with placeholders for what varies) from the values supplied for a specific installation (the actual replica count, image tag, or hostname), and a rendering step that deterministically combines the two into concrete, appliable YAML.
# template
spec:
replicas: {{ .Values.replicaCount }}
# values
replicaCount: 3
# rendered output
spec:
replicas: 3
Determinism as a Core Requirement
Rendering the same template with the same values must always produce identical output; a packaging tool whose rendering step depends on ambient state (the current time, a random seed, an unpinned external lookup) undermines the reproducibility that makes packaging valuable in the first place, since the same nominal installation could then produce different manifests on different runs.
The Release Concept
Tracking What Was Actually Installed
Beyond rendering, most packaging tools introduce a release concept, a record of which template version and which values were used for a specific installation, stored either as an in-cluster object (Helm's release secrets) or as the state of a Git repository at a specific commit (the GitOps equivalent).
helm list
NAME CHART APP VERSION REVISION
my-app mychart-1.2.0 2.0.1 3
Revisions as an Append-Only History
helm history my-app
REVISION STATUS CHART
1 superseded mychart-1.0.0
2 superseded mychart-1.1.0
3 deployed mychart-1.2.0
Each install or upgrade of a release is recorded as a new, immutable revision rather than overwriting the previous record, which is what enables a rollback operation to reconstruct exactly what a prior revision's rendered manifests looked like and reapply them.
Declarative Rendering vs. Imperative Reconciliation
Packaging Produces a Snapshot, Not a Live Loop
A critical distinction in the packaging model is that rendering a package produces a one-time snapshot of manifests to be applied, not an ongoing reconciliation process; unlike a controller's reconcile loop, which continuously converges actual state toward desired state, a packaging tool's job ends the moment the rendered manifests are handed off to kubectl apply or an equivalent apply mechanism.
helm template ./chart -f values.yaml | kubectl apply -f -
Where GitOps Extends the Model
GitOps tooling extends the packaging model by continuously re-rendering and re-applying a package whenever its source template or values change in Git, effectively adding a reconciliation loop on top of an otherwise one-shot rendering step, closing the gap between "packaging produces a snapshot" and "the cluster should always match the current package definition."
Versioning Within the Model
Package Version vs. Application Version
The packaging model distinguishes the version of the package itself (incremented when the template structure changes) from the version of the application it deploys (the container image tag), since a package can be updated purely to fix a templating bug without any change to the underlying application, or the application can be upgraded without any change to how it is packaged.
# Chart.yaml
version: 1.2.0
appVersion: "2.0.1"
Idempotent Application of Rendered Output
Convergence on Reapplication
Rendered manifests applied through kubectl apply (rather than create) are expected to converge to the same state whether applied once or many times, mirroring the idempotency requirement of a controller's reconcile logic; a packaging tool that renders manifests violating this property, generating a new random name on every render, for instance, breaks the ability to safely reapply a package without unintended side effects.
Relationship to Packaging Scope and Areas
The packaging model is the abstract structure underlying every specific tool covered under packaging and customization areas: Helm's charts and releases, Kustomize's bases and overlays, and configuration languages like CUE all instantiate the same template-values-render-release pattern in different syntaxes, and understanding this shared model is what makes switching between, or combining, these specific tools a matter of translating representation rather than relearning a fundamentally different underlying concept each time.