Mastering Helm

The Package Manager for Kubernetes

Helm has become an essential tool in the Kubernetes ecosystem, used by 70% of organizations in their cloud environments. As the official package manager for Kubernetes, Helm transforms complex application deployments from managing dozens of YAML files into a single, repeatable command. This guide will walk you through everything from Helm fundamentals to advanced practices for production deployments.

What is Helm and Why Does It Matter?

Helm is a templating engine and package manager that simplifies deploying applications on Kubernetes. A Helm Chart is a collection of pre-configured Kubernetes resources that define how an application should be deployed.

The core concepts are straightforward:

TermDefinition
ChartA Helm package containing all Kubernetes manifests needed to deploy an application
ReleaseAn instance of a chart deployed in your cluster with a specific configuration
RepositoryAn HTTP server hosting downloadable Helm charts
ValuesConfiguration parameters you pass to the chart to customize the deployment

Without Helm, deploying a complex application like WordPress requires managing separate YAML files for Deployments, Services, PersistentVolumeClaims, Ingress, and Secrets—often 15-25 files per service. With Helm, a single command handles everything.

Installation and Getting Started

Installing Helm

Install Helm on your preferred operating system:

macOS:

bash

brew install helm

Linux:

bash

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Windows:

bash

choco install kubernetes-helm

Verify your installation:

bash

helm version

Adding Repositories

Helm repositories work like package registries. Add the Bitnami repository—one of the most trusted sources for production-ready charts:

bash

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

Deploying WordPress with Helm

Deploying WordPress on Kubernetes demonstrates Helm’s power. With one command, you get a fully functional WordPress installation with a MariaDB database:

bash

helm install my-wordpress oci://registry-1.docker.io/bitnamicharts/wordpress

After deployment, retrieve your WordPress credentials:

bash

# Get the admin password
kubectl get secret my-wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d

# Get the service URL
export SERVICE_IP=$(kubectl get svc my-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
echo "WordPress URL: http://$SERVICE_IP/"

Customizing Deployments with Values

While the default installation works, real-world deployments require customization. Helm offers three ways to override default values:

1. Command-Line Overrides

For quick changes:

bash

helm install my-wordpress bitnami/wordpress \
  --set wordpressBlogName="My Awesome Blog" \
  --set wordpressUsername=admin

2. Custom Values File

For multiple overrides, create a custom-values.yaml file:

yaml

wordpressBlogName: My Awesome Blog
wordpressEmail: admin@example.com
replicaCount: 2

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"

Then deploy with:

bash

helm install my-wordpress bitnami/wordpress -f custom-values.yaml

3. Local Chart Modification

Pull the chart locally and edit the built-in values.yaml:

bash

helm pull --untar bitnami/wordpress
# Edit wordpress/values.yaml
helm install my-wordpress ./wordpress

Managing Release Lifecycle

Helm provides robust lifecycle management that manual kubectl apply cannot match:

Upgrading

bash

helm upgrade my-wordpress bitnami/wordpress -f updated-values.yaml

Viewing History

bash

helm history my-wordpress

Rolling Back

bash

# Rollback to revision 1
helm rollback my-wordpress 1

This capability is critical for production environments. A rollback takes approximately 30 seconds with zero downtime.

Uninstalling

bash

helm uninstall my-wordpress

Advanced Configuration for Production

Resource Management

For production workloads, always set resource requests and limits. The Bitnami WordPress chart provides resourcesPreset values, but custom configuration is recommended for production:

yaml

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"

External Database Support

For managed database services or shared database servers:

yaml

mariadb:
  enabled: false

externalDatabase:
  host: myexternalhost
  user: myuser
  password: mypassword
  database: mydatabase
  port: 3306

Enabling Memcached for Performance

Cache database queries to improve website performance:

yaml

wordpressConfigureCache: true
memcached:
  enabled: true

Ingress Configuration

Expose WordPress with TLS:

yaml

ingress:
  enabled: true
  hostname: wordpress.example.com
  tls: true

Creating Your Own Charts

When you need to package your own applications, Helm provides a complete framework:

Generate Chart Structure

bash

helm create my-app

This creates:

text

my-app/
├── Chart.yaml          # Chart metadata
├── values.yaml         # Default values
├── templates/          # Kubernetes templates
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── _helpers.tpl    # Helper functions
└── charts/             # Dependencies

Best Practices for Chart Development

1. Separate Environment Values:
Create environment-specific values files:

text

values-dev.yaml
values-staging.yaml
values-prod.yaml

2. Limit Template Logic:
Keep templates clean and avoid complex conditionals. Templates should look like configuration, not application code.

3. Version Charts Semantically:

  • Patch for fixes
  • Minor for backward-compatible updates
  • Major for breaking changes

4. Manage Secrets Externally:
Never store secrets in plain values files. Reference Kubernetes Secrets or use external secret managers.

5. Test Before Deploying:

bash

# Lint the chart
helm lint my-app

# Preview rendered templates
helm template my-app ./my-app -f custom-values.yaml

# Dry-run installation
helm install my-app ./my-app --dry-run --debug

Helm and GitOps with ArgoCD

While Helm handles packaging and deployment, ArgoCD extends it with GitOps capabilities:

Helm alone: A developer runs helm upgrade from a CI/CD pipeline when code is pushed.

Helm + ArgoCD: ArgoCD monitors Git and automatically syncs the cluster to match the Git state. Manual changes are detected and reverted—the cluster is self-healing.

The combination creates a powerful workflow where promoting from staging to production is simply a Git operation—update the image tag in the production values file and merge the PR.

Common Pitfalls to Avoid

1. Not Committing Charts to Git:
When Helm tries to manage resources created with kubectl apply, it can’t track them. Always commit charts to Git.

2. Configuration Drift Across Environments:
Without Helm, maintaining three sets of near-identical YAML files for dev, staging, and production leads to drift. One chart with environment-specific values solves this.

3. Immutable Field Errors:
spec.selector cannot be changed after creation. Plan for this in your templates.

4. Overloaded Templates:
Keep templates small and focused. Avoid deep nesting and hidden behavior.

Conclusion

Helm has become the standard for Kubernetes deployments for good reason. It eliminates the complexity of managing hundreds of YAML files, provides version-controlled rollbacks, and enables consistent deployments across environments.

Whether you’re deploying WordPress or your own applications, Helm transforms Kubernetes from a complex orchestration platform into a manageable, repeatable deployment system. Combined with GitOps practices using ArgoCD, it creates a complete, auditable deployment pipeline that scales with your organization.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *