beginner ~60 min updated 2026-06-01
Kubernetes Deployment with Helm
Deploy a production-style NGINX release to a local kind Kubernetes cluster using Helm. Learn chart installation, values overrides, upgrades, rollbacks, and release management end to end.
Objective
Install, upgrade, and roll back an application on a local Kubernetes cluster using Helm charts and custom values files. By the end of this lab you will understand how Helm packages Kubernetes manifests into versioned releases and how to manage their full lifecycle.
Prerequisites
- Docker installed and running
- kind installed (or minikube as an alternative)
- kubectl installed and on your PATH
- Helm v3 installed (
helm versionshould print v3.x) - At least 4 GB of free RAM for the local cluster
Architecture
The lab runs a single-node Kubernetes cluster inside a Docker container via kind. Helm talks to the Kubernetes API server, renders the chart templates with your values, and applies the resulting manifests. The chart deploys an NGINX Deployment, a Service, and a ConfigMap. Release metadata is stored as Secrets in the cluster namespace, which is what enables rollbacks.
+--------------------------------------------------+
| Your laptop |
| |
| helm CLI ----> Kubernetes API (kind container) |
| | |
| v |
| +-------------- namespace: web -------------+ |
| | Deployment (nginx) --> Pods x2 | |
| | Service (ClusterIP) | |
| | Secret (helm release metadata) | |
| +--------------------------------------------+ |
+--------------------------------------------------+
Steps
1. Create a local Kubernetes cluster
kind create cluster --name helm-lab
kubectl cluster-info --context kind-helm-lab
kubectl get nodes
2. Add the Bitnami chart repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo bitnami/nginx --versions | head -5
3. Inspect the chart before installing
helm show values bitnami/nginx | head -40
helm template my-nginx bitnami/nginx --namespace web | head -60
4. Install the chart with custom values
Create a values override file:
# values-lab.yaml
replicaCount: 2
service:
type: ClusterIP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
Install the release:
kubectl create namespace web
helm install my-nginx bitnami/nginx \
--namespace web \
--values values-lab.yaml \
--wait
5. Verify the release
helm list --namespace web
kubectl get pods,svc --namespace web
kubectl port-forward svc/my-nginx 8080:80 --namespace web &
curl -s http://localhost:8080 | head -5
kill %1
6. Upgrade the release
Bump the replica count and upgrade:
helm upgrade my-nginx bitnami/nginx \
--namespace web \
--values values-lab.yaml \
--set replicaCount=3 \
--wait
helm history my-nginx --namespace web
7. Roll back to revision 1
helm rollback my-nginx 1 --namespace web --wait
kubectl get pods --namespace web
helm history my-nginx --namespace web
Expected output
$ helm list --namespace web
NAME NAMESPACE REVISION STATUS CHART APP VERSION
my-nginx web 1 deployed nginx-18.x.x 1.27.x
$ kubectl get pods --namespace web
NAME READY STATUS RESTARTS AGE
my-nginx-7d4b9c8f6d-2xkqp 1/1 Running 0 45s
my-nginx-7d4b9c8f6d-9wlmn 1/1 Running 0 45s
$ helm history my-nginx --namespace web
REVISION STATUS DESCRIPTION
1 superseded Install complete
2 superseded Upgrade complete
3 deployed Rollback to 1
Troubleshooting
- Pods stuck in
ImagePullBackOff: your machine cannot reach Docker Hub. Check connectivity withdocker pull bitnami/nginx:latest, or pre-load the image into kind withkind load docker-image bitnami/nginx:latest --name helm-lab. Error: Kubernetes cluster unreachable: your kubeconfig context is wrong. Runkubectl config use-context kind-helm-laband retry.helm installhangs with--wait: pods are not becoming Ready. Inspect withkubectl describe pod -n weband look at Events — usually insufficient memory on the kind node.port-forwardconnection refused: the Service has no ready endpoints yet. Confirm withkubectl get endpoints my-nginx -n webbefore curling.- Chart version not found: stale repo cache. Run
helm repo updateand search again.
Cleanup
helm uninstall my-nginx --namespace web
kubectl delete namespace web
kind delete cluster --name helm-lab
rm -f values-lab.yaml