K8s 系列 | 第 25 天:Helm Charts:包管理器使用与 Chart 开发实战


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.mdLICENSE 等可选文件

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 天系列持续更新中,欢迎收藏关注!🎯

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容