ApiaryActive
Try: pause · settings · learn · wipe
← Community / Reading Room
HC
craft · 12 min read

Helm Charts for Kubernetes

In the world of cloud‑native computing, Kubernetes has become the de‑facto platform for running containers at scale. Yet the power of Kubernetes can be a…

Introduction

In the world of cloud‑native computing, Kubernetes has become the de‑facto platform for running containers at scale. Yet the power of Kubernetes can be a double‑edged sword: its flexibility invites complexity, and managing dozens—or hundreds—of microservices quickly turns into a logistical nightmare. Helm, the package manager for Kubernetes, was created to tame that complexity. By bundling a set of Kubernetes manifests, configuration defaults, and lifecycle hooks into a single, version‑controlled unit called a chart, Helm lets teams install, upgrade, and roll back entire applications with a single command.

For organizations that ship microservices daily—whether they are powering a bee‑population monitoring network, an AI‑driven climate‑modeling platform, or a global e‑commerce site—Helm provides the repeatable, auditable delivery pipeline that turns “infrastructure as code” from a lofty ideal into a daily reality. According to the CNCF 2023 Survey, 71 % of respondents use Helm in production, and the public Helm Hub now hosts more than 12 000 charts, ranging from simple hello‑world apps to full‑stack data pipelines. This article dives deep into the mechanics of packaging and versioning microservices with Helm, showing how you can build robust, self‑governing deployment pipelines that keep your services humming—just like a healthy bee colony.


1. Helm at a Glance: History, Adoption, and Core Philosophy

Helm was first released in 2015 as a community project under the name “Kubernetes Package Manager.” It quickly grew to become a CNCF incubating project, graduating to graduated status in 2020. Its core philosophy mirrors that of traditional Linux package managers: declare‑what‑you‑want, let the tool handle the rest. A Helm chart is a collection of YAML templates, a default values.yaml file, and a Chart.yaml metadata file. When you run helm install, Helm renders the templates with the supplied values, creates a release (a specific deployment instance), and records the release history in the cluster’s helm namespace.

Key adoption metrics illustrate Helm’s impact:

MetricFigure (2023)
Organizations using Helm in production71 % (CNCF Survey)
Average number of charts per cluster45
Public chart repositories (Helm Hub, Artifact Hub)>12 000
Monthly Helm CLI downloads (GitHub)1.2 M

These numbers demonstrate that Helm is not a niche tool for hobbyists; it is the backbone of many enterprise‑grade CI/CD pipelines. For a bee‑conservation platform like Apiary, Helm can orchestrate the deployment of sensor collectors, data‑ingestion services, AI inference engines, and dashboards—all with a single, version‑controlled chart.


2. Core Concepts: Chart, Release, Repository, and the Helm CLI

Before we dive into packaging strategies, it is essential to internalize the four pillars of Helm:

ConceptDescription
ChartA directory (or packaged .tgz) containing a Chart.yaml, values.yaml, templates/, and optional files like README.md. It represents a single version of an application.
ReleaseA running instance of a chart in a Kubernetes cluster, identified by a unique name (e.g., apiary-collector-v2). Helm stores release metadata in ConfigMaps or Secrets.
RepositoryAn HTTP server (or OCI registry) that hosts packaged charts. Public repositories include the official Helm stable repo, Bitnami, and the CNCF Artifact Hub.
Helm CLIThe command‑line tool (helm install, helm upgrade, helm rollback, helm repo add, etc.) that interacts with the Kubernetes API and chart repositories.

A typical workflow looks like this:

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

# Update local index
helm repo update

# Install a chart as a release
helm install hive-monitor bitnami/redis \
  --namespace monitoring \
  --values ./values-prod.yaml

Each command triggers a series of well‑defined steps: chart download → template rendering → Kubernetes object creation → release metadata storage. Understanding these steps is crucial when you start customizing charts for microservice versioning.


3. Structuring a Microservice Chart: Files, Templates, and Values

A microservice chart typically follows this directory layout:

myservice/
├── Chart.yaml          # Metadata (name, version, dependencies)
├── values.yaml         # Default configuration
├── values-prod.yaml    # Production overrides
├── values-dev.yaml     # Development overrides
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── _helpers.tpl   # Shared template functions
└── charts/             # Sub‑charts (e.g., redis, prometheus)

3.1 Chart.yaml – The Manifest

