Helm Chart 包管理

2026-06-22 · 6 阅读 · 782字
CI/CDKubernetes

Helm Chart 包管理

概述

Helm 是 Kubernetes 的包管理器,用于定义、安装和升级 Kubernetes 应用。Chart 是 Helm 的打包格式,包含描述一组相关 Kubernetes 资源的文件集合。

核心概念

概念 说明
Chart 应用的打包格式,包含模板和配置
Release Chart 的一次运行实例
Repository Chart 的存储和分发仓库
Values 模板的配置值,可覆盖默认值

安装与入门

# 安装 Helm 客户端
# macOS
brew install helm
# Ubuntu
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt install helm
# 二进制安装
curl -fsSL https://get.helm.sh/helm-v3.14.0-linux-amd64.tar.gz | tar xz
sudo mv linux-amd64/helm /usr/local/bin/

# 验证
helm version

常用命令

# 搜索 Chart
helm search hub nginx           # 在 Artifact Hub 中搜索
helm search repo nginx          # 在已添加的仓库中搜索

# 添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# 安装 Chart
helm install my-nginx bitnami/nginx
helm install my-nginx ./my-chart   # 本地 Chart

# 查看状态
helm list
helm status my-nginx
helm get values my-nginx

# 升级
helm upgrade my-nginx bitnami/nginx --set replicaCount=3

# 回滚
helm rollback my-nginx 1

# 卸载
helm uninstall my-nginx

Chart 结构

mychart/
├── Chart.yaml               # Chart 元信息
├── values.yaml              # 默认配置值
├── charts/                  # 子 Chart 依赖
├── templates/               # Kubernetes 模板文件
│   ├── NOTES.txt            # 安装后的提示信息
│   ├── _helpers.tpl         # 模板辅助函数
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   └── tests/
│       └── test-connection.yaml
└── .helmignore              # 排除文件

Chart.yaml

apiVersion: v2
name: myapp
description: 一个示例应用
version: 0.1.0
appVersion: "1.16.0"
type: application

dependencies:
  - name: postgresql
    version: ~12.5.0
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled

模板编写

基本模板语法

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "mychart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "mychart.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

_helpers.tpl 辅助函数

{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{- define "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.name" . }}-{{ .Chart.Version }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

Values 文件

# values.yaml
replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  className: nginx
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix
  tls: []

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

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10

值覆盖

多种覆盖方式

# 1. 命令行 --set
helm install myapp ./mychart --set image.tag=v2 --set replicaCount=3

# 2. 自定义 values 文件
helm install myapp ./mychart -f values-prod.yaml

# 3. 使用 --values 多次(后覆盖前)
helm install myapp ./mychart \
    -f values.yaml \
    -f values-production.yaml

# 4. 继承父 Chart 的 values

values-production.yaml

replicaCount: 5

image:
  tag: production

resources:
  requests:
    cpu: 500m
    memory: 1Gi
  limits:
    cpu: 2
    memory: 2Gi

ingress:
  enabled: true
  hosts:
    - host: prod.example.com

依赖管理

# 更新依赖
helm dependency update ./mychart

# 查看依赖树
helm dependency list ./mychart

# 构建依赖(将依赖打包到 charts/ 目录)
helm dependency build ./mychart

Chart 测试

# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "mychart.fullname" . }}-test-connection"
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['{{ include "mychart.fullname" . }}:{{ .Values.service.port }}']
  restartPolicy: Never
# 运行测试
helm test myapp

最佳实践

1. 命名规范

  • Chart 名称使用小写字母和连字符
  • 模板中所有资源名称使用辅助函数生成
  • 标签符合 Kubernetes 推荐标签规范

2. 配置设计

  • 提供合理的默认值
  • 敏感信息通过 values 传递并使用 --set 或 Secret
  • 条件启用可选功能(如 Ingress、自动伸缩)

3. 版本管理

  • 修改 Chart 时更新 version 字段
  • 应用版本变更时更新 appVersion
  • 维护 CHANGELOG

4. 打包与分发

# 打包 Chart
helm package ./mychart -d ./dist

# 签名(使用 GPG)
helm package --sign --key 'John' --keyring ~/.gnupg/secring.gpg ./mychart

# 推送仓库
helm push mychart-0.1.0.tgz oci://registry.example.com/charts

总结

Helm 通过模板化和参数化设计,大幅降低了 Kubernetes 应用部署和管理的复杂度。从编写简单的 Chart 开始,逐步掌握依赖管理、条件渲染和生命周期钩子等高级特性,可以有效提升 Kubernetes 应用交付的效率。