第 39 篇 k8s之Helm 入门:包管理工具与 Chart

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.comcounter.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 upgradehelm 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 思维!

相关推荐
做个文艺程序员3 小时前
第07篇:K8s 安全加固指南:RBAC、NetworkPolicy、OPA——Java SaaS 多租户安全隔离深度实践
java·安全·kubernetes
衫水6 小时前
项目后端服务 Docker 部署SOP (2026-06-04)
运维·docker·容器
H_老邪6 小时前
Docker 学习之路-Linux安装指定版本docker
学习·docker·容器
IT策士7 小时前
第 40 篇 k8s之Helm:编写自定义 Helm Chart
云原生·容器·kubernetes
江华森7 小时前
Nacos 微服务注册与配置中心深度学习指南
微服务·云原生·架构
codeejun7 小时前
每日一Go-74、Go 云原生可观测性实战之OpenTelemetry 全链路采集:Trace + Metrics + Logs
开发语言·云原生·golang
木雷坞7 小时前
自托管 n8n:Docker Compose、Webhook 和升级备份排查
运维·容器
qq_452396237 小时前
第十八篇:《Docker 监控与性能优化》
docker·容器·性能优化
openFuyao8 小时前
AI Native基础设施的目标形态和它存在的一些挑战有哪些?K8s驱动异构算力面临挑战,下一代的K8s是渐进式优化,还是革命式的驱动AI的发展
人工智能·容器·kubernetes