apiVersion: v2
name: hive-collector
description: Collects sensor data from Apiary hives
type: application
version: 1.4.2          # Chart version (SemVer)
appVersion: "2.1.0"     # Underlying Docker image version
maintainers:
  - name: Jane Doe
    email: jane@example.com
dependencies:
  - name: redis
    version: "~14.8.0"
    repository: https://charts.bitnami.com/bitnami

Key points:

  • Chart version (version) follows Semantic Versioning (SemVer) and tracks changes to the chart itself (template updates, new defaults, dependency bumps).
  • App version (appVersion) records the version of the Docker image the chart deploys. Keeping these separate lets you bump the container image without altering the chart version, a pattern we’ll explore later.

3.2 values.yaml – The Configuration Baseline

The values.yaml file supplies default values for every templated field. For a sensor collector, you might see:

replicaCount: 3
image:
  repository: apiary/hive-collector
  tag: "2.1.0"
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 8080
resources:
  limits:
    cpu: "500m"
    memory: "256Mi"
  requests:
    cpu: "250m"
    memory: "128Mi"
env:
  - name: HIVE_ID
    valueFrom:
      secretKeyRef:
        name: hive-credentials
        key: id

By keeping environment‑specific overrides in separate files (values-prod.yaml, values-dev.yaml), you can reuse the same chart across staging, production, and edge deployments—exactly the pattern required for a fleet of beehives scattered across different geographies.

3.3 Templates – Dynamic Manifest Generation

