Helm: Kubernetes Package Manager


Helm is widely known as "the package manager for Kubernetes." It simplifies application deployment by packaging Kubernetes resources into reusable, versioned units called charts. Helm helps you manage complexity, standardize deployments, and enable easy rollbacks of Kubernetes applications.

What is Helm?

Helm is a tool that streamlines installing and managing Kubernetes applications. Think of it like apt/yum/homebrew for Kubernetes. It provides several key capabilities:

  • Chart Management: Find, share, and use software packaged as Kubernetes charts
  • Release Management: Install, upgrade, and rollback applications with ease
  • Templating: Parameterize Kubernetes manifests for different environments
  • Dependency Management: Handle complex applications with multiple components

Helm Components

Helm consists of two main components:

Helm Client (CLI)

The command-line interface that users interact with. It's responsible for:

  • Local chart development
  • Managing repositories
  • Interacting with the Helm library
  • Sending charts to be installed

Helm Library

The logic that interacts with the Kubernetes API server to:

  • Combine charts and configuration to build a release
  • Install charts into Kubernetes and track subsequent releases
  • Upgrade and rollback releases by interacting with Kubernetes

Understanding Helm Charts

A Helm chart is a collection of files that describe a related set of Kubernetes resources. Charts are the packaging format used by Helm, similar to DEB or RPM packages in Linux systems.

Chart Structure

A typical Helm chart has the following directory structure:

mychart/
├── Chart.yaml          # Information about the chart
├── values.yaml         # Default configuration values
├── charts/             # Directory containing dependency charts
├── templates/          # Template files
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl    # Helper templates
│   └── tests/          # Test files
└── README.md           # Documentation
    

Chart.yaml

The Chart.yaml file contains metadata about the chart:

apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes
type: application
version: 1.2.3
appVersion: 2.1.0
dependencies:
  - name: redis
    version: 10.5.7
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
    

Template Files

Templates are Kubernetes manifest files with added template functions and variables. Helm uses the Go template language extended with Sprig functions and special Helm functions.

Example Deployment Template

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}
  labels:
    app: {{ .Chart.Name }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
      release: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
        release: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - containerPort: {{ .Values.service.port }}
          env:
            - name: ENVIRONMENT
              value: {{ .Values.environment }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
    

Values.yaml

The values.yaml file provides default configuration values for the template:

replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
  hosts:
    - host: chart-example.local
      paths: []

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi
    

Template Functions and Pipelines

Helm provides powerful template functions to manipulate data:

# String manipulation
name: {{ .Values.name | upper | quote }}

# Default values
replicas: {{ .Values.replicas | default 3 }}

# Conditional logic
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
{{- end }}

# Range loops
env:
{{- range .Values.extraEnv }}
  - name: {{ .name }}
    value: {{ .value | quote }}
{{- end }}

# With blocks
{{- with .Values.resources }}
resources:
  limits:
    cpu: {{ .limits.cpu }}
    memory: {{ .limits.memory }}
  requests:
    cpu: {{ .requests.cpu }}
    memory: {{ .requests.memory }}
{{- end }}
    

Deploying Applications with Helm

Helm Repositories

Helm charts are stored in repositories. You can add, list, and search repositories:

# Add a repository
helm repo add bitnami https://charts.bitnami.com/bitnami

# List repositories
helm repo list

# Update repository information
helm repo update

# Search for charts
helm search repo nginx

# Remove a repository
helm repo remove bitnami
    

Installing Charts

You can install charts from various sources:

From a Repository

# Install the latest version
helm install my-release bitnami/nginx

# Install a specific version
helm install my-release bitnami/nginx --version 9.5.4

# Install with custom values
helm install my-release bitnami/nginx -f values.yaml

# Install with set values
helm install my-release bitnami/nginx \
  --set service.type=LoadBalancer \
  --set replicaCount=3
    

From a Local Chart Directory

# Install from local directory
helm install my-release ./mychart

# Dry-run to test installation
helm install my-release ./mychart --dry-run

# Debug template rendering
helm template my-release ./mychart
    

From a Chart Archive

# Package a chart first
helm package ./mychart

# Install from the packaged chart
helm install my-release mychart-1.2.3.tgz
    

Managing Releases

Helm keeps track of installed charts as "releases":

# List releases
helm list

# List all releases (including deleted ones)
helm list --all

# Get status of a release
helm status my-release

# Get the manifest of a release
helm get manifest my-release

# Get the values of a release
helm get values my-release

# Upgrade a release
helm upgrade my-release bitnami/nginx --set replicaCount=3

# Rollback a release
helm rollback my-release 1

# Uninstall a release
helm uninstall my-release
    

Advanced Helm Features

Chart Dependencies

Charts can depend on other charts, which are stored in the charts/ directory:

# Manage dependencies
helm dependency update ./mychart
helm dependency build ./mychart
helm dependency list ./mychart
    

Hooks

Helm hooks allow you to intervene at certain points in a release lifecycle:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}-db-migration"
  annotations:
    "helm.sh/hook": pre-upgrade,pre-install
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": before-hook-creation
spec:
  template:
    spec:
      containers:
      - name: db-migration
        image: alpine
        command: ["/bin/sh", "-c", "echo 'Running database migration'"]
      restartPolicy: Never
    

Tests

Helm supports test definitions to validate chart installations:

# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ .Release.Name }}-test-connection"
  annotations:
    "helm.sh/hook": test
spec:
  containers:
  - name: wget
    image: busybox
    command: ['wget']
    args: ['{{ .Release.Name }}:{{ .Values.service.port }}']
  restartPolicy: Never
    

Best Practices

Chart Development

  • Follow semantic versioning for charts
  • Use template functions for conditional resources
  • Include comprehensive values.yaml with comments
  • Provide README with installation instructions
  • Include NOTES.txt for post-install information

Security

  • Never include secrets in charts - use external secret management
  • Validate chart sources before installation
  • Use --dry-run to preview changes before applying
  • Limit Tiller permissions in Helm 2 (Helm 3 doesn't use Tiller)

CI/CD Integration

  • Store charts in version control
  • Automate chart testing and linting
  • Use chart museum or OCI registries for chart storage
  • Implement automated release processes

Helm 2 vs Helm 3

Helm 3 introduced significant improvements over Helm 2:

  • Removed Tiller: No server-side component, improved security
  • Improved Upgrade Strategy: Three-way strategic merge patches
  • Library Charts
  • OCI Support: Store charts in OCI registries
  • JSON Schema Validation

Helm dramatically simplifies Kubernetes application management by providing a consistent way to define, install, and upgrade even the most complex applications. Its templating system, release management, and repository ecosystem make it an indispensable tool for Kubernetes operators and developers.

Post a Comment

0 Comments