DevToolBox免费
博客

Helm 完全指南:Kubernetes 包管理器

22 min read作者 DevToolBox Team
TL;DR

Helm 是 Kubernetes 的包管理器。它将清单文件打包为可复用的 Chart,通过 values.yaml 进行配置。核心命令:helm install(部署)、helm upgrade(更新)、helm rollback(回滚)、helm uninstall(卸载)。Chart 使用 Go 模板引擎和内置对象(.Values、.Release、.Chart)。使用 Helmfile 管理多个 Release,使用 Chart 仓库(Artifact Hub、Harbor、ChartMuseum)共享 Chart,使用 helm-secrets 或 Cosign 保障安全。Helm 擅长复杂的多环境部署;Kustomize 更适合基于 overlay 的补丁方案。

Key Takeaways
  • Helm packages Kubernetes manifests into reusable Charts with configurable values and versioned releases.
  • Core commands: helm install, helm upgrade, helm rollback, helm uninstall, helm list, helm repo, helm search.
  • Charts use Go template syntax with built-in objects: .Values, .Release, .Chart, .Capabilities.
  • Override values via -f values-file.yaml or --set key=value; multiple sources merge with defined precedence.
  • Hooks (pre-install, post-upgrade, etc.) run Jobs at lifecycle points for migrations, backups, and tests.
  • Helmfile manages multiple releases declaratively; chart repos (Harbor, ChartMuseum) enable team sharing.
  • Helm excels at parameterized packaging; Kustomize excels at overlay patching. Many teams use both.

What Is Helm?

Helm is the package manager for Kubernetes. Just as apt manages packages on Debian, npm manages packages for Node.js, and Homebrew manages packages on macOS, Helm manages packages for Kubernetes clusters. A Helm package is called a Chart — a collection of Kubernetes manifest templates bundled with default configuration values and metadata.

Without Helm, deploying a production application to Kubernetes means writing and maintaining dozens of YAML files — Deployments, Services, ConfigMaps, Secrets, Ingress, PersistentVolumeClaims, ServiceAccounts, RBAC roles, and more. When you need the same application in dev, staging, and production with different configurations, you end up duplicating YAML or writing brittle sed scripts. Helm solves this by parameterizing your manifests: you write templates once, and customize each deployment through a values file.

Helm v3 (the current major version since 2019) removed the server-side Tiller component that was required in v2, making Helm a purely client-side tool. It stores release state as Kubernetes Secrets in the target namespace, uses three-way strategic merge patches for upgrades, and supports OCI registries for chart distribution.

Installing Helm

Helm is distributed as a single binary. Install it on any platform and verify the installation with helm version.

# ── macOS ────────────────────────────────────────────────────────
brew install helm

# ── Linux (official script) ───────────────────────────────────
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# ── Linux (snap) ─────────────────────────────────────────────
sudo snap install helm --classic

# ── Windows (Chocolatey) ─────────────────────────────────────
choco install kubernetes-helm

# ── Windows (Scoop) ──────────────────────────────────────────
scoop install helm

# ── Verify installation ──────────────────────────────────────
helm version
# version.BuildInfo{Version:"v3.16.x", ...}

# ── Shell completion ─────────────────────────────────────────
helm completion bash > /etc/bash_completion.d/helm
helm completion zsh > "${fpath[1]}/_helm"

Helm Core Concepts: Charts, Releases, and Repositories

Charts

A Chart is a directory (or .tgz archive) containing all the Kubernetes resource definitions needed to run an application. Every chart has a Chart.yaml (metadata), a values.yaml (default configuration), and a templates/ directory containing Go-templated Kubernetes manifests.

Releases

A Release is a running instance of a Chart in a Kubernetes cluster. When you run helm install my-app ./my-chart, Helm creates a release named "my-app". You can install the same chart multiple times with different release names and different values, each producing an independent set of Kubernetes resources. Each release has a revision history, enabling upgrades and rollbacks.

Repositories

A Repository is an HTTP server or OCI registry that hosts packaged charts. Artifact Hub (artifacthub.io) is the public discovery portal aggregating charts from hundreds of repositories. You can also run private repositories using Harbor, ChartMuseum, or any OCI-compatible registry (Docker Hub, GitHub Container Registry, AWS ECR).

