云计算百科
云计算领域专业知识百科平台

【架构实战】Helm Chart 进阶:依赖管理、测试与 CI/CD 集成

一、开篇:从"单 Chart"到"应用栈"

上篇我们聊了 Helm 的基础概念、values.yaml 配置管理和 Release 回滚机制。但真实世界远比单个 Chart 复杂:

一个典型的微服务应用栈,可能包含:

  • 前端
  • 后端 API(Spring Boot)
  • 数据库
  • 缓存(Redis Cluster)
  • 消息队列
  • 监控

如果用 6 个独立 Chart 分别管理,启动顺序、配置依赖、环境隔离都是噩梦。这就是 Helm Chart 依赖管理要解决的核心问题。

今天这篇,我们深入 Helm 的进阶能力:依赖管理、子 Chart、测试框架、CI/CD 集成,以及我们团队在落地过程中总结的最佳实践。

二、Chart 依赖管理:从"手动编排"到"声明式依赖"

Helm 3 支持 Chart 依赖声明,类似 npm 的 package.json 或 Maven 的 pom.xml。

Chart.yaml 中声明依赖:

apiVersion: v2
name: myappstack
version: 1.0.0
dependencies:
name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
tags:
cache

name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
alias: db # 在模板中用 .Values.db 访问

name: myappbackend
version: "1.2.0"
repository: "file://charts/backend" # 本地 Chart

关键参数解释:

参数作用示例
condition 条件启用,可通过 values 控制是否安装 redis.enabled: false 跳过 Redis
tags 批量控制一组依赖 tags: [cache] 可统一开关
alias 重命名依赖,避免冲突 两个不同版本的 Redis 用不同别名

下载依赖并构建 charts/ 目录:

helm dependency update myapp-stack/
# 或简写
helm dep up myapp-stack/

执行后会在 charts/ 目录生成 .tgz 压缩包:

myapp-stack/
├── Chart.yaml
├── charts/
│ ├── redis-17.3.0.tgz
│ ├── postgresql-12.1.0.tgz
│ └── backend/
└── values.yaml

通过 values.yaml 控制依赖启用:

# 不安装 Redis,用外部托管服务
redis:
enabled: false

# 启用 PostgreSQL,覆盖默认配置
postgresql:
enabled: true
auth:
password: "prod-db-password-2026"
primary:
persistence:
size: 100Gi
storageClass: ssdgold

# 后端服务配置
backend:
image:
repository: myregistry/myappbackend
tag: "2.1.4"
env:
DATABASE_URL: "postgresql://db:5432/myapp"

三、子 Chart 的值传递:父 Chart 如何控制子 Chart

这是 Helm 依赖管理中最容易踩坑的地方:values 是如何从父 Chart 传递到子 Chart 的?

规则很简单但容易被忽略:

  • 父 Chart 的 values.yaml 中,以子 Chart 名称为 key 的部分,会传递给子 Chart
  • 子 Chart 只能看到自己命名空间下的值

示例:父 values.yaml

# 全局配置(所有子 Chart 可见)
global:
imageRegistry: myregistry.io
imagePullSecrets:
name: registrysecret

# 传递给 redis 子 Chart
redis:
auth:
password: "redis-prod-pass"
replica:
replicaCount: 3

# 传递给 postgresql 子 Chart(注意 alias)
db: # 用 alias 名,不是原名
auth:
password: "pg-prod-pass"

# 后端应用配置(非子 Chart,直接在本 Chart 模板使用)
backend:
image:
tag: "2.1.4"

子 Chart(redis)收到的 values:

# redis 子 Chart 的 values.yaml + 父 Chart 传入的覆盖
auth:
password: "redis-prod-pass"
replica:
replicaCount: 3

# global 是特殊字段,所有子 Chart 自动继承
global:
imageRegistry: myregistry.io
imagePullSecrets:
name: registrysecret

踩坑记录: 我们第一次用依赖管理时,把 redis.auth.password 写在 values.yaml 根级别,结果 Redis 一直用默认密码启动。排查半天才发现:必须放在 redis: 下面,Helm 才会把值传给子 Chart。

四、Chart 测试框架:安装后自动验证

Helm 内置了测试框架,可以在安装/升级后自动运行验证脚本,确保应用真正可用。

定义测试 Pod(templates/tests/):

# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test-connection"
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": hooksucceeded
spec:
containers:
name: wget
image: busybox
command: ['wget']
args: ['{{ .Release.Name }}:{{ .Values.service.port }}']
restartPolicy: Never

