luvv to helpDiscover the Best Free Online Tools
Topic 6 of 7

Helm Basics

Learn Helm Basics for free with explanations, exercises, and a quick test (for MLOps Engineer).

Published: January 4, 2026 | Updated: January 4, 2026

Why this matters

As an MLOps Engineer, you package and deploy model services, batch jobs, and data pipelines repeatedly across dev, staging, and prod. Helm lets you template Kubernetes manifests, version configurations, and roll out updates safely. Real tasks you will handle:

  • Deploying a model inference service with different image tags and resources per environment.
  • Rolling out updates and quickly rolling back if a release misbehaves.
  • Sharing reusable charts for training jobs, batch predictions, and feature pipelines.

Who this is for

  • Beginners to Helm who already know basic Kubernetes objects (Deployment, Service, ConfigMap, Secret).
  • MLOps engineers standardizing model deployments across environments.
  • Data scientists transitioning to productionizing ML workloads.

Prerequisites

  • Basic Kubernetes knowledge: Pods, Deployments, Services, Namespaces.
  • kubectl installed and access to a test cluster (e.g., local kind or Minikube).
  • Docker image of a simple ML service or a public image you can reference.

Concept explained simply

Helm is a package manager for Kubernetes. A Helm chart is a folder of templates and default values. When you run Helm, it renders those templates with your values and installs a release into the cluster. You can upgrade, rollback, and uninstall releases.

Mental model: Chart = function, Values = arguments, Rendered Manifests = output, Release = running instance of that output in your cluster.

Core parts of a chart

  • Chart.yaml: chart metadata (name, version, description).
  • values.yaml: default configurable values (image, resources, replicas).
  • templates/: Kubernetes YAML files with Go templates (e.g., Deployment, Service).
  • helpers templates (optional): common name labels and annotations.
  • Release lifecycle: helm install → helm upgrade → helm rollback/uninstall.
  • Repositories: where charts are stored and pulled from (you can also use local charts).

Worked examples

Example 1: Minimal inference service chart

Create a simple chart that deploys a single-replica model service with a ClusterIP Service.

# Create chart
helm create ml-infer

# Clean up extras (optional)
rm -rf ml-infer/templates/tests

# Edit Chart.yaml (key fields)
apiVersion: v2
name: ml-infer
version: 0.1.0
description: Minimal ML inference service

# values.yaml (essentials)
image:
  repository: myrepo/ml-infer
  tag: "0.1.0"
  pullPolicy: IfNotPresent
replicaCount: 1
service:
  type: ClusterIP
  port: 80
resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "200m"
    memory: "256Mi"

# templates/deployment.yaml (snippet)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "ml-infer.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "ml-infer.name" . }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "ml-infer.name" . }}
    spec:
      containers:
        - name: app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          resources: {{- toYaml .Values.resources | nindent 12 }}
          ports:
            - containerPort: 8080

# templates/service.yaml (snippet)
apiVersion: v1
kind: Service
metadata:
  name: {{ include "ml-infer.fullname" . }}
