title: K8s 系列 | 第 25 天:Helm Charts:包管理器使用与 Chart 开发实战
tags:
– Kubernetes
– K8s系列
– DevOps
– Helm
– Charts
– 包管理
第 25/30 天
引言
在 Kubernetes 生态中,随着微服务架构的普及,一个典型的应用往往由 Deployment、Service、ConfigMap、Ingress 等多个资源对象组成。手动逐个编写和管理这些 YAML 清单不仅效率低下,而且难以复用和版本控制。当需要部署同一应用的不同环境(开发、测试、生产)时,参数化配置的需求更是让纯 YAML 管理的维护成本直线上升。
Helm 正是为解决这些问题而生的 Kubernetes 包管理器。它将 K8s 资源打包为可复用的 Chart,支持参数化模板化部署、版本化管理、依赖管理和一键安装/升级/回滚。无论是开源项目(如 Prometheus、Nginx Ingress、Cert-Manager)还是企业内部应用,Helm 已经成为 K8s 应用交付的事实标准。
本文将深入讲解 Helm 的核心概念、基本命令操作、Chart 开发实战以及生产环境中的最佳实践。
一、Helm 核心概念
Helm 引入了三个核心概念来管理 K8s 应用的生命周期:
1. Chart
Chart 是 Helm 的打包格式,它是一个包含了部署 K8s 应用所需的所有资源定义的目录结构。一个 Chart 包含:
– Chart.yaml:Chart 的元数据(名称、版本、描述等)
– values.yaml:默认配置值
– templates/:Go 模板渲染的 K8s 资源清单
– charts/:子 Chart 依赖
– README.md、LICENSE 等可选文件
2. Repository(仓库)
Chart 仓库是存放和分发 Chart 包的 HTTP 服务器。著名的公共仓库包括:
– Artifact Hub(artifacthub.io):官方推荐的 Chart 中心仓库
– Bitnami 仓库:提供大量生产级 Chart
3. Release(发布)
当 Chart 部署到 K8s 集群时,会创建一个 Release。同一 Chart 可以多次部署到同一集群,每次部署都生成一个独立的 Release。例如,用同一个 Nginx Chart 部署三个独立的 Nginx 实例,会得到三个不同的 Release。
二、Helm 安装与基础操作
安装 Helm
# Linux 下安装 Helm v3
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 验证安装
helm version
# 输出示例:version.BuildInfo{Version: "v3.16.0", ...}
添加 Chart 仓库
# 添加 Bitnami 官方仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
# 添加稳定版仓库
helm repo add stable https://charts.helm.sh/stable
# 更新本地仓库索引
helm repo update
# 查看已添加的仓库
helm repo list
搜索 Chart
# 在已添加的仓库中搜索
helm search repo nginx
# 在 Artifact Hub 上搜索
helm search hub nginx-ingress
安装 Chart
# 安装一个 Nginx Release
helm install my-nginx bitnami/nginx
# 使用自定义 values 文件安装
helm install my-nginx bitnami/nginx -f custom-values.yaml
# 通过 --set 覆盖特定参数
helm install my-nginx bitnami/nginx
--set service.type=NodePort
--set replicas=3
# 指定命名空间安装
helm install my-nginx bitnami/nginx
--namespace my-namespace
--create-namespace
管理 Release
# 查看已部署的 Release
helm list
# 查看 Release 状态详情
helm status my-nginx
# 升级 Release
helm upgrade my-nginx bitnami/nginx
--set replicas=5
# 查看版本历史
helm history my-nginx
# 回滚到上一个版本
helm rollback my-nginx 1
# 卸载 Release
helm uninstall my-nginx
三、Chart 目录结构详解
现在我们来开发一个完整的 Chart。使用 helm create 命令可以快速生成骨架:
helm create myapp
生成的目录结构如下:
myapp/
├── .helmignore # 打包时排除的文件列表
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── charts/ # 子 Chart 依赖(手动或通过 helm dependency 管理)
├── templates/ # Go 模板文件
│ ├── NOTES.txt # 安装后的使用说明
│ ├── _helpers.tpl # 模板辅助函数
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── hpa.yaml
│ ├── serviceaccount.yaml
│ └── tests/
│ └── test-connection.yaml
Chart.yaml 示例
apiVersion: v2
name: myapp
description: 一个示例 Helm Chart
type: application
version: 0.1.0
appVersion: "1.16.0"
keywords:
- web
- demo
maintainers:
- name: developer
email: dev@example.com
dependencies:
- name: redis
version: ">=17.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
四、Chart 模板开发实战
Helm 使用 Go 模板引擎(text/template)配合 Sprig 函数库来渲染 K8s 资源。下面通过一个实战示例来掌握模板开发的精髓。
values.yaml:定义可配置参数
# 镜像配置
image:
repository: nginx
tag: latest
pullPolicy: IfNotPresent
# 副本数
replicaCount: 2
# 服务配置
service:
type: ClusterIP
port: 80
targetPort: 8080
# 资源限制
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 200m
memory: 256Mi
# 环境变量
env:
- name: APP_ENV
value: production
- name: LOG_LEVEL
value: info
# Ingress 配置
ingress:
enabled: true
host: myapp.example.com
annotations:
kubernetes.io/ingress.class: nginx
# 持久化存储
persistence:
enabled: true
size: 10Gi
storageClass: ""
templates/deployment.yaml:核心模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "myapp.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.targetPort }}
name: http
env:
{{- toYaml .Values.env | nindent 12 }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.persistence.enabled }}
volumeMounts:
- name: data
mountPath: /data
subPath: {{ .Release.Name }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.persistence.enabled }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ include "myapp.fullname" . }}
{{- end }}
_helpers.tpl:模板辅助函数
{{- define "myapp.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "myapp.labels" -}}
helm.sh/chart: {{ include "myapp.fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "myapp.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
五、Chart 的安装、升级与回滚
开发完 Chart 后,我们来实地操作一遍完整的生命周期管理。
本地调试 Chart
# 在本地模拟渲染,不实际部署
helm template myapp ./myapp
# 检查 Chart 语法正确性
helm lint ./myapp
# 模拟安装(dry run),查看将要部署的资源
helm install myapp ./myapp --dry-run --debug
安装并升级
# 正式安装
helm install myapp ./myapp
# 修改 values.yaml 后升级
helm upgrade myapp ./myapp
--set replicaCount=5
--set service.type=LoadBalancer
# 如果升级失败,自动回滚
helm upgrade myapp ./myapp
--atomic
--timeout 5m
# 查看 Release 历史
helm history myapp
# REVISION UPDATED STATUS CHART APP VERSION
# 1 Sat Jul 11 08:00:00 2026 deployed myapp-0.1.0 1.16.0
# 2 Sat Jul 11 08:05:00 2026 deployed myapp-0.2.0 1.17.0
版本回滚
# 回滚到版本 1
helm rollback myapp 1
# 回滚并等待就绪
helm rollback myapp 1 --wait --timeout 10m
六、依赖管理
实际项目中,一个应用通常依赖数据库、缓存等中间件。Helm 的依赖管理让这变得非常简单。
声明依赖
在 Chart.yaml 中声明子 Chart 依赖:
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
管理依赖
# 下载依赖到 charts/ 目录
helm dependency update ./myapp
# 查看依赖树
helm dependency list ./myapp
# NAME VERSION REPOSITORY STATUS
# postgresql 12.x.x https://charts.bitnami.com/bitnami ok
# redis 17.x.x https://charts.bitnami.com/bitnami ok
然后在 values.yaml 中可以通过 postgresql.enabled: true/false 控制是否启用子 Chart。
七、生产环境最佳实践
1. 版本管理策略
- Chart 版本使用 SemVer(语义化版本),
version字段代表 Chart 本身的版本,appVersion代表打包的应用版本 - 每次修改资源模板或 values 后,记得升级 Chart 版本号
- 使用
helm package打包为.tgz归档并上传到私有 Chart 仓库
2. values 分层管理
# 使用多层级 values 文件覆盖
helm install myapp ./myapp
-f values.yaml # 默认值
-f values-staging.yaml # 环境覆盖
--set image.tag=v1.2.3 # 最终覆盖
3. 安全合规
- 避免在 values.yaml 中硬编码敏感信息,配合
--set从 CI/CD 注入 - 使用
helm secrets插件加密敏感 values - 生产环境禁用
latest标签,始终使用明确的版本号
4. Chart 测试
# 运行 Chart 内置测试(在 templates/tests/ 中定义)
helm test myapp
5. 私有 Chart 仓库搭建
# 使用 Harbor 作为私有仓库(推荐)
# 或使用 ChartMuseum
helm repo add myrepo https://charts.mycompany.com
# 推送 Chart 到私有仓库
helm push myapp-0.1.0.tgz myrepo
常见问题
Q1:Helm v2 和 v3 有什么区别?
Helm v3 移除了 Tiller(服务端组件),客户端直接通过 K8s API 通信,安全性大幅提升。不建议再使用 v2。
Q2:如何排查模板渲染错误?
使用 helm template --debug 查看渲染后的完整 YAML,配合 helm lint 进行语法检查。
Q3:Release 名称长度限制?
Release 名称不能超过 53 个字符(K8s 资源名称长度限制),建议使用简短的命名。
Q4:如何查看 Chart 支持的配置项?
helm show values bitnami/nginx 可以查看 Chart 的默认 values,快速了解所有可配置参数。
总结
本文系统性地介绍了 Helm 的核心概念、基础操作、Chart 开发实战以及生产环境最佳实践。Helm 作为 Kubernetes 生态中最重要的工具之一,通过模板化、参数化和版本化管理,将 K8s 应用的部署从手工劳动提升到了工程化、自动化的高度。掌握 Helm 是每一位 K8s 运维和开发人员的必备技能。
下期预告
第 26 天:集群备份与恢复:etcd 快照 + Velero 方案
Kubernetes 集群的数据安全至关重要。明天我们将深入探讨 etcd 快照备份与恢复机制、Velero 集群级备份方案,以及灾后恢复的完整操作流程,确保你的生产集群在灾难面前稳如磐石。
📚 K8s 系列目录导航
– 第 1 天:Kubernetes 是什么?核心概念与架构全景解析
– 第 2 天:手把手搭建你的第一个 K8s 集群
– …
– 第 24 天:RBAC 权限控制
– 第 25 天:Helm Charts(当前)
– 第 26 天:集群备份与恢复(预告)
完整 30 天系列持续更新中,欢迎收藏关注!🎯















暂无评论内容