Deploy a custom Helm Chart on a local Kubernetes Cluster
Deploy a custom Helm Chart on a local Kubernetes Cluster
When experimenting with Kubernetes locally, combining Podman as the container runtime, k3d/k3s as the lightweight Kubernetes distribution, and Helm as the package manager provides a powerful, self-contained environment. Adding Traefik as a load balancer and ingress controller lets you simulate real-world traffic routing, complete with host-based routing and dashboards.
This article walks through setting up such an environment, deploying Traefik, and creating a custom Helm chart for a simple sample application.
1. Preparing Podman
On macOS, Podman runs inside a VM. Start by allocating resources and initializing the machine:
podman machine init \ --cpus 8 \ --disk-size 100 \ --memory 8092podman machine start
This provides the container runtime that k3d will use to host the Kubernetes cluster.
2. Creating a k3d/k3s Cluster
Next, create a new cluster using k3d. In this setup, we’ll expose ports for HTTP, HTTPS, and a Traefik dashboard, while disabling the default Traefik that ships with k3s (so we can install our own):
k3d cluster create traefik \ --port 80:80@loadbalancer \ --port 443:443@loadbalancer \ --port 8000:8000@loadbalancer \ --k3s-arg "--disable=traefik@server:0"
Check the cluster:
kubectl cluster-info --context k3d-traefik
3. Installing Traefik with Helm
With the cluster ready, install Traefik via its Helm chart. This will enable the dashboard and set up Kubernetes Gateway API support:
helm repo add traefik https://traefik.github.io/chartshelm repo update
helm install traefik traefik/traefik --wait \ --set ingressRoute.dashboard.enabled=true \ --set ingressRoute.dashboard.matchRule='Host(`dashboard.localhost`)' \ --set ingressRoute.dashboard.entryPoints={web} \ --set providers.kubernetesGateway.enabled=true \ --set gateway.listeners.web.namespacePolicy.from=All
Inspect the installed GatewayClass to confirm Traefik is registered:
kubectl describe gatewayclasses.gateway.networking.k8s.io traefik
Once ready, open the dashboard:
open http://dashboard.localhost/dashboard/
4. Creating a Custom Helm Chart
Now that the cluster and Traefik ingress are working, let’s package a small sample application with Helm. We’ll use Traefik’s whoami container, which simply responds with request information.
Scaffold a new chart:
helm create whoami
By default, helm create
generates a full set of example templates (ConfigMaps, Ingress, HPA, tests, etc.). For a minimal chart, you can clear them out and start fresh:
rm whoami/templates/*
This leaves you with an empty templates/
directory that you can populate only with the manifests you need.
values.yaml
Here we define the app name, image, replicas, and service port:
name: whoamireplicaCount: 2image: traefik/whoamiservice: port: 80
Deployment
A simple deployment pulling values from values.yaml
:
# templates/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: {{ .Values.name }}spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.name }} template: metadata: labels: app: {{ .Values.name }} spec: containers: - name: {{ .Values.name }} image: {{ .Values.image }} ports: - containerPort: 80
Service
Expose the pods internally with a ClusterIP
service:
# templates/service.yamlapiVersion: v1kind: Servicemetadata: name: {{ .Values.name }}spec: ports: - port: {{ .Values.service.port }} selector: app: {{ .Values.name }}
IngressRoute
Route external requests via Traefik. This maps http://whoami.localhost
to the service:
# templates/ingress-route.yamlapiVersion: traefik.io/v1alpha1kind: IngressRoutemetadata: name: {{ .Values.name }}spec: entryPoints: - web routes: - match: Host(`{{ .Values.name }}.localhost`) kind: Rule services: - name: {{ .Values.name }} port: {{ .Values.service.port }}
5. Deploy and Verify
Install the chart:
helm install whoami ./whoami
(Optionally run with --debug --dry-run
first to inspect the rendered manifests.)
Check the generated manifests:
helm get manifest whoami
Now, open http://whoami.localhost in your browser. You should see output like:
Hostname: whoami-xxxxxxxxxx-xxxxxIP: 10.42.x.x
This confirms your app is deployed, load-balanced, and routed through Traefik.
6. Cleanup
When you’re finished testing, it’s good practice to tear down the resources you created so your local environment stays clean.
First, uninstall the Helm release for your sample application:
helm uninstall whoami
If you also want to remove Traefik:
helm uninstall traefik
Finally, delete the entire k3d cluster:
k3d cluster delete traefik
This will stop and remove all containers, networks, and volumes associated with the cluster. If you want to reclaim resources used by the Podman VM, you can also stop or remove it:
podman machine stop# or remove it completely:podman machine rm
With that, your environment is back to a clean state, ready for your next Kubernetes experiment.
Conclusion
By combining Podman, k3d/k3s, Traefik, and Helm, you can simulate a production-like Kubernetes environment entirely on your laptop.
- Podman provides the container runtime.
- k3d/k3s runs a lightweight Kubernetes cluster.
- Traefik acts as an ingress controller and load balancer.
- Helm allows you to package, configure, and deploy applications.
The whoami
example demonstrates the complete lifecycle: from cluster creation to ingress routing. With this foundation, you can now adapt charts for your own services, experiment with Kubernetes Gateway API, and iterate on deployments locally before promoting them to larger environments.