✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Packaging Guidelines

Kubernetes Packaging Guidelines provide best practices for consistent, scalable, and efficient application deployment in Kubernetes environments.

Kubernetes Packaging Guidelines describe the practices for organizing, templating, and distributing sets of Kubernetes manifests as coherent, reusable, versioned units — using tools such as Helm and Kustomize — rather than treating each cluster's configuration as a loose, hand-maintained collection of independent YAML files that drift apart over time and are difficult to promote consistently across environments.


Why Raw Manifests Don't Scale

Duplication Across Environments

A workload deployed to development, staging, and production typically shares the vast majority of its configuration, differing only in replica counts, resource sizing, and a handful of environment-specific values. Maintaining fully separate manifest copies per environment causes that shared configuration to drift out of sync as changes are applied inconsistently, and makes the actual difference between environments hard to see at a glance.

Versioning and Release Tracking

Raw kubectl apply against a directory of manifests provides no built-in concept of a release, a version, or a rollback point — packaging tools introduce that concept explicitly, tracking what was deployed, when, and providing a mechanism to revert to a specific prior state as a single operation rather than manually reconstructing it from git history.


Helm

Charts as the Packaging Unit

A Helm chart bundles templated manifests, a schema for configurable values (values.yaml), and metadata (chart version, application version, dependencies) into a single distributable, versioned artifact. Charts can be published to and pulled from chart repositories or OCI registries, giving packaged applications the same kind of versioned distribution model that container images already have.

Templating for Environment Variation

Helm's Go-template-based templating lets a single chart produce different rendered output based on the values.yaml (or environment-specific values overrides) supplied at install time, capturing the shared structure once while parameterizing exactly the values that legitimately differ between deployments.

Release Lifecycle Management

helm install, helm upgrade, and helm rollback track releases as first-class objects with history, letting an operator revert a bad release to a specific prior revision as a single command, backed by Helm's own record of exactly what was previously rendered and applied — a materially different experience from manually reconstructing a prior manifest state from source control.

Chart Complexity Tradeoffs

Templating logic embedded in a chart (conditionals, loops, helper templates) can become difficult to reason about as it grows, especially for charts trying to support many divergent use cases through configuration alone; charts should be kept as simple as the actual variation they need to support demands, rather than pre-emptively parameterizing every conceivable value.


Kustomize

Overlay-Based Composition Without Templating

Kustomize takes a different approach: a base directory holds the canonical manifests, and per-environment overlays apply strategic merge patches or JSON patches on top, producing the final manifest without any templating language at all. This avoids an entire category of templating-related bugs (malformed output from incorrect template syntax) since every intermediate and final artifact is always valid, directly readable YAML.

Native kubectl Integration

Kustomize is built into kubectl (kubectl apply -k), requiring no additional tooling installation for basic use, which lowers the barrier to adopting at least some structure over raw manifests even in environments not ready to adopt a full packaging tool like Helm.

Patches Over Parameters

Where Helm parameterizes values that a template consumes, Kustomize patches the rendered structure of a base manifest directly — a difference in philosophy that tends to make Kustomize overlays easier to audit (the diff between environments is visible as an explicit patch) at the cost of being less suited to expressing complex conditional logic that a templating language handles more naturally.


Choosing Between Them

Helm for Distributable, Third-Party, or Highly Parameterized Applications

Helm's packaging, versioning, and release-tracking model suits applications distributed to multiple independent consumers (open-source software, internal platform components installed by many teams) where a well-defined configuration surface and installable artifact matter more than direct manifest transparency.

Kustomize for Environment-Specific Variation of Owned Applications

Kustomize's patch-based overlay model suits the common internal case of a single team's application that needs environment-specific variation without the overhead of designing and maintaining a templated values schema, particularly when manifest transparency and patch auditability are valued over packaging portability.

Combining Both

The two are not mutually exclusive — a common pattern uses Helm to package the application itself for portability and versioning, then uses Kustomize as a downstream layer to apply site-specific overlay patches to the Helm-rendered output, gaining Helm's release management alongside Kustomize's patch transparency at the point of deployment.


Repository and Promotion Practices

GitOps as the Deployment Mechanism

Packaged manifests are increasingly delivered via GitOps tooling (Argo CD, Flux), where a Kubernetes-native controller continuously reconciles cluster state against manifests stored in a git repository, rather than helm install/kubectl apply being run manually or from a CI pipeline's push step — this gives auditable, git-history-backed deployment history and makes drift between desired and actual cluster state continuously visible.

Progressive Promotion Between Environments

Changes to packaged configuration should flow through the same environment progression as application code — validated in a lower environment before being promoted to production — with the packaging tool's environment-specific values or overlays making that promotion an explicit, reviewable diff rather than a manual, error-prone reproduction of the change in each environment separately.


Example Structure

# values-production.yaml
replicaCount: 6
resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
image:
  tag: "v2.4.1"
ingress:
  host: "api.codartium.example.com"
# kustomization.yaml (overlay)
resources:
  - ../../base
patches:
  - path: production-replica-patch.yaml
    target:
      kind: Deployment
      name: codartium-api

Practical Consequences

Disciplined packaging produces deployments that are consistent in structure across environments, versioned with a clear rollback path, and reviewable as explicit diffs rather than manually reconciled duplicated files. Neglecting packaging discipline commonly results in environment drift discovered only when a production-only difference causes an incident, rollbacks that require manually reconstructing a prior manifest state under incident pressure, and configuration changes whose actual effect across environments was never clearly visible before they were applied.