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 应用交付的效率。