Skip to main content

Kubernetes Ep 15: Production Helm Charts & Package Deployment

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
kubernetes - This article is part of a series.
Part 15: This Article
Managing dozens of static YAML manifests across multiple environments (dev, staging, prod) leads to repetitive code and configuration drift. Helm is the official package manager for Kubernetes, enabling templating, parameterization, versioned releases, and one-click upgrades.

TL;DR (Quick Summary)
#

  • Helm Key Concepts:
    • Chart: A bundle of Go-templated Kubernetes YAML manifests (Chart.yaml, values.yaml, templates/).
    • Release: An instance of a Chart deployed to a Kubernetes cluster with specific values.
    • values.yaml: Default configuration values passed into templates.
  • Commands: helm create, helm install, helm upgrade, helm rollback, helm list.

1. Helm Architecture & Directory Anatomy
#


graph TD
    User["DevOps Engineer / CI-CD"] -->|helm install app ./my-chart -f values-prod.yaml| HelmCLI["Helm 3 CLI"]
    HelmCLI -->|Renders Go Templates| YAMLs["Generated K8s Manifests
(Deployments, Services, Ingress, Secrets)"] YAMLs -->|Submits to| API["kube-apiserver"]

Standard Helm Chart Directory Structure
#

my-web-app/
├── Chart.yaml          # Chart metadata (name, version, appVersion)
├── values.yaml         # Default configuration values
├── values-staging.yaml # Staging environment overrides
├── values-prod.yaml    # Production environment overrides
└── templates/          # Go template files
    ├── _helpers.tpl    # Template partials and named helpers
    ├── deployment.yaml # Templated Deployment manifest
    ├── service.yaml    # Templated Service manifest
    ├── ingress.yaml    # Templated Ingress manifest
    └── NOTES.txt       # Post-installation status instructions

2. Creating & Templating a Production Helm Chart
#

Generate a new chart skeleton:

helm create my-web-app

Chart.yaml Metadata
#

apiVersion: v2
name: my-web-app
description: Production-grade Helm chart for web microservices
type: application
version: 1.0.0
appVersion: "2.4.0"

values.yaml (Central Configuration)
#

replicaCount: 3

image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "1.25-alpine"

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: nginx
  host: app.mycompany.com

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 250m
    memory: 256Mi

templates/deployment.yaml (Go Templated Manifest)
#

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment
  labels:
    app: {{ .Chart.Name }}
    release: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
      release: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
        release: {{ .Release.Name }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.port }}
        resources:
          {{- toYaml .Values.resources | nindent 10 }}

3. Dry-Run Validation & Release Management
#

1. Lint and Test Template Rendering
#

Before deploying to a real cluster, dry-run template rendering to catch syntax errors:

helm template my-release ./my-web-app --debug

2. Deploying a Release (helm install)
#

helm install prod-web ./my-web-app -f values-prod.yaml --namespace production --create-namespace

Expected Terminal Output:

NAME: prod-web
LAST DEPLOYED: Mon Aug 10 01:15:00 2026
NAMESPACE: production
STATUS: deployed
REVISION: 1
TEST SUITE: None

3. Listing Active Helm Releases
#

helm list -n production
NAME      NAMESPACE   REVISION  UPDATED                                 STATUS    CHART            APP VERSION
prod-web  production  1         2026-08-10 01:15:00.123456789 +0000 UTC deployed  my-web-app-1.0.0 2.4.0

4. Upgrading Releases (helm upgrade)
#

When updating image tags or configuration settings, execute an atomic upgrade:

helm upgrade prod-web ./my-web-app --set replicaCount=5 -n production

5. Instant Helm Rollbacks (helm rollback)
#

If a release upgrade causes issues, roll back to revision 1:

helm rollback prod-web 1 -n production

4. Masterclass Series Conclusion
#

Congratulations! You have completed the Kubernetes Masterclass Series. Across 15 episodes, you have mastered:

  1. Foundations: Container runtime mechanics, Control Plane vs Worker Node architecture, and kubectl control flows.
  2. Workloads: Pods, Deployments, ReplicaSets, StatefulSets, DaemonSets, Jobs, and CronJobs.
  3. Networking & Storage: ClusterIP, NodePort, LoadBalancer, Ingress Controllers, PVs, PVCs, and StorageClasses.
  4. Operations & Security: Namespaces, ResourceQuotas, LimitRanges, RBAC, Health Probes, Rolling Updates, and Helm Package Management.

Keep building, deploying, and operating resilient cloud-native systems!

kubernetes - This article is part of a series.
Part 15: This Article