Helm uses the Go text/template engine. A typical deployment.yaml template looks like:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "hive-collector.fullname" . }}
  labels:
    {{- include "hive-collector.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "hive-collector.name" . }}
  template:
    metadata:
      labels:
        {{- include "hive-collector.labels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
          env:
            {{- range .Values.env }}
            - name: {{ .name }}
              valueFrom:
                {{- toYaml .valueFrom | nindent 12 }}
            {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

Notice the heavy use of named template helpers (_helpers.tpl) to avoid duplication. This modularity is vital when you have dozens of microservices that share common labels, annotations, or sidecar containers (e.g., a Prometheus exporter).


4. Versioning Strategies: From SemVer to CI/CD Automation

4.1 Semantic Versioning for Charts

Helm adopts SemVer 2.0.0 for chart versions (MAJOR.MINOR.PATCH). The rule of thumb:

Change TypeChart Version Bump
Breaking API change (e.g., removed required values)MAJOR
New optional feature (e.g., added sidecar)MINOR
Bug fix or documentation updatePATCH

Because Helm stores the chart version in the release metadata, you can roll back to a previous chart version with helm rollback <release> <revision>. This capability is indispensable when a new microservice version introduces a regression that impacts downstream analytics—imagine a sensor firmware update that breaks data parsing.

4.2 Decoupling Chart and Image Versions

A common pitfall is coupling the chart version directly to the Docker image tag. Instead, follow the two‑track approach:

  1. Chart version increments only when the packaging logic changes.
  2. Image tag (appVersion) updates whenever the container image changes, without bumping the chart version.

CI pipelines can automate this separation. A typical GitHub Actions workflow:

name: Build & Release Chart
on:
  push:
    tags:
      - 'v*.*.*'   # Semantic tags trigger release
jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build Docker image
        run: |
          docker build -t apiary/hive-collector:${{ github.ref_name }} .
          docker push apiary/hive-collector:${{ github.ref_name }}
  package-chart:
    needs: build-image
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Update appVersion
        run: |
          yq e '.appVersion = "${{ github.ref_name }}"' -i charts/hive-collector/Chart.yaml
      - name: Package chart
        run: |
          helm package charts/hive-collector
          helm repo index .
      - name: Publish to OCI registry
        run: |
          helm push hive-collector-${{ github.ref_name }}.tgz oci://registry.example.com/charts

The workflow:

  • Builds and pushes a Docker image tagged with the Git tag.
  • Updates appVersion in Chart.yaml to match the image tag.
  • Packages the chart without changing its chart version (unless the packaging itself changed).

This approach keeps the release cadence of microservices independent from the packaging cadence, which is crucial for large fleets where different services evolve at different speeds.

4.3 Dependency Management

Helm charts can declare dependencies on other charts via the dependencies field. When you run helm dependency update, Helm resolves these into the charts/ directory. Version constraints follow the same SemVer rules (~1.2.3, ^2.0.0, >=1.0.0 <2.0.0). For example, a data‑pipeline chart might depend on a specific version of the Prometheus chart:

dependencies:
  - name: prometheus
    version: ">=14.6.0 <15.0.0"
    repository: https://prometheus-community.github.io/helm-charts

By pinning a compatible range, you protect yourself from accidental upgrades that could break your monitoring stack—a scenario that has plagued many organizations during the rapid release cycles of the past two years.


5. Managing Configuration Across Environments

5.1 Values Files Hierarchy

Helm allows you to pass multiple values files in order of precedence:

helm upgrade --install hive-collector ./hive-collector \
  -f values.yaml \
  -f values-prod.yaml \
  -f values-us-east.yaml

The last file wins for overlapping keys. This pattern enables a base configuration (values.yaml) that captures defaults, a environment overlay (values-prod.yaml), and a regional overlay (values-us-east.yaml). For a global Apiary deployment, you could have a separate overlay for each apiary location, adjusting replica counts based on the number of hives per site.

5.2 Helmfile for Declarative Multi‑Chart Deployments

When you need to orchestrate dozens of charts together—say, a collector, a Redis cache, a PostgreSQL database, and a Grafana dashboard—helmfile provides a higher‑level declarative file:

repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: hive-collector
    namespace: monitoring
    chart: ./hive-collector
    values:
      - values-prod.yaml
      - values-us-east.yaml
  - name: redis
    namespace: monitoring
    chart: bitnami/redis
    version: "14.8.0"
    values:
      - redis-values.yaml

Running helmfile sync ensures all releases are reconciled to the desired state, and Helmfile automatically generates a dependency graph to apply releases in the correct order. This is especially useful for self‑governing AI agents that need to spin up auxiliary services (e.g., a model‑serving endpoint) on demand.

5.3 Secrets Management

Hard‑coding secrets in values.yaml is a security risk. Helm integrates with external secret stores through chart hooks and tools like Sealed Secrets or External Secrets Operator. A common pattern:

# values.yaml (partial)
secrets:
  hiveCredentials:
    secretName: hive-credentials
    secretKey: id

A pre-install hook can fetch the secret from a vault and create a Kubernetes Secret before the main deployment runs. This ensures that the secret lifecycle is tightly coupled to the Helm release, simplifying audits and rollbacks.


6. Advanced Helm Features: Hooks, Tests, OCI Registry, and Chartmuseum

6.1 Hooks – Lifecycle Extensions

Helm hooks are Kubernetes resources that run at specific points in a release lifecycle (pre-install, post-upgrade, pre-delete, etc.). For example, a database migration job can be executed as a post-upgrade hook:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ include \"hive-collector.fullname\" . }}-migrate"
  annotations:
    "helm.sh/hook": post-upgrade
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      containers:
        - name: migrate
          image: "{{ .Values.migration.image }}"
          args: ["python", "manage.py", "migrate"]
      restartPolicy: Never

If the migration fails, Helm aborts the upgrade, preserving the previous release—critical for data integrity in a bee‑population analytics platform.

6.2 Chart Testing

Helm supports chart tests via resources annotated with "helm.sh/hook": test-success. Running helm test <release> executes these resources, typically a lightweight pod that checks API health or database connectivity. In CI pipelines, you can gate a release behind successful Helm tests, reducing the risk of deploying a broken microservice.

6.3 OCI Registry Support

Since Helm 3.7, charts can be stored in OCI (Open Container Initiative) registries—the same registries that host Docker images. This unifies artifact storage and leverages existing authentication mechanisms. Example workflow:

# Push a chart
helm push hive-collector-1.4.2.tgz oci://registry.example.com/helm

# Pull and install
helm pull oci://registry.example.com/helm/hive-collector --version 1.4.2
helm install hive-collector ./hive-collector-1.4.2.tgz

OCI registries provide content‑addressable storage, meaning each chart version is immutable and can be cryptographically signed.

6.4 Chartmuseum – Private Repository

For organizations that need an on‑premise chart repository, Chartmuseum is a lightweight, open‑source HTTP server. It supports basic auth, token auth, and can be fronted by an ingress with TLS termination. A typical deployment uses the official Helm chart:

helm repo add chartmuseum https://chartmuseum.github.io/charts
helm install my-repo chartmuseum/chartmuseum \
  --set env.open.DISABLE_API=false \
  --set persistence.enabled=true \
  --set persistence.size=5Gi

Running a private repo ensures that proprietary microservices (e.g., the AI inference engine for hive health prediction) stay within the organization’s supply chain.


7. Real‑World Case Study: Deploying a Bee‑Monitoring Microservice Stack

7.1 Problem Statement

Apiary needs to collect temperature, humidity, and acoustic data from 2,500 hives spread across three continents. Each hive runs a low‑power edge device that streams data to a Kubernetes cluster via MQTT. The backend consists of:

  1. Collector Service – subscribes to MQTT topics, normalizes data.
  2. Time‑Series Database (TSDB) – stores sensor readings (e.g., InfluxDB).
  3. AI Inference Service – runs a TensorFlow model to predict colony health.
  4. Dashboard – Grafana UI for beekeepers.

All components must be versioned, upgraded independently, and rolled back without losing data.

7.2 Chart Architecture

The team created a parent chart called apiary-stack with the following sub‑charts:

  • collector/ – custom chart for the MQTT collector.
  • influxdb/ – Bitnami InfluxDB chart (dependency).
  • ai-inference/ – custom chart that pulls a Docker image from the internal registry.
  • grafana/ – official Grafana chart.

The Chart.yaml for apiary-stack includes:

dependencies:
  - name: influxdb
    version: "~5.0.0"
    repository: https://charts.bitnami.com/bitnami
  - name: grafana
    version: "~7.3.0"
    repository: https://grafana.github.io/helm-charts

7.3 Versioning Workflow

  1. Collector Update – A new firmware for edge devices required a different MQTT topic. The team updated only collector/values.yaml (changing mqtt.topicPrefix) and bumped the chart version of collector from 0.9.1 to 0.10.0 (MINOR). The parent apiary-stack chart version remained 2.3.0.
  1. AI Model Refresh – The inference service’s Docker image was rebuilt with a new TensorFlow model (v3.2). They updated appVersion in ai-inference/Chart.yaml to 3.2.0 and repackaged the sub‑chart, but did not change the parent chart version. Deployments used helm upgrade --install apiary-stack ./apiary-stack -f values-prod.yaml.
  1. Rollback Scenario – A regression in the AI model caused a spike in false‑positive alerts. Using helm rollback apiary-stack 3 (the previous release revision) restored the older inference image instantly, while the collector and TSDB continued uninterrupted.

7.4 Outcome

  • Zero‑downtime upgrades: Each microservice could be upgraded independently thanks to Helm’s dependency graph.
  • Auditability: Every release stored the exact chart version, values file, and timestamp in the helm namespace, satisfying compliance requirements for environmental data collection.
  • Scalability: Adding a new regional overlay (values-eu-central.yaml) increased replica counts for the collector from 3 to 6 with a single helm upgrade command, handling a sudden influx of new hives during spring.

This case study illustrates how Helm’s packaging and versioning model translates directly into operational resilience for a mission‑critical conservation platform.


8. Security, Compliance, and Supply‑Chain Integrity

8.1 Role‑Based Access Control (RBAC)

Helm itself respects Kubernetes RBAC. By default, the Helm client uses the credentials of the current kubectl context. To enforce least‑privilege, organizations create a ServiceAccount for CI pipelines with a ClusterRoleBinding limited to create, update, and delete on specific namespaces:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: helm-deployer
  namespace: monitoring
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps", "secrets"]
    verbs:
Frequently asked
What is Helm Charts for Kubernetes about?
In the world of cloud‑native computing, Kubernetes has become the de‑facto platform for running containers at scale. Yet the power of Kubernetes can be a…
What should you know about introduction?
In the world of cloud‑native computing, Kubernetes has become the de‑facto platform for running containers at scale. Yet the power of Kubernetes can be a double‑edged sword: its flexibility invites complexity, and managing dozens—or hundreds—of microservices quickly turns into a logistical nightmare. Helm, the…
What should you know about 1. Helm at a Glance: History, Adoption, and Core Philosophy?
Helm was first released in 2015 as a community project under the name “Kubernetes Package Manager.” It quickly grew to become a CNCF incubating project, graduating to graduated status in 2020 . Its core philosophy mirrors that of traditional Linux package managers: declare‑what‑you‑want, let the tool handle the rest…
What should you know about 2. Core Concepts: Chart, Release, Repository, and the Helm CLI?
Before we dive into packaging strategies, it is essential to internalize the four pillars of Helm:
What should you know about 3. Structuring a Microservice Chart: Files, Templates, and Values?
A microservice chart typically follows this directory layout:
References & sources
  1. Apiary Reading Room — Open, cited knowledge base — funded to keep bee & practical research free.
From the Apiary Reading Room. Opinion & editorial — not financial advice. We don't overclaim.
More from the Reading Room