Kubernetes Helm Charts in 2026: Packaging, Deployment and Interview Questions
Learn Helm chart structure, templating, dependencies, and deployment strategies. Includes common interview questions and best practices for production deployments.

Kubernetes Helm Charts simplify application deployment by packaging all Kubernetes resources into a single, versioned artifact. Helm 3, the current stable release, eliminates the need for Tiller and introduces OCI registry support, making chart distribution more secure and standardized. This tutorial covers chart creation, templating, deployment strategies, and the most common interview questions asked by hiring teams.
Helm charts contain a Chart.yaml (metadata), values.yaml (defaults), and a templates/ directory with Kubernetes manifests. The helm install command renders templates with values and applies them to the cluster.
Understanding Helm Chart Structure and Components
A Helm chart is a directory with a predefined structure. The chart name becomes the directory name, and every file serves a specific purpose in the packaging and deployment process.
# Chart.yaml
apiVersion: v2
name: my-application
description: A production-ready web application
type: application
version: 1.0.0
appVersion: "2.1.0"
dependencies:
- name: postgresql
version: "15.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabledThe apiVersion: v2 indicates Helm 3 compatibility. The version field tracks chart changes, while appVersion reflects the deployed application version. Dependencies declare other charts this chart requires, with optional conditions to enable or disable them.
# values.yaml
replicaCount: 3
image:
repository: myregistry.io/app
tag: "2.1.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8080
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
postgresql:
enabled: true
auth:
database: appdbValues define configuration defaults that users override during installation. Nesting values under meaningful keys keeps configurations organized and self-documenting.
Creating Kubernetes Deployments with Helm Templates
Helm templates use Go templating with Sprig functions to generate Kubernetes manifests dynamically. The {{ .Values }} object provides access to values.yaml content, while {{ .Release }} contains deployment metadata.
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-application.fullname" . }}
labels:
{{- include "my-application.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-application.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-application.selectorLabels" . | nindent 8 }}
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 12 }}The nindent function adds newline and indentation, critical for YAML generation. Using include with named templates (defined in _helpers.tpl) keeps templates DRY and maintainable.
# templates/_helpers.tpl
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
app.kubernetes.io/name: {{ include "my-application.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}Helper templates standardize naming conventions and labels across all resources, ensuring consistency with Kubernetes recommended labels.
Helm Chart Dependencies and Subcharts
Complex applications often depend on databases, caches, or message queues. Helm dependencies allow embedding these as subcharts, managed automatically during installation.
# Update dependencies before packaging
helm dependency update ./my-application
# Build dependencies (creates charts/ directory)
helm dependency build ./my-applicationThe helm dependency update command downloads dependencies to the charts/ directory. Conditional dependencies use values to toggle inclusion:
# values.yaml
postgresql:
enabled: true
redis:
enabled: false# Chart.yaml
dependencies:
- name: postgresql
version: "15.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "19.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabledThis pattern enables environment-specific configurations where production uses managed services while development uses in-cluster databases.
Helm 3.8+ supports storing charts in OCI-compliant registries like Docker Hub, GitHub Container Registry, and AWS ECR. Push charts with helm push my-app-1.0.0.tgz oci://registry.example.com/charts.
Deploying Helm Charts with Release Management
Helm tracks deployments as releases, enabling versioned rollbacks and upgrades. Each release maintains history for auditing and recovery.
# Install a chart with custom values
helm install my-release ./my-application \
--namespace production \
--create-namespace \
--values production-values.yaml \
--set image.tag=2.1.1
# Upgrade an existing release
helm upgrade my-release ./my-application \
--namespace production \
--values production-values.yaml \
--set image.tag=2.2.0 \
--atomic \
--timeout 5mThe --atomic flag ensures failed upgrades automatically rollback. The --timeout flag sets how long Helm waits for resources to become ready before declaring failure.
# View release history
helm history my-release -n production
# Rollback to previous revision
helm rollback my-release 2 -n production
# Uninstall a release
helm uninstall my-release -n production --keep-historyThe --keep-history flag preserves release records even after uninstallation, useful for compliance and debugging.
Ready to ace your DevOps interviews?
Practice with our interactive simulators, flashcards, and technical tests.
Helm Chart Testing and Validation Strategies
Testing Helm charts before deployment catches template errors and configuration issues early. Helm provides built-in tools for linting and dry-run testing.
# Lint chart for errors and best practices
helm lint ./my-application
# Render templates locally without deploying
helm template my-release ./my-application \
--values production-values.yaml \
> rendered-manifests.yaml
# Dry-run against cluster API
helm install my-release ./my-application \
--dry-run \
--debug \
--namespace productionThe helm template command renders manifests locally, useful for CI pipelines that validate generated YAML. The --dry-run flag sends manifests to the Kubernetes API server for validation without creating resources.
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "my-application.fullname" . }}-test"
labels:
{{- include "my-application.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: curl
image: curlimages/curl:8.7.1
command: ['curl']
args: ['{{ include "my-application.fullname" . }}:{{ .Values.service.port }}/health']
restartPolicy: NeverHelm hooks with helm.sh/hook: test run after helm test my-release, validating deployments work correctly post-installation.
Advanced Helm Templating Techniques
Production charts require conditional logic, loops, and data transformation. Sprig functions extend Go templates with utilities for string manipulation, encoding, and flow control.
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "my-application.fullname" . }}-config
data:
{{- range $key, $value := .Values.config }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- if .Values.features.enabled }}
FEATURE_FLAGS: {{ .Values.features.flags | join "," | quote }}
{{- end }}# templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: {{ include "my-application.fullname" . }}-secrets
type: Opaque
data:
{{- range $key, $value := .Values.secrets }}
{{ $key }}: {{ $value | b64enc }}
{{- end }}The range function iterates over maps and lists. The b64enc function base64-encodes values for Kubernetes secrets. Pipe operators chain functions for data transformation.
Storing secrets in values.yaml exposes them in version control. Use external secret managers like HashiCorp Vault, AWS Secrets Manager with External Secrets Operator, or SOPS-encrypted values files for production deployments.
Helm Charts Interview Questions and Answers
Technical interviews frequently test Helm knowledge through conceptual and practical questions. The following covers the most commonly asked topics.
What is the difference between helm install and helm upgrade --install?
helm install creates a new release and fails if the release already exists. helm upgrade --install (with the --install flag) creates a new release if one doesn't exist, or upgrades it if it does. CI/CD pipelines typically use helm upgrade --install for idempotent deployments.
How do you pass sensitive data to Helm charts?
Three approaches exist: external secret managers (Vault, AWS Secrets Manager), encrypted values files (SOPS, sealed-secrets), or Kubernetes secrets created outside Helm and referenced in templates. Avoid storing secrets in plain-text values.yaml files committed to version control.
What are Helm hooks and when should you use them?
Hooks execute at specific points in release lifecycle: pre-install, post-install, pre-upgrade, post-upgrade, pre-delete, post-delete, pre-rollback, post-rollback, and test. Common uses include database migrations before upgrades, sending notifications after deployments, or running integration tests.
How do you handle chart versioning?
The version field in Chart.yaml tracks chart changes using semantic versioning. The appVersion field tracks the deployed application version. Increment version for any chart modification, even if the application version stays the same.
What is the purpose of .helmignore?
Similar to .gitignore, .helmignore excludes files from chart packaging. Typical entries include *.tgz (avoid packaging previous builds), .git/, *.md documentation not needed at runtime, and CI configuration files.
For more Kubernetes interview preparation, explore the Kubernetes Basics and Kubernetes Advanced question modules on SharpSkill.
Conclusion
Practical takeaways for working with Helm charts:
- Structure charts with clear separation between Chart.yaml metadata, values.yaml defaults, and templates directory containing Kubernetes manifests
- Use helper templates in _helpers.tpl to standardize naming and labels across all resources
- Manage dependencies through Chart.yaml with conditional enablement for environment-specific configurations
- Test charts with
helm lint,helm template, andhelm install --dry-runbefore deploying to production - Track releases with meaningful names and use
--atomicflag for automatic rollback on failed upgrades - Store secrets in external managers rather than plain-text values files
Start practicing!
Test your knowledge with our interview simulators and technical tests.
Tags
Share
Related articles

Kubernetes Interview: Pods, Services and Deployments Explained
Master the three core Kubernetes building blocks — Pods, Services, and Deployments — with production-ready YAML manifests, networking internals, and common interview questions.

Kubernetes: Deploying Your First Application
Hands-on guide to deploying an application on Kubernetes. From minikube installation to Deployments, Services, and ConfigMaps with practical examples.

Essential DevOps Interview Questions: Complete Guide 2026
Prepare for DevOps interviews with must-know questions on CI/CD, Kubernetes, Docker, Terraform, and SRE practices. Detailed answers included.