第 10 章:K8s Helm:从手动部署到企业级包管理
上一章讲了 HPA。本章讲 Helm。它把 K8s 应用打包成 Chart,解决手动部署、配置管理、版本回退的问题。
10.1 为什么需要 Helm
手动管理 K8s 应用时,经常遇到这些问题:
- 一个应用由十几个 YAML 文件组成,部署时容易漏掉
- 不同环境(开发、测试、生产)要改一堆配置
- 版本升级和回滚没有统一管理
- 团队内部想复用已有的部署模板
Helm 就是 K8s 世界的包管理器,类似 Linux 的 apt/yum、macOS 的 Homebrew。
Helm 把一个应用的所有 K8s 资源打包成一个 Chart,可以一键安装、升级、回滚、卸载。
helm install myapp ./mychart
helm upgrade myapp ./mychart
helm rollback myapp 1
helm uninstall myapp
10.2 Chart 目录结构
Helm 把一个应用的所有 K8s 资源打包成一个 Chart:
mychart/
Chart.yaml # Chart 元数据
values.yaml # 默认配置值
values-dev.yaml # 开发环境覆盖值(可选)
templates/ # YAML 模板
_helpers.tpl # 辅助模板函数
deployment.yaml
service.yaml
ingress.yaml
hpa.yaml
charts/ # 依赖的 Chart(可选)
README.md
10.2.1 Chart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for my application
type: application
version: 1.0.0
appVersion: "v1.2.3"
| 字段 | 含义 |
|---|---|
version | Chart 本身的版本 |
appVersion | 应用的版本 |
type | application 或 library |
10.2.2 values.yaml
定义可配置项的默认值:
replicaCount: 2
image:
repository: nginx
tag: "1.27"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
host: app.example.com
resources:
requests:
cpu: 100m
memory: 128Mi
10.2.3 templates/
模板文件使用 Go template 语法。例如 deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ include "myapp.name" . }}
template:
metadata:
labels:
app: {{ include "myapp.name" . }}
spec:
containers:
- name: {{ include "myapp.name" . }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{ .Values.xxx }} 读取 values.yaml 中的值。{{ include }} 调用 _helpers.tpl 中定义的函数。
10.3 安装、升级、回滚、卸载
10.3.1 安装
# 安装本地 Chart
$ helm install myapp ./mychart
# 从仓库安装
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install mynginx bitnami/nginx
10.3.2 查看已安装应用
$ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART
myapp default 1 2024-05-01 10:00:00 deployed myapp-1.0.0
10.3.3 升级
$ helm upgrade myapp ./mychart
每次升级都会生成一个新的 revision。
10.3.4 回滚
# 查看历史
$ helm history myapp
REVISION UPDATED STATUS
1 2024-05-01 10:00:00 deployed
2 2024-05-01 11:00:00 failed
# 回滚到版本 1
$ helm rollback myapp 1
10.3.5 卸载
$ helm uninstall myapp
Helm 会删除所有通过它创建的资源。
10.4 用 --set 和 -f 覆盖配置
10.4.1 --set 命令行覆盖
$ helm install myapp ./mychart \
--set replicaCount=5 \
--set image.tag=1.28
适合临时修改少量参数。
10.4.2 -f 指定 values 文件
# 开发环境
$ helm install myapp ./mychart -f values-dev.yaml
# 生产环境
$ helm install myapp ./mychart -f values-prod.yaml
values-prod.yaml 示例:
replicaCount: 5
image:
tag: "1.27"
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
ingress:
enabled: true
host: app.example.com
这样同一个 Chart 可以服务多个环境,不需要复制模板。
10.5 实战:通过 Helm 安装 Nginx
先添加仓库并搜索:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
$ helm search repo nginx
NAME CHART VERSION APP VERSION
bitnami/nginx 15.0.0 1.27.0
安装:
$ helm install mynginx bitnami/nginx \
--set service.type=NodePort \
--set service.nodePorts.http=30080
查看:
$ helm list
$ kubectl get pod,svc
在浏览器或 curl 访问:
$ curl http://192.168.0.201:30080
升级版本:
$ helm upgrade mynginx bitnami/nginx --set image.tag=1.28
回滚:
$ helm rollback mynginx 1
10.6 打包自己的应用为 Chart
下面从零创建一个最简单的 Chart:
$ helm create myapp
Helm 会生成一个模板工程。我们修改 values.yaml:
replicaCount: 2
image:
repository: nginx
tag: "1.27"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
requests:
cpu: 100m
memory: 128Mi
安装测试:
$ helm install myapp ./myapp
$ kubectl get pod,svc
NAME READY STATUS
pod/myapp-xxx 1/1 Running
NAME TYPE CLUSTER-IP
service/myapp ClusterIP 10.96.12.34
打包为 tgz 文件:
$ helm package ./myapp
Successfully packaged chart and saved it to: myapp-1.0.0.tgz
这个文件可以上传到 Helm 仓库或私有的 Chart Museum。
10.7 最佳实践
| 建议 | 原因 |
|---|---|
不要用 latest 标签 | 升级时 Helm 可能认为镜像没变,不触发滚动更新 |
| 使用语义化版本 | 版本号清晰,方便回滚 |
| 用 values 文件管理环境差异 | 不复制模板,减少维护成本 |
配置 resources | 避免 Pod 占用过多资源 |
使用 helm lint 和 helm template | 安装前检查模板语法 |
| 敏感信息用 Secret | 不要把密码写进 values.yaml 明文提交 |
10.8 helm lint 和 helm template
安装前可以先本地检查:
# 检查 Chart 语法
$ helm lint ./myapp
# 渲染模板但不安装
$ helm template myapp ./myapp
helm template 是排查模板问题的好工具。它会把 values 注入模板,输出最终 YAML,方便检查字段是否正确。
10.9 本章小结
- Helm 是 K8s 的包管理器,管理应用安装、升级、回滚
- Chart 由 Chart.yaml、values.yaml、templates/ 组成
- 用
--set和-f可以灵活覆盖配置 - 同一个 Chart 配合不同 values 文件服务多环境
- 不要写
latest标签,要用语义化版本 helm lint和helm template是本地检查利器
10.10 课后练习
- 用
helm create创建一个自己的 Chart,安装并查看生成的资源。 - 用
--set把副本数改成 5,验证 Deployment 是否同步更新。 - 为同一个 Chart 创建
values-dev.yaml和values-prod.yaml,分别安装到不同命名空间。 - 升级 Chart 版本后执行回滚,观察
helm history的变化。