部署一个 Redis 要写 5 个 YAML 文件?升级时要逐个改镜像版本?Helm 把一组 K8s 资源打包成 Chart,一条命令安装、升级、回滚,还能自定义配置。
想在 K3s 上部署 Redis。网上找到一份 YAML,改了镜像、改了存储、改了密码,5 个文件,200 行。下周想加个哨兵模式,又翻了一遍文档。为什么装个软件不能像 apt install 一样简单?
K8s 生态的服务动辄包含 Deployment、Service、ConfigMap、Secret、PVC、ServiceAccount、RoleBinding……手动管理这些 YAML 简直是噩梦。Helm 就是来解这个问题的。
Helm 是什么
一句话:K8s 的 apt/yum。
传统方式:
找 YAML → 手动改配置 → kubectl apply → 升级时手动改版本 → 再 apply
Helm 方式:
helm install redis bitnami/redis -f values.yaml
helm upgrade redis bitnami/redis -f values.yaml
helm rollback redis
核心概念:
| 概念 |
类比 |
说明 |
| Chart |
.deb 包 |
一组 K8s YAML 的打包+模板 |
| Release |
已安装的实例 |
同一个 Chart 可以装多份 |
| Repository |
apt 源 |
Chart 仓库(Bitnami、官方等) |
| Values |
配置文件 |
覆盖 Chart 默认参数 |
安装 Helm
# Ubuntu/Debian
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt update && sudo apt install helm
# macOS
brew install helm
# 验证
helm version
使用 Chart 仓库
# 添加 Bitnami 仓库(最常用的社区 Chart 源)
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新仓库索引
helm repo update
# 搜索 Redis
helm search repo redis
输出:
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/redis 19.6.0 7.4.0 Redis(TM) is an open source...
bitnami/redis-cluster 10.0.0 7.4.0 Redis Cluster...
安装第一个 Chart
先创建命名空间,再安装 Redis:
# 创建命名空间
kubectl create namespace redis
# 安装 Redis
helm install redis bitnami/redis \
-n redis \
--set auth.password=mypassword \
--set architecture=standalone \
--set persistence.size=8Gi
就这么简单,一条命令下来,Redis 的 Deployment、Service、PVC、Secret、ConfigMap 全部创建完毕。
常用命令:
# 查看已安装的 Release
helm list -n redis
# 查看 Release 状态
helm status redis -n redis
# 查看 Redis 生成的所有 K8s 资源
helm get manifest redis -n redis
Values 配置:自定义部署
如果只是临时改一两个参数,--set 够用了;一旦配置复杂起来,还是得靠 values.yaml 文件:
# values.yaml
architecture: replication
auth:
password: "MyStr0ngP@ss"
existingSecret: ""
master:
persistence:
size: 10Gi
storageClass: nfs-client
resources:
requests:
cpu: 100m
memory: 256Mi
replica:
replicaCount: 2
persistence:
size: 10Gi
storageClass: nfs-client
安装时指定:
helm install redis bitnami/redis -n redis -f values.yaml
想查看 Chart 支持哪些可配置参数:
# 查看所有默认值
helm show values bitnami/redis
# 导出默认 values 到文件
helm show values bitnami/redis > redis-defaults.yaml
升级与回滚
# 升级 Chart 版本
helm repo update
helm upgrade redis bitnami/redis -n redis -f values.yaml
# 查看历史版本
helm history redis -n redis
# 回滚到上一个版本
helm rollback redis -n redis
# 回滚到指定版本
helm rollback redis 3 -n redis
Helm 会保留每次部署的历史记录,所以升级与回滚都能秒级完成,比手动 kubectl apply 旧 YAML 快得多。
Chart 结构:写你自己的 Chart
第三方 Chart 不够用?自己写一个也不难。用 Helm 创建脚手架:
helm create my-app
生成的结构:
my-app/
├── Chart.yaml # Chart 元信息
├── values.yaml # 默认配置
├── templates/ # K8s YAML 模板
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # 公共模板函数
│ └── tests/
│ └── test-connection.yaml
├── charts/ # 依赖的子 Chart
└── .helmignore
核心是 templates/ 下的 Jinja2 模板。看 deployment.yaml 的关键部分:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}
模板语法要点:
{{ .Values.xxx }} 从 values.yaml 读配置
{{ .Chart.Name }} 从 Chart.yaml 读元信息
{{ include "xxx" . }} 调用 _helpers.tpl 里的模板函数
{{- if xxx }} 条件渲染
实战:打包自己的 HomeLab 应用
以部署 Halo 博客为例,创建一个自定义 Chart。
首先是 Chart 元信息:
# Chart.yaml
apiVersion: v2
name: halo-blog
description: Halo 博客系统 HomeLab 部署
type: application
version: 1.0.0
appVersion: "2.20.0"
默认配置:
# values.yaml
image:
repository: registry.local:5000/halo
tag: "2.20.0"
pullPolicy: IfNotPresent
replicaCount: 1
service:
type: ClusterIP
port: 8090
ingress:
enabled: true
className: traefik
host: blog.homelab.local
persistence:
enabled: true
size: 5Gi
storageClass: nfs-client
halo:
externalUrl: "https://blog.homelab.local"
database: postgresql
Deployment 模板:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: halo
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 8090
env:
- name: HALO_EXTERNAL_URL
value: {{ .Values.halo.externalUrl | quote }}
volumeMounts:
- name: data
mountPath: /root/.halo2
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ .Release.Name }}-pvc
打包并安装:
# 打包 Chart
helm package ./halo-blog
# 安装
helm install halo ./halo-blog-1.0.0.tgz -n blog -f halo-values.yaml
配合 ArgoCD 使用
Helm + ArgoCD 是黄金组合。ArgoCD 原生支持 Helm Chart:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: redis
namespace: argocd
spec:
source:
repoURL: https://charts.bitnami.com/bitnami
chart: redis
targetRevision: 19.6.0
helm:
values: |
architecture: replication
auth:
password: "MyStr0ngP@ss"
master:
persistence:
size: 10Gi
destination:
server: https://kubernetes.default.svc
namespace: redis
syncPolicy:
automated:
prune: true
selfHeal: true
Git 里存一份 Helm Chart 引用 + values,ArgoCD 负责同步。升级版本只需要改 targetRevision 然后 push。
小结
| 操作 |
手动 YAML |
Helm |
| 安装 |
找 5 个 YAML,改配置,kubectl apply |
helm install |
| 配置 |
逐个文件改 |
改一个 values.yaml |
| 升级 |
手动改镜像版本,再 apply |
helm upgrade |
| 回滚 |
翻 Git 历史找旧版本 |
helm rollback |
| 卸载 |
逐个 kubectl delete |
helm uninstall |
Helm 解决的是“一组 K8s 资源的打包和生命周期管理”。如果你想更系统地学习 Kubernetes 云原生技术栈,欢迎到 云栈社区 和开发者们一起交流实战经验。下一篇,我们接着聊 GitLab CI/CD,打通从代码提交到部署的完整流水线。