# Helm Concepts Overview
#
# Chart (Package)      ──install──▶  Release (Instance)
#   Chart.yaml                         my-app (rev 1)
#   values.yaml         ──upgrade──▶  my-app (rev 2)
#   templates/                          
#     deployment.yaml   ──rollback──▶ my-app (rev 1)
#     service.yaml
#     ingress.yaml      ──uninstall──▶ (deleted)
#
# Repository: where charts are stored and shared
#   artifacthub.io  |  Harbor  |  ChartMuseum  |  OCI Registry

Essential Helm Commands

Repository Management

# Add a chart repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jetstack https://charts.jetstack.io

# Update local repo index
helm repo update

# List configured repos
helm repo list

# Search for charts
helm search repo redis              # Search local repos
helm search hub wordpress           # Search Artifact Hub
helm search repo bitnami/postgresql --versions  # All versions

Install, Upgrade, Rollback, Uninstall

# ── Install a chart ──────────────────────────────────────────
helm install my-redis bitnami/redis \
  --namespace caching --create-namespace \
  --set auth.password=supersecret \
  --set replica.replicaCount=3

# Install with custom values file
helm install my-app ./my-chart -f prod-values.yaml

# Dry-run to preview (no actual install)
helm install my-app ./my-chart --dry-run --debug

# ── List releases ─────────────────────────────────────────
helm list                           # Current namespace
helm list -A                        # All namespaces
helm list --failed                  # Only failed releases

# ── Upgrade a release ─────────────────────────────────────
helm upgrade my-redis bitnami/redis \
  --set replica.replicaCount=5

helm upgrade my-app ./my-chart -f prod-values.yaml

# Install if not exists, upgrade if exists
helm upgrade --install my-app ./my-chart -f values.yaml

# ── Rollback ──────────────────────────────────────────────
helm history my-redis               # Show revision history
helm rollback my-redis 1            # Rollback to revision 1
helm rollback my-redis 0            # Rollback to previous

# ── Uninstall ─────────────────────────────────────────────
helm uninstall my-redis
helm uninstall my-redis --keep-history  # Keep release history

Inspect and Debug

# Show chart info
helm show chart bitnami/redis       # Chart.yaml metadata
helm show values bitnami/redis      # Default values.yaml
helm show readme bitnami/redis      # README
helm show all bitnami/redis         # Everything

# View release details
helm get values my-redis            # User-supplied values
helm get values my-redis --all      # All values (merged)
helm get manifest my-redis          # Rendered K8s manifests
helm get notes my-redis             # Post-install notes

# Render templates locally without installing
helm template my-app ./my-chart -f values.yaml
helm template my-app ./my-chart --debug  # With debug info

Creating Your Own Helm Chart

Use helm create to scaffold a new chart. This generates a complete directory structure with best-practice defaults including a Deployment, Service, Ingress, ServiceAccount, and HPA templates.

# Scaffold a new chart
helm create my-app

# Generated structure:
my-app/
  Chart.yaml          # Chart metadata (name, version, deps)
  values.yaml         # Default configuration values
  charts/             # Dependency charts (subcharts)
  templates/          # Go-templated Kubernetes manifests
    deployment.yaml
    service.yaml
    ingress.yaml
    serviceaccount.yaml
    hpa.yaml
    NOTES.txt          # Post-install instructions
    _helpers.tpl        # Reusable template snippets
    tests/
      test-connection.yaml

Chart.yaml

apiVersion: v2
name: my-app
description: A Helm chart for My Application
type: application          # "application" or "library"
version: 0.1.0             # Chart version (SemVer)
appVersion: "1.16.0"       # App version (informational)
keywords:
  - web
  - api
maintainers:
  - name: DevOps Team
    email: devops@example.com
dependencies:
  - name: postgresql
    version: "~13.0"
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled

values.yaml

# Default values for my-app
replicaCount: 2

image:
  repository: myregistry.io/my-app
  tag: "latest"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  host: my-app.example.com
  tls: []

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

env:
  - name: NODE_ENV
    value: production
  - name: LOG_LEVEL
    value: info

postgresql:
  enabled: true
  auth:
    database: myapp
    username: appuser

Helm Template Language

Helm uses the Go template engine (text/template) extended with Sprig functions and custom Helm functions. Templates are rendered before being sent to Kubernetes, producing valid YAML manifests. Understanding the template language is essential for creating flexible, production-grade charts.