运行测试:

helm test my-release
# NAME: my-release
# LAST DEPLOYED: Mon Jul 27 15:00:00 2026
# NAMESPACE: default
# STATUS: deployed
# TEST SUITE: my-release-test-connection
# Last Started: Mon Jul 27 15:01:00 2026
# Last Completed: Mon Jul 27 15:01:05 2026
# Phase: Succeeded

我们团队的实践: 所有 Chart 必须包含至少一个测试用例,验证核心服务可访问性。CI/CD 流程中 helm upgrade 后自动跑 helm test,测试失败则自动回滚。

进阶测试:数据库连通性验证

# templates/tests/test-db-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test-db"
annotations:
"helm.sh/hook": test
spec:
containers:
name: pgtest
image: postgres:15
command: ['psql']
args:
'-c'
'SELECT 1'
env:
name: PGHOST
value: "{{ .Release.Name }}-db"
name: PGUSER
value: "postgres"
name: PGPASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-db-postgresql"
key: password
restartPolicy: Never

五、CI/CD 集成:从手动部署到自动化流水线

Helm 天然适合 CI/CD 集成。我们团队用 GitLab CI + Helm 实现了一套完整流程:

.gitlab-ci.yml 核心片段:

stages:
lint
test
package
deploy

# 阶段 1:语法检查
helm-lint:
stage: lint
image: alpine/helm:3.12.0
script:
helm lint charts/myapp/
rules:
if: $CI_PIPELINE_SOURCE == "merge_request_event"

# 阶段 2:模板渲染验证(dry-run)
helm-template:
stage: test
image: alpine/helm:3.12.0
script:
helm template myapp charts/myapp/ f values/dev.yaml > /dev/null
helm template myapp charts/myapp/ f values/prod.yaml > /dev/null
rules:
if: $CI_PIPELINE_SOURCE == "merge_request_event"

# 阶段 3:打包并推送到 Chart 仓库
helm-package:
stage: package
image: alpine/helm:3.12.0
script:
helm dependency update charts/myapp/
helm package charts/myapp/ version $CI_COMMIT_TAG
helm push myapp$CI_COMMIT_TAG.tgz oci://$OCI_REGISTRY/charts
rules:
if: $CI_COMMIT_TAG

# 阶段 4:部署到 staging
deploy-staging:
stage: deploy
image: alpine/helm:3.12.0
environment: staging
script:
helm upgrade install myapp oci://$OCI_REGISTRY/charts/myapp
version $CI_COMMIT_TAG
f values/staging.yaml
n myappstaging
createnamespace
helm test myapp n myappstaging
rules:
if: $CI_COMMIT_TAG =~ /^v[09]+\\.[09]+\\.[09]+rc\\.[09]+$/
after_script:
|
if [ $CI_JOB_STATUS == "failed" ]; then
helm rollback myapp -n myapp-staging
fi

# 阶段 5:部署到 production(需要手动审批)
deploy-production:
stage: deploy
image: alpine/helm:3.12.0
environment: production
script:
helm upgrade install myapp oci://$OCI_REGISTRY/charts/myapp
version $CI_COMMIT_TAG
f values/production.yaml
n myappprod
createnamespace
helm test myapp n myappprod
rules:
if: $CI_COMMIT_TAG =~ /^v[09]+\\.[09]+\\.[09]+$/
when: manual
allow_failure: false

