dissected.io
Lesson 8 of 15
Intermediatehelmchartspackage-managementtemplatingreleases9 min read

Helm and Package Management

A real Kubernetes application isn't one manifest — it's a Deployment, a Service, a ConfigMap, an Ingress, maybe a PersistentVolumeClaim, RBAC rules, and a HorizontalPodAutoscaler. That's 7+ YAML files that need to stay in sync, parameterized per environment, and versioned together. Helm solves this by packaging related manifests into a single deployable unit called a chart, with templating for environment-specific values and built-in release management for upgrades and rollbacks.

Helm Package Management: Templates + Values → Manifests → Releases

Helm ChartChart.yamlvalues.yamltemplates/deployment.yamlservice.yamlHelm EngineGo Templatinghelm templatePlain K8s ManifestsapiVersion: apps/v1kind: Deploymentreplicas: 3image: nginx:1.25---kind: Servicetype: ClusterIPRelease History in Cluster (stored as Secrets in kube-system)Revision 1 (SUPERSEDED)helm install my-appRevision 2 (DEPLOYED)helm upgrade --set replicas=5Instant Safety Net:helm rollback my-app 11. Chart bundles parameterized templates with default values.yaml.

What Helm Actually Does

Helm is a package manager for Kubernetes — think apt or brew, but for K8s resources. It does three things:

  1. Packages multiple manifests into a single chart
  2. Templates those manifests with configurable values
  3. Manages releases — tracking what's installed, supporting upgrades and rollbacks

Without Helm, deploying an application means running kubectl apply on a pile of YAML files and hoping you got the right versions, in the right order, with the right environment-specific values. Helm gives you helm install my-app ./my-chart -f production.yaml — one command, parameterized, versioned.

Chart Structure

A Helm chart is a directory with a specific layout:

my-chart/
├── Chart.yaml          # Chart metadata (name, version, dependencies)
├── values.yaml         # Default configuration values
├── templates/          # Kubernetes manifest templates
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── hpa.yaml
│   └── _helpers.tpl    # Reusable template snippets
├── charts/             # Dependency charts
└── README.md

Chart.yaml defines the chart's identity and dependencies:

apiVersion: v2
name: my-web-app
version: 1.2.0        # Chart version
appVersion: "3.1.0"   # Application version
dependencies:
  - name: postgresql
    version: "12.1.0"
    repository: "https://charts.bitnami.com/bitnami"

values.yaml provides defaults that users override per environment:

replicaCount: 3
image:
  repository: myapp
  tag: "3.1.0"
resources:
  requests:
    cpu: 250m
    memory: 256Mi
ingress:
  enabled: true
  host: app.example.com

Template Rendering

Templates use Go's text/template syntax with Helm's extensions. The {{ .Values.xxx }} accessor pulls from values.yaml or user overrides:

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-chart.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

You can preview what Helm will generate without deploying: helm template my-release ./my-chart -f staging.yaml. This is invaluable for debugging — always check the rendered output before deploying.

Core Commands

# Install a chart as a new release
helm install my-release ./my-chart -f production.yaml

# Upgrade an existing release (new revision)
helm upgrade my-release ./my-chart -f production.yaml

# Rollback to a previous revision
helm rollback my-release 2

# List releases
helm list

# View release history
helm history my-release

# Uninstall a release
helm uninstall my-release

# Search Artifact Hub for community charts
helm search hub prometheus

# Add a chart repository
helm repo add bitnami https://charts.bitnami.com/bitnami

Repositories and Artifact Hub

Helm charts are distributed via OCI registries or chart repositories. Artifact Hub (artifacthub.io) is the central search engine — it indexes charts from hundreds of repositories. Major chart publishers include Bitnami, the Prometheus community, and cloud provider official repos.

For internal charts, most teams push to their existing container registry (ECR, GCR, ACR all support OCI-based Helm charts) or use a dedicated chart repository like ChartMuseum.

Creating Custom Charts

# Scaffold a new chart
helm create my-service

# Lint for issues
helm lint ./my-service

# Package for distribution
helm package ./my-service

# Push to OCI registry
helm push my-service-1.0.0.tgz oci://registry.example.com/charts

The scaffolded chart is a good starting point, but it includes templates for features you might not need (ServiceAccount, Ingress, HPA). Strip it down to what you actually use — a leaner chart is easier to maintain.

Helm vs Kustomize

Kustomize is the main alternative to Helm. It's built into kubectl (kubectl apply -k) and uses an overlay-based approach instead of templating. You write plain YAML manifests and layer patches on top per environment.

AspectHelmKustomize
ApproachTemplate + valuesBase + overlays (patches)
ParameterizationGo templates, values filesStrategic merge patches, JSON patches
PackagingCharts distributed via registriesPlain directories in git
Release managementBuilt-in (revisions, rollback)None — relies on GitOps tooling
Learning curveModerate (templating syntax)Lower (just YAML patches)
EcosystemThousands of community chartsNo package ecosystem
Best forThird-party software, complex appsInternal apps, GitOps workflows

The practical guidance: use Helm for community software (installing Prometheus, NGINX Ingress, cert-manager) and Kustomize for your own applications where you control the manifests and want the simplicity of pure YAML with overlays. Many teams use both.

Key Takeaways

  • Helm packages multiple Kubernetes manifests into a single versioned, parameterized chart
  • values.yaml provides defaults that you override per environment — keeps your templates DRY
  • Always run helm template to inspect rendered output before deploying
  • Use Artifact Hub to find community charts instead of writing manifests from scratch
  • Helm's release management gives you upgrade/rollback history; Kustomize needs external tooling for this
  • Use Helm for third-party charts, Kustomize for your own apps — or use both

Enjoyed this breakdown?

Get notified when new lessons go live.