Built-in Objects

  • .Values — user-supplied configuration merged from values.yaml, -f files, and --set flags.
  • .Release — release metadata: .Release.Name, .Release.Namespace, .Release.Revision, .Release.IsUpgrade, .Release.IsInstall.
  • .Chart — contents of Chart.yaml: .Chart.Name, .Chart.Version, .Chart.AppVersion.
  • .Capabilities — cluster info: .Capabilities.KubeVersion, .Capabilities.APIVersions.
  • .Template — current template info: .Template.Name, .Template.BasePath.
  • .Files — access non-template files in the chart: .Files.Get, .Files.GetBytes, .Files.AsConfig.

Template Syntax and Functions

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels:
    {{- include "my-app.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "my-app.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-app.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
          {{- if .Values.resources }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          {{- end }}
          {{- if .Values.env }}
          env:
            {{- range .Values.env }}
            - name: {{ .name }}
              value: {{ .value | quote }}
            {{- end }}
          {{- end }}

Pipelines and Sprig Functions

# ── Pipelines: chain functions with | ─────────────────────────
{{ .Values.name | upper | quote }}         # "MY-APP"
{{ .Values.name | default "fallback" }}    # Use fallback if empty
{{ .Values.port | int }}                   # Cast to integer

# ── String functions ───────────────────────────────────────────
{{ trim .Values.name }}
{{ trimSuffix "-" .Values.name }}
{{ printf "%s-%s" .Release.Name .Chart.Name }}
{{ .Values.name | replace "-" "_" }}

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

{{- if and .Values.tls.enabled .Values.tls.secret }}
  tls:
    - secretName: {{ .Values.tls.secret }}
{{- else if .Values.tls.enabled }}
  tls:
    - secretName: {{ .Release.Name }}-tls
{{- end }}

# ── Range (iteration) ─────────────────────────────────────────
{{- range .Values.ingress.hosts }}
  - host: {{ .host | quote }}
    http:
      paths:
        {{- range .paths }}
        - path: {{ .path }}
          pathType: {{ .pathType }}
        {{- end }}
{{- end }}

# ── toYaml for nested structures ──────────────────────────────
{{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
{{- end }}

Named Templates (_helpers.tpl)

# templates/_helpers.tpl
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

{{- define "my-app.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
{{ include "my-app.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

Values and Overrides

Helm merges values from multiple sources with a defined precedence. Understanding this merge order is critical for managing per-environment configurations correctly.

# Value precedence (lowest to highest):
# 1. Chart default values.yaml
# 2. Parent chart values (if subchart)
# 3. -f / --values files (left to right)
# 4. --set / --set-string / --set-file flags

# ── Per-environment values files ─────────────────────────────
# values.yaml          (defaults)
# values-dev.yaml      (dev overrides)
# values-staging.yaml  (staging overrides)
# values-prod.yaml     (production overrides)

# Deploy to staging:
helm upgrade --install my-app ./my-chart \
  -f values.yaml \
  -f values-staging.yaml \
  --namespace staging

# Deploy to production with an extra override:
helm upgrade --install my-app ./my-chart \
  -f values.yaml \
  -f values-prod.yaml \
  --set image.tag=v2.5.0 \
  --namespace production

# View all merged values for a release:
helm get values my-app --all

# Show chart defaults:
helm show values bitnami/redis > redis-defaults.yaml

Dependencies and Subcharts

Charts can depend on other charts. Dependencies are declared in Chart.yaml and downloaded into the charts/ directory. This lets you compose complex applications (e.g., your app + PostgreSQL + Redis) as a single deployable unit.

# Chart.yaml dependencies section
dependencies:
  - name: postgresql
    version: "~13.0"
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled
  - name: redis
    version: "~18.0"
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
  - name: common
    version: "~2.0"
    repository: https://charts.bitnami.com/bitnami
    tags:
      - infrastructure

# ── Manage dependencies ──────────────────────────────────────
helm dependency update ./my-chart   # Download deps to charts/
helm dependency list ./my-chart     # List deps and status
helm dependency build ./my-chart    # Rebuild Chart.lock

# ── Override subchart values in parent values.yaml ───────────
# values.yaml
postgresql:
  enabled: true
  auth:
    database: myapp
    username: appuser
    password: secret123
  primary:
    persistence:
      size: 20Gi

redis:
  enabled: true
  auth:
    enabled: false
  replica:
    replicaCount: 2

Helm Hooks

Hooks let you run operations at specific points in the release lifecycle. They are standard Kubernetes resources with special annotations that tell Helm when to execute them. Common use cases include database migrations before an upgrade, cache warming after an install, and backups before a delete.

  • pre-install — runs after templates are rendered but before any resources are created.
  • post-install — runs after all resources are created and ready.
  • pre-upgrade — runs before an upgrade (ideal for database migrations and backups).
  • post-upgrade — runs after upgrade is complete.
  • pre-delete / post-delete — runs before/after release deletion.
  • pre-rollback / post-rollback — runs before/after a rollback operation.
  • test — runs when helm test is invoked.
# templates/db-migration-hook.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "my-app.fullname" . }}-db-migrate
  annotations:
    "helm.sh/hook": pre-upgrade,pre-install
    "helm.sh/hook-weight": "0"       # Lower runs first
    "helm.sh/hook-delete-policy": before-hook-creation
spec:
  backoffLimit: 3
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          command: ["npm", "run", "db:migrate"]
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: {{ include "my-app.fullname" . }}-db
                  key: url

# Hook delete policies:
#   before-hook-creation  - delete previous hook before new one
#   hook-succeeded        - delete after success
#   hook-failed           - delete after failure

Chart Testing

Helm supports built-in testing via the helm test command. Test resources are annotated with helm.sh/hook: test and typically verify that the deployed application is reachable and functioning correctly.

# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: {{ include "my-app.fullname" . }}-test
  annotations:
    "helm.sh/hook": test
spec:
  restartPolicy: Never
  containers:
    - name: wget
      image: busybox:latest
      command:
        - /bin/sh
        - -c
        - |
          wget -qO- http://{{ include "my-app.fullname" . }}:{{ .Values.service.port }}/health
          if [ \$? -eq 0 ]; then echo "PASS"; else echo "FAIL" && exit 1; fi

# Run tests
helm test my-app
helm test my-app --logs    # Show test pod logs

# ── Lint and validate ────────────────────────────────────────
helm lint ./my-chart               # Check chart for issues
helm lint ./my-chart -f values-prod.yaml  # Lint with values

# Validate rendered templates with kubeval or kubeconform
helm template my-app ./my-chart | kubeconform -strict

Helmfile: Managing Multiple Releases

Helmfile is a declarative specification for deploying multiple Helm charts. It defines a desired state of Helm releases and lets you apply, diff, and destroy them as a group. Think of it as a Terraform for Helm releases — you declare what you want, and Helmfile reconciles the cluster to match.

# helmfile.yaml
repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami
  - name: ingress-nginx
    url: https://kubernetes.github.io/ingress-nginx

environments:
  dev:
    values:
      - env/dev.yaml
  staging:
    values:
      - env/staging.yaml
  production:
    values:
      - env/production.yaml

releases:
  - name: ingress
    chart: ingress-nginx/ingress-nginx
    namespace: ingress-system
    version: 4.10.x
    values:
      - ingress-values.yaml

  - name: my-api
    chart: ./charts/my-api
    namespace: {{ .Environment.Name }}
    values:
      - charts/my-api/values.yaml
      - charts/my-api/values-{{ .Environment.Name }}.yaml
    set:
      - name: image.tag
        value: {{ requiredEnv "IMAGE_TAG" }}

  - name: database
    chart: bitnami/postgresql
    namespace: {{ .Environment.Name }}
    version: 13.x
    condition: database.enabled
    values:
      - db-values.yaml

# ── Helmfile commands ────────────────────────────────────────
# helmfile -e staging sync        # Apply all releases
# helmfile -e production diff     # Preview changes
# helmfile -e dev destroy         # Remove all releases
# helmfile -e staging apply       # Sync with confirmation
# helmfile -l name=my-api sync    # Sync specific release

Chart Repositories: Harbor, ChartMuseum, and OCI

For teams that need private chart hosting, several options exist beyond the public Artifact Hub. Harbor provides enterprise-grade registry features. ChartMuseum is a lightweight chart server. Modern Helm also supports OCI registries natively.

# ── ChartMuseum (lightweight chart server) ───────────────────
# Install ChartMuseum
helm repo add chartmuseum https://chartmuseum.github.io/charts
helm install chartmuseum chartmuseum/chartmuseum \
  --set env.open.DISABLE_API=false \
  --set persistence.enabled=true

# Push a chart to ChartMuseum
helm package ./my-chart
curl --data-binary "@my-chart-0.1.0.tgz" \
  http://chartmuseum.example.com/api/charts

# ── OCI Registry (Docker Hub, GHCR, ECR, Harbor) ────────────
# Login to registry
helm registry login ghcr.io -u USERNAME

# Package and push
helm package ./my-chart
helm push my-chart-0.1.0.tgz oci://ghcr.io/myorg/charts

# Pull and install from OCI
helm pull oci://ghcr.io/myorg/charts/my-chart --version 0.1.0
helm install my-app oci://ghcr.io/myorg/charts/my-chart \
  --version 0.1.0

# ── Harbor (enterprise registry) ────────────────────────────
helm repo add harbor https://harbor.example.com/chartrepo/myproject
helm push my-chart-0.1.0.tgz harbor

Helm with CI/CD: GitHub Actions and ArgoCD

GitHub Actions

# .github/workflows/helm-deploy.yaml
name: Deploy with Helm
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Helm
        uses: azure/setup-helm@v4
        with:
          version: v3.16.0

      - name: Configure kubeconfig
        run: |
          mkdir -p \$HOME/.kube
          echo "\${{ secrets.KUBECONFIG }}" > \$HOME/.kube/config

      - name: Helm lint
        run: helm lint ./charts/my-app

      - name: Deploy to staging
        run: |
          helm upgrade --install my-app ./charts/my-app \
            -f charts/my-app/values-staging.yaml \
            --set image.tag=\${{ github.sha }} \
            --namespace staging \
            --wait --timeout 5m

ArgoCD with Helm

# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/my-app.git
    targetRevision: main
    path: charts/my-app
    helm:
      valueFiles:
        - values-production.yaml
      parameters:
        - name: image.tag
          value: v2.5.0
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Helm Security: Signing and Provenance

Helm supports chart signing and verification using GnuPG (GPG) keys. A provenance file (.prov) is generated alongside the chart archive, containing a cryptographic signature and a SHA-256 hash of the chart. This ensures chart integrity and authenticity.

# ── Sign a chart with GPG ────────────────────────────────────
# Generate a GPG key (if you do not have one)
gpg --full-generate-key

# Package and sign
helm package --sign --key "DevOps Team" \
  --keyring ~/.gnupg/secring.gpg ./my-chart
# Produces: my-chart-0.1.0.tgz + my-chart-0.1.0.tgz.prov

# ── Verify a chart ────────────────────────────────────────
helm verify my-chart-0.1.0.tgz
helm install --verify my-app my-chart-0.1.0.tgz

# ── OCI + Cosign (sigstore) ──────────────────────────────
# Modern alternative using keyless signing
cosign sign ghcr.io/myorg/charts/my-chart:0.1.0
cosign verify ghcr.io/myorg/charts/my-chart:0.1.0

# ── Helm Secrets plugin (encrypted values) ──────────────
helm plugin install https://github.com/jkroepke/helm-secrets

# Encrypt a values file with SOPS + age
sops --encrypt --age age1abc123... values-secrets.yaml \
  > values-secrets.enc.yaml

# Deploy with encrypted values
helm secrets upgrade my-app ./my-chart \
  -f values.yaml \
  -f values-secrets.enc.yaml

Helm Best Practices

  • Pin chart versions — always specify --version when installing from repositories. Never rely on "latest" in production.
  • Use helm upgrade --install — this idempotent command installs if the release does not exist and upgrades if it does. Ideal for CI/CD.
  • Always pass --wait and --timeout--wait makes Helm wait until all resources are ready before marking the release as successful. --timeout 5m prevents indefinite hangs.
  • Keep values.yaml minimal — only include parameters that users genuinely need to customize. Document each value with comments.
  • Use _helpers.tpl — extract reusable template logic (names, labels, selectors) into named templates to avoid repetition and ensure consistency.
  • Run helm lint and helm template — lint catches structural issues and template renders manifests locally for inspection before deploying.
  • Version your charts with SemVer — bump the chart version on every change. Use appVersion to track the application version independently.
  • Use --atomic for safety--atomic automatically rolls back a failed upgrade, preventing broken releases in production.
  • Separate secrets from values — use helm-secrets or external secret managers (Vault, AWS Secrets Manager, SOPS) instead of putting secrets in plain values files.
  • Test your charts — write helm test hooks, use ct (chart-testing) for CI, and validate rendered output with kubeconform.

Helm vs Kustomize

Helm and Kustomize are the two dominant approaches to managing Kubernetes configurations. They solve overlapping but different problems, and many teams use both.

AspectHelmKustomize
ApproachTemplating + packagingOverlay patching (template-free)
LanguageGo templates + SprigPlain YAML + kustomization.yaml
PackagingCharts (.tgz) with reposDirectories (no packaging)
Release managementBuilt-in (history, rollback)None (relies on kubectl / GitOps)
Conditionals / loopsFull (if/else, range, with)None
kubectl nativeNo (separate binary)Yes (kubectl apply -k)
Best forCommunity charts, complex apps, multi-envSimple overlays, in-house apps
# ── Kustomize example for comparison ──────────────────────────
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml

# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5
images:
  - name: my-app
    newTag: v2.5.0

# Apply with kubectl
kubectl apply -k overlays/production/

# ── Using both together ──────────────────────────────────────
# Render Helm templates, then apply Kustomize patches
helm template my-app ./my-chart -f values.yaml > rendered.yaml
# Add rendered.yaml to Kustomize base, then overlay

Frequently Asked Questions

What is Helm and why do I need it?

Helm bundles Kubernetes manifests into reusable Charts. Use it for complex multi-resource deployments, per-environment configuration, and installing community software from Artifact Hub.

Chart vs Release?

A Chart is a package (templates + values). A Release is a running instance in your cluster. The same Chart can be installed multiple times with different names and configurations.

How do I install Helm?

macOS: brew install helm. Linux: official install script or snap install helm --classic. Windows: choco install kubernetes-helm. Verify with helm version.

How does the template language work?

Go template syntax with Sprig functions. Access .Values, .Release, .Chart, and .Capabilities objects. Supports conditionals, loops, pipelines, and named templates in _helpers.tpl.

How do I override values?

Precedence: chart defaults < parent chart < -f files (left to right) < --set flags. Use helm show values to discover available parameters.

What are Helm hooks?

Resources annotated with helm.sh/hook that run at lifecycle points (pre-install, pre-upgrade, post-upgrade, test, etc.). Used for DB migrations, backups, and smoke tests.

What is Helmfile?

A declarative tool for managing multiple Helm releases in one helmfile.yaml with environment support, dependencies, and synchronized apply/destroy.

Helm or Kustomize?

Helm for reusable packages, community charts, and release lifecycle. Kustomize for overlay patching and kubectl-native workflows. Many teams use both together.

Conclusion

Helm is an essential tool in the Kubernetes ecosystem. It transforms the complexity of managing dozens of YAML manifests into reusable, versioned, configurable packages. Whether you are deploying a simple web application or orchestrating a complex microservices architecture with databases, caches, and ingress controllers, Helm provides the packaging, release management, and ecosystem that make Kubernetes deployments repeatable and reliable.

Start with helm create to scaffold your first chart, learn the template language incrementally, and adopt best practices like version pinning, helm lint, and --atomic upgrades. As your infrastructure grows, add Helmfile for multi-release management, chart repositories for team sharing, and chart signing for security. The investment in learning Helm pays dividends across every Kubernetes project you touch.

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter📋YAML Formatter

相关文章

Grafana 完全指南:DevOps 仪表盘与可观测性

掌握 Grafana 数据源、仪表盘、面板类型、变量、告警、配置即代码、Loki、Tempo 与 RBAC。

Kubernetes开发者完整指南:Pod、Helm、RBAC和CI/CD

掌握Kubernetes的开发者指南。含Pod、Deployment、Service、Ingress、Helm、PVC、健康检查、HPA、RBAC和GitHub Actions CI/CD集成。

Ansible 完全指南:简化基础设施自动化

掌握 Ansible 清单、Playbook、模块、角色、Galaxy、Vault、Jinja2 模板与动态清单。