关键设计点:

  • lint + template 双重验证:语法正确不代表渲染正确,必须两步都过
  • OCI Registry:Helm 3 支持 OCI 协议,直接推送到 Docker Registry,不需要单独的 ChartMuseum
  • 语义化版本规则:v1.2.3-rc.1 自动部署 staging,v1.2.3 需手动审批上生产
  • 测试失败自动回滚:after_script 中判断任务状态,失败则回滚
  • 六、Chart 仓库:从本地文件到企业级托管

    Helm 支持多种 Chart 仓库方案:

    方案适用场景优缺点
    本地文件系统 开发测试 简单但无法团队共享
    HTTP 服务器 中小团队 需自建,维护成本中等
    ChartMuseum 企业私有仓库 功能完善,支持多存储后端
    OCI Registry 现代方案 复用 Docker Registry,无需额外服务
    Artifact Hub 开源 Chart 发现 公开仓库,类似 npm registry

    OCI Registry 方式(推荐):

    # 登录 Registry
    helm registry login registry.example.com -u myuser -p mytoken

    # 推送 Chart
    helm push myapp-1.2.0.tgz oci://registry.example.com/charts

    # 安装
    helm install myapp oci://registry.example.com/charts/myapp –version 1.2.0

    我们团队的选择: 用 Harbor 作为私有 Registry,同时托管 Docker 镜像和 Helm Chart,一套权限体系管理所有制品。

    七、Helm Diff 插件:升级前预览变更

    helm upgrade 最大的痛点是不知道具体改了什么。Helm Diff 插件解决了这个问题:

    # 安装插件
    helm plugin install https://github.com/databus23/helm-diff

    # 升级前预览变更
    helm diff upgrade myapp bitnami/nginx -f values/prod.yaml
    # default, myapp-nginx (Deployment) spec.template.spec.containers[0].image
    # – image: nginx:1.20
    # + image: nginx:1.21

    CI/CD 中集成 Diff:

    helm-diff:
    stage: test
    script:
    helm diff upgrade myapp charts/myapp/ f values/prod.yaml || true
    artifacts:
    paths:
    diffoutput.txt

    我们团队规定:生产环境任何 helm upgrade,必须先跑 diff 并在 MR 中展示变更内容。

    八、敏感信息管理:从明文到加密

    Chart 中经常包含数据库密码、API Key 等敏感信息。直接写 values.yaml 会进入 Git 仓库,存在安全风险。

    方案 1:Sealed Secrets(推荐)

    # values.yaml 中引用加密 Secret
    postgresql:
    auth:
    existingSecret: "myapp-db-secret"

    用 kubeseal 加密 Secret:

    kubectl create secret generic myapp-db-secret –from-literal=password=prod-pass-2026 –dry-run=client -o yaml | kubeseal -o yaml > sealed-secret.yaml

    方案 2:Helm Secrets 插件

    # 安装插件
    helm plugin install https://github.com/jkroepke/helm-secrets

    # 加密 values 文件
    helm secrets encrypt values/prod-secrets.yaml

    # 部署时自动解密
    helm secrets upgrade myapp charts/myapp/ -f values/prod.yaml -f values/prod-secrets.yaml

    我们团队的选择: CI/CD 中用 Helm Secrets,本地开发用 Sealed Secrets。两种方案各有优劣,但核心原则一致:敏感信息不入 Git。

    九、我们落地 Helm 依赖管理的几个关键坑

    坑 1:循环依赖导致无限递归。
    A 依赖 B,B 又依赖 A。Helm 会直接报错,但排查时容易忽略。规范:依赖图必须是无环有向图(DAG)。

    坑 2:子 Chart 版本不兼容。
    父 Chart 声明 redis: "17.x.x",但某个子 Chart 又依赖 redis: "16.x.x",版本冲突。解决方案:用 helm dependency list 检查版本树,确保兼容。

    坑 3:charts/ 目录忘记提交。
    helm dep up 生成的 .tgz 文件应该提交到 Git(除非用 CI/CD 自动构建)。我们团队规定:charts/ 目录必须纳入版本控制,保证任何时间点都能完整复现发布。

    坑 4:global 值污染。
    global 字段会传递给所有子 Chart,但很多新人不知道。我们在规范里明确:global 只放真正全局的值(如 imageRegistry),环境特定配置必须放在对应子 Chart 命名空间下。

    十、写在最后

    Helm 的依赖管理和 CI/CD 集成,本质上是在解决应用栈的标准化交付问题。

    从单 Chart 到多 Chart 依赖,从手动 helm install 到 GitLab CI 自动化流水线,从明文密码到 Helm Secrets 加密——这套工程化能力的演进,映射着我们从"能跑就行"到"可复现、可追溯、可回滚"的架构成熟度提升。

    我们团队现在的标准:任何应用栈上线,必须提供 Helm Chart + CI/CD 流水线 + 测试用例。 Chart 即文档,流水线即流程,测试即保障。

    下一站,我们可以聊聊 ArgoCD + Helm,看看在 GitOps 体系下,Helm Chart 如何成为声明式部署的核心载体。关注我,架构路上不迷路。

    —— 本文是《100 篇架构实战》系列第 90 篇,承接上篇 Helm 基础,进阶探讨依赖管理与自动化集成。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【架构实战】Helm Chart 进阶:依赖管理、测试与 CI/CD 集成
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!