spec:
  type: {{ .Values.service.type }}
  selector:
    app.kubernetes.io/name: {{ include "ml-infer.name" . }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: 8080

# Dry-run render
helm template demo ./ml-infer

# Install
helm install demo ./ml-infer

# Upgrade later with a new image tag
helm upgrade demo ./ml-infer --set image.tag=0.1.1

Result: a Deployment and Service for your inference container. Upgrades change image tags consistently.

Example 2: Environment-specific values (dev vs prod)

Keep different configs per environment using separate values files.

# values-dev.yaml
replicaCount: 1
image:
  tag: "0.2.0-dev"
resources:
  requests:
    cpu: "50m"
    memory: "128Mi"
  limits:
    cpu: "100m"
    memory: "256Mi"

# values-prod.yaml
replicaCount: 3
image:
  tag: "0.2.0"
resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
  limits:
    cpu: "1"
    memory: "1Gi"

# Install dev
helm install demo-dev ./ml-infer -f values-dev.yaml

# Install prod
helm install demo-prod ./ml-infer -f values-prod.yaml

Result: the same chart deploys differently by environment, without editing templates.

Example 3: Configurable model version via ConfigMap and rollout

Expose model settings from values into a ConfigMap mounted into the container.

# values.yaml (add)
model:
  name: fraud-detector
  version: "2024-01-15"

# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "ml-infer.fullname" . }}-config
data:
  MODEL_NAME: {{ .Values.model.name | quote }}
  MODEL_VERSION: {{ .Values.model.version | quote }}

# templates/deployment.yaml (mount as env)
        env:
          - name: MODEL_NAME
            valueFrom:
              configMapKeyRef:
                name: {{ include "ml-infer.fullname" . }}-config
                key: MODEL_NAME
          - name: MODEL_VERSION
            valueFrom:
              configMapKeyRef:
                name: {{ include "ml-infer.fullname" . }}-config
                key: MODEL_VERSION

# Upgrade to roll out a new model version
helm upgrade demo ./ml-infer --set model.version=2024-02-01

Result: a clean rollout when the model version changes, with values tracked in release history.

Common mistakes and self-check

  • Hardcoding values: If you see image tags or resource limits hardcoded in templates, move them to values.yaml. Self-check: run helm template and confirm outputs reflect overrides from --set or -f.
  • Forgetting resource requests/limits: ML pods without requests can be evicted or starve. Self-check: values.yaml must include requests and limits, and they render into Deployment.
  • Putting secrets in plain values.yaml: Avoid storing sensitive data in plain text. Prefer Kubernetes Secrets created securely and referenced by the chart. Self-check: search for passwords/tokens in repo; keep them out of version control.
  • Upgrading without dry-run: Self-check with helm upgrade --dry-run --debug to catch template errors early.
  • Inconsistent labels/selectors: Make sure Service selectors match Deployment labels. Self-check: cross-verify labels in rendered manifests.

Exercises

Do these to build confidence. You can validate output using helm template and, if you have a cluster, by installing into a disposable namespace.

Exercise 1: Pack a batch prediction CronJob

Goal: Create a Helm chart that schedules a batch prediction job (CronJob) with a configurable image and schedule.

  • Create a chart named batch-predict.
  • Add values.yaml fields: image.repository, image.tag, schedule (e.g., "0 * * * *"), and resources.
  • Template a CronJob that runs python predict.py with ENV MODEL_VERSION from values.
  • Provide two values files: dev (every 15 min) and prod (hourly).
  • Dry-run with dev and prod files; confirm schedule and tags differ.

Exercise 2: Optional GPU toggle for inference

Goal: Extend the ml-infer chart to optionally request 1 NVIDIA GPU in prod.

  • Add gpu.enabled (bool) and gpu.count (int) to values.
  • In the Deployment template, conditionally include resources.limits["nvidia.com/gpu"] when enabled.
  • Create values-prod.yaml that enables GPU and sets gpu.count: 1.
  • Dry-run for dev (no GPU) and prod (GPU present). Verify differences.
Checklist: Ready to ship?
  • Values are not hardcoded in templates.
  • helm template renders valid Kubernetes YAML without errors.
  • Service selectors match Deployment labels.
  • Resource requests/limits present and environment-specific files work.
  • Upgrade path tested with --dry-run.

Practical projects

  • Project A: Unified chart for training + inference — One chart with sub-templates to deploy either a training Job or an inference Deployment based on a value switch. Deliverables: values-dev/prod, README with commands, successful dry-run renders.
  • Project B: Blue/Green model rollout — Extend the inference chart to deploy two Deployments (blue/green) and a Service selector controlled by values. Deliverables: values-blue.yaml and values-green.yaml demonstrating a traffic switch via label change.
  • Project C: Scheduled feature computation — A CronJob chart that mounts a ConfigMap for SQL and writes to a PVC. Deliverables: chart + values showing storage class, schedule, and resource tuning.

Learning path

  • Before this: Kubernetes basics (Pods, Deployments, Services).
  • This step: Helm basics (charts, values, releases, overrides).
  • Next: Advanced templating (helpers, conditionals, loops), dependencies, and chart testing.
  • Later: GitOps with continuous delivery, progressive rollouts, and observability for ML services.

Next steps

  • Refactor common labels/annotations into a _helpers.tpl template.
  • Add a NOTES.txt to guide operators after install (port-forward, health checks).
  • Introduce a values-staging.yaml and practice promoting images via values only.
  • Set up a simple CI step that runs helm lint and helm template on pull requests.

Mini challenge

Turn the minimal inference chart into a reusable library by parameterizing container port, readiness/liveness probes, and optional autoscaling (HPA). Provide dev/prod values showing different probe thresholds and min/max replicas. Validate with helm template.

Quick Test

Take the quick test below to check your understanding. Available to everyone; only logged-in users get saved progress.

Practice Exercises

2 exercises to complete

Instructions

Create a Helm chart named batch-predict that deploys a CronJob. Make image, tag, schedule, resources, and MODEL_VERSION configurable via values. Provide dev (every 15 minutes) and prod (hourly) values files. Validate with helm template.

Expected Output
Rendering dev shows schedule '*/15 * * * *' and image tag with '-dev'. Rendering prod shows '0 * * * *' and prod tag. The CronJob spec includes resources and MODEL_VERSION env var.

Helm Basics — Quick Test

Test your knowledge with 8 questions. Pass with 70% or higher.

8 questions70% to pass

Have questions about Helm Basics?

AI Assistant

Ask questions about this tool