IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在前面的文章中,我们手动编写了大量的 YAML 文件------Deployment、Service、ConfigMap、Secret、Ingress、PVC。每部署一个应用,就要创建好几个文件,手动 kubectl apply -f。如果是部署一套微服务,动辄几十上百个 YAML 文件,管理的复杂度直线上升。
更麻烦的是,当我们需要部署同一个应用的不同版本或不同环境(开发、测试、生产)时,往往需要复制粘贴 YAML 然后手动修改其中某些值(比如镜像标签、副本数、资源限制)。这种做法效率低、易出错。
Kubernetes 社区为了解决这个"应用包管理"的问题,推出了 Helm。它常被称为"Kubernetes 的 apt/yum",因为它的核心功能正是:将一堆 K8s YAML 文件模板化、打包、版本化 ,实现一键部署/升级/回滚。这也是我们这一篇要深入探讨的内容。
今天这篇,我们就来认识 Helm,安装它,用它来一键部署我们熟悉的 WordPress,并把贯穿系列的 Flask + Redis 应用也搬上 Helm。
一、Helm 解决什么痛点?
回顾一下我们在前面的文章(如第 10 篇)中部署 Flask + Redis 应用时涉及到的 K8s 对象:
-
Flask Deployment(含探针、资源限制、ServiceAccount)
-
Flask Service(ClusterIP)
-
Redis Deployment(含 PVC)
-
Redis Service(ClusterIP)
-
ConfigMap(应用配置)
-
Secret(敏感信息)
-
Ingress(外部入口,含 TLS)
-
PersistentVolumeClaim(动态存储)
在裸 K8s 中,需要创建 8 个 YAML 文件(或写在一个文件里用 --- 分隔),然后 kubectl apply -f 挨个部署。
更麻烦的是,给生产环境部署时,可能需要修改:
-
镜像标签(2.0 → 3.0)
-
副本数(1 → 3)
-
域名(
counter.example.com→counter.prod.internal) -
TLS 证书名
如果用原始 YAML,只能手动修改或者借助 sed 脚本。而 Helm 提供了一套模板机制和值注入,让同一套模板能适配不同环境,同时记录每次部署的版本历史,方便回滚。
二、Helm 核心概念
在动手之前,先理清 Helm 的三个核心概念:
简单来说:
-
Chart 是"配方"------定义了这个应用需要哪些资源(Deployment、Service 等)。
-
Release 是"一道菜"------用 Chart 模板 + 特定环境的值(values.yaml)渲染出的具体实例。
-
Repository 是"食谱仓库"------存放了很多 Chart 可供搜索和下载。
当你运行 helm install my-release ./my-chart 时,Helm 把模板渲染成实际的 YAML,提交给 K8s API,并记录这个 Release 的版本。
三、安装 Helm
3.1 各平台安装
macOS:
Windows(推荐 winget):
Linux:
bash
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
3.2 验证安装
bash
helm version
# version.BuildInfo{Version:"v3.16.0", GitCommit:"...", GitTreeState:"clean", GoVersion:"go1.22.5"}
Helm v3 是当前主推版本(2019 年发布),不需要在集群中安装 Tiller(v2 时代的服务端组件),所有操作通过 kubectl 上下文直接与 API Server 交互,更安全、更轻量。
四、使用官方 Chart 一键部署 WordPress
在动手写自己的 Chart 之前,先用官方仓库的 WordPress Chart 感受一下 Helm 的威力。
4.1 添加官方仓库并拉取 Chart
bash
# 添加 Bitnami 仓库(维护了大量高质量 Chart)
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新本地仓库索引
helm repo update
# 搜索 WordPress
helm search repo wordpress
# NAME CHART VERSION APP VERSION DESCRIPTION
# bitnami/wordpress 23.1.0 6.6.2 WordPress is the world's most popular...
4.2 安装 WordPress
bash
helm install my-wp bitnami/wordpress \
--set wordpressUsername=admin \
--set wordpressPassword=Admin123! \
--set service.type=NodePort
输出:
bash
NAME: my-wp
LAST DEPLOYED: Mon May 27 10:00:00 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the WordPress URL:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services my-wp-wordpress)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo "WordPress URL: http://$NODE_IP:$NODE_PORT/"
一条命令,Helm 帮我们完成了:部署 MariaDB(WordPress Chart 的默认依赖)、部署 WordPress、创建对应的 Service、ConfigMap、Secret、PVC。整个过程不超过 30 秒。
4.3 查看 Release
bash
helm list
# NAME NAMESPACE REVISION UPDATED STATUS CHART
# my-wp default 1 Mon May 27 10:00:00 deployed wordpress-23.1.0
REVISION=1 表示这是第 1 次部署。每次 helm upgrade 都会增加版本号,方便后续回滚。
4.4 自定义参数
上面的 --set 可以在命令行覆盖默认值。更推荐的做法是创建自定义 values.yaml:
bash
# custom-values.yaml
wordpressUsername: admin
wordpressPassword: Admin123!
service:
type: NodePort
persistence:
enabled: true
size: 5Gi
bash
helm upgrade my-wp bitnami/wordpress -f custom-values.yaml
4.5 卸载
bash
helm uninstall my-wp
# release "my-wp" uninstalled
五、使用 Helm 部署贯穿案例:Flask + Redis
现在我们尝试用 Helm 来管理贯穿系列的 Flask + Redis 应用。
5.1 生成 Chart 骨架
bash
helm create flask-redis-chart
查看生成的目录结构:
bash
flask-redis-chart/
├── charts/ # 存放子 Chart(依赖)
├── templates/ # K8s YAML 模板文件
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── serviceaccount.yaml
│ ├── NOTES.txt # helm install 后显示的帮助信息
│ └── _helpers.tpl # 模板辅助函数(宏)
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
└── .helmignore
helm create生成的是一个 Nginx 示例。我们需要把它改造成 Flask + Redis 应用。
5.2 修改 Chart.yaml
bash
apiVersion: v2
name: flask-redis-chart
description: A Helm chart for Flask + Redis Counter App
type: application
version: 0.1.0
appVersion: "3.0"
-
version是 Chart 自身的版本号。 -
appVersion是应用(镜像)的版本号。两者独立,方便 Chart 模板变更和应用镜像变更分开管理。
5.3 修改 values.yaml
bash
# 镜像配置
image:
repository: flask-redis-counter
tag: "3.0"
pullPolicy: IfNotPresent
# Flask 副本数
replicaCount: 3
# 服务配置
service:
type: ClusterIP
port: 5000
# Ingress 配置
ingress:
enabled: true
className: nginx
hosts:
- host: counter.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: counter-tls
hosts:
- counter.example.com
# 环境变量(ConfigMap)
config:
FLASK_ENV: production
LOG_LEVEL: info
REDIS_HOST: redis-service
REDIS_PORT: "6379"
# Redis 配置
redis:
enabled: true
image:
repository: redis
tag: alpine
persistence:
enabled: true
size: 1Gi
storageClass: standard
service:
name: redis-service
port: 6379
5.4 编写模板文件
基于 templates/ 下的模板,引入 values 值。例如 deployment.yaml 核心片段:
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "flask-redis-chart.fullname" . }}
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: flask
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
env:
- name: FLASK_ENV
value: {{ .Values.config.FLASK_ENV | quote }}
- name: LOG_LEVEL
value: {{ .Values.config.LOG_LEVEL | quote }}
模板中的 {``{ .Values.xxx }} 是 Helm 的占位符语法。Helm 安装或升级时,会从 values.yaml(以及 --set 传入的值)中读取对应值并替换。
5.5 安装验证
bash
# 进入 Chart 目录
cd flask-redis-chart
# 检查模板渲染结果(不实际部署)
helm install flask-counter . --dry-run --debug
# 正式部署
helm install flask-counter .
# 查看状态
helm list
kubectl get all -l app.kubernetes.io/instance=flask-counter
现在,Flask + Redis 这个贯穿案例就变成了一个 Helm Release,可以使用 helm upgrade、helm rollback 来管理。
5.6 升级与回滚
修改 values.yaml 或通过 --set 更新配置并升级:
bash
helm upgrade flask-counter . --set replicaCount=5
查看历史版本:
bash
helm history flask-counter
# REVISION UPDATED STATUS CHART
# 1 Mon May 27 10:00:00 superseded flask-redis-chart-0.1.0
# 2 Mon May 27 10:05:00 deployed flask-redis-chart-0.1.0
回滚到上一版本:
bash
helm rollback flask-counter 1
六、常用 Helm 命令速查
七、本篇总结
-
Helm 的价值:将一组 K8s 资源打包为一个 Chart,实现模板化、参数化、版本化。一个 Chart 可以对应多个环境的值文件,消除复制粘贴和手动替换。
-
三大核心概念:Chart(应用包模板)、Release(一次部署实例)、Repository(Chart 仓库)。
-
两个实战:使用官方 WordPress Chart 体验一键部署完整应用栈;生成 Chart 骨架并将贯穿案例的 Flask + Redis 应用转换为 Helm Chart。
-
与裸 YAML 的对比 :裸 YAML 是静态的,Helm 通过
values.yaml+--set实现动态注入,每次 Release 都有版本记录可追溯和回滚。
本篇通过 Helm,应用部署从"文件堆砌"变成了"软件包管理"。虽然我们使用 helm create 生成了初始模板,但如果想真正掌握自定义 Chart 的编写技巧,还需要深入了解模板语法、流程控制以及 Chart 的发布与共享。下一篇------第 40 篇:编写自定义 Helm Chart------我们将学习从零构建一个 Chart,掌握模板语法,并把它发布到仓库中。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维!