《Helm3 从入门到精通》连载第 3 篇:Chart 依赖管理与子Chart 实战——从单应用到应用栈的跨越

导语:上两篇我们掌握了 Helm3 的安装、核心概念(Chart/Release/Repo)以及 values.yaml 配置管理 。但真实生产环境远比单个 Chart 复杂:一个微服务应用栈可能包含前端、后端 API、数据库、缓存、消息队列、监控等 6+ 个组件。如果用独立 Chart 分别管理,启动顺序、配置依赖、环境隔离都是噩梦。今天这篇,我们深入 Helm 的进阶能力:依赖管理、子 Chart、测试框架,以及生产环境落地的最佳实践。


一、为什么需要 Chart 依赖管理?

1.1 从"单 Chart"到"应用栈"的演进

假设你要部署一个完整的电商系统:

┌─────────────────────────────────────────────────────────┐
│                    电商应用栈                            │
├─────────────┬─────────────┬─────────────┬───────────────┤
│   前端      │  后端 API   │   数据库    │    缓存       │
│  (Vue3)     │ (Spring Boot)│ (PostgreSQL)│   (Redis)    │
├─────────────┼─────────────┼─────────────┼───────────────┤
│   消息队列   │   监控      │   日志      │    认证      │
│  (Kafka)    │(Prometheus) │  (ELK)      │   (Keycloak) │
└─────────────┴─────────────┴─────────────┴───────────────┘

如果用 6 个独立 Chart 分别 helm install,你会遇到:

  • 启动顺序问题:数据库没就绪,后端就启动,导致反复重启
  • 配置分散:6 套 values.yaml,环境切换时要改 6 个文件
  • 版本不一致:开发环境用 Redis 6,生产用 Redis 7,排查问题困难
  • 回滚复杂:一个组件升级失败,需要手动回滚 6 个 Release

Helm 3 的依赖管理机制,就是为了解决这些问题而设计的 。


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

2.1 在 Chart.yaml 中声明依赖

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

# Chart.yaml
apiVersion: v2
name: ecommerce-stack
version: 1.0.0
description: 电商应用完整栈
type: application

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: kafka
    version: "20.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: kafka.enabled
    tags:
      - messaging
  
  - name: backend
    version: "1.2.0"
    repository: "file://charts/backend"  # 本地 Chart

2.2 关键参数详解

参数作用示例
condition条件启用,可通过 values 控制是否安装redis.enabled: false 跳过 Redis
tags批量控制一组依赖tags: [cache] 可统一开关所有缓存组件
alias重命名依赖,避免冲突两个不同版本的 Redis 用不同别名
repositoryChart 仓库地址支持远程仓库或本地路径
version依赖版本范围支持语义化版本约束

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

# 下载所有依赖
helm dependency update ecommerce-stack/

# 或简写
helm dep up ecommerce-stack/

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

ecommerce-stack/
├── Chart.yaml
├── charts/
│   ├── redis-17.3.0.tgz
│   ├── postgresql-12.1.0.tgz
│   ├── kafka-20.1.0.tgz
│   └── backend-1.2.0.tgz
├── values.yaml
└── templates/

生产建议:将 charts/ 目录加入 .gitignore,依赖包通过 CI/CD 流水线动态下载,避免仓库体积膨胀 。


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

3.1 值传递规则(容易踩坑!)

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

核心规则 :

  1. 父 Chart 的 values.yaml 中,以子 Chart 名称为 key 的部分,会传递给子 Chart
  2. 子 Chart 只能看到自己命名空间下的值
  3. global 是特殊字段,所有子 Chart 自动继承

3.2 完整示例

父 Chart 的 values.yaml:

# values.yaml

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

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

# 传递给 postgresql 子 Chart(注意用 alias 名)
db:  # 用 alias 名,不是原名 postgresql
  auth:
    password: "pg-prod-pass"
  primary:
    persistence:
      size: 100Gi
      storageClass: ssd-gold

# 后端应用配置(非子 Chart,直接在本 Chart 模板使用)
backend:
  image:
    tag: "2.1.4"
  env:
    DATABASE_URL: "postgresql://db:5432/ecommerce"

子 Chart(redis)收到的 values:

# redis 子 Chart 的 values.yaml + 父 Chart 传入的覆盖
auth:
  password: "redis-prod-pass"
replica:
  replicaCount: 3
# global 是特殊字段,所有子 Chart 自动继承
global:
  imageRegistry: myregistry.io
  imagePullSecrets:
    - name: registry-secret

3.3 踩坑记录

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

错误写法:

# ❌ 这样写,Redis 收不到密码
auth:
  password: "redis-prod-pass"

正确写法:

# ✅ 必须放在子 Chart 名称下
redis:
  auth:
    password: "redis-prod-pass"

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

4.1 为什么需要测试?

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

生产场景:

  • 验证服务端口是否可访问
  • 验证数据库连接是否成功
  • 验证依赖组件是否就绪
  • CI/CD 流程中自动回滚

4.2 定义测试 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": hook-succeeded
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['{{ .Release.Name }}:{{ .Values.service.port }}']
  restartPolicy: Never

关键注解说明:

  • "helm.sh/hook": test:标记为测试 Hook
  • "helm.sh/hook-delete-policy": hook-succeeded:测试成功后自动删除 Pod

4.3 运行测试

# 安装后手动运行测试
helm test my-release

# 输出示例
# NAME: my-release
# LAST DEPLOYED: Mon Aug 17 08:00:00 2026
# NAMESPACE: default
# STATUS: deployed
# TEST SUITE: my-release-test-connection
# Last Started: Mon Aug 17 08:01:00 2026
# Last Completed: Mon Aug 17 08:01:05 2026
# Phase: Succeeded

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

# templates/tests/test-db-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ .Release.Name }}-test-db"
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: pg-test
      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

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


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

5.1 架构总览

┌─────────────────────────────────────────────────────────┐
│  开发者提交代码 → GitLab EE(代码托管 + CI 编排)        │
│                         ↓                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐ │
│  │ Java 构建   │  │ Python 构建 │  │ 安全扫描/单元测试│ │
│  │(Maven/Gradle)│  │(pip/poetry) │  │ (SAST/依赖检测) │ │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────┘ │
│         └────────────────┴──────────────────────┘       │
│                         ↓                               │
│           统一容器镜像仓库(Harbor/Nexus)               │
│                         ↓                               │
│  ┌──────────────────────────────────────────────────┐  │
│  │  ArgoCD(GitOps 持续交付引擎)                    │  │
│  │  自动同步 Git 仓库中的 K8s Manifest 到多集群      │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

这是当前(2026 年)超大规模多语言环境下,在维护成本、新人友好度、自动化效率三者间平衡最优的架构 。

5.2 GitLab CI 核心配置

# .gitlab-ci.yml
stages:
  - build
  - test
  - package
  - deploy

variables:
  DOCKER_REGISTRY: "harbor.company.com"
  HELM_VERSION: "3.12.0"

# 构建镜像
build:
  stage: build
  script:
    - docker build -t $DOCKER_REGISTRY/myapp:$CI_COMMIT_SHA .
    - docker push $DOCKER_REGISTRY/myapp:$CI_COMMIT_SHA

# Helm 打包
helm-package:
  stage: package
  script:
    - helm dependency update
    - helm package . --version $CI_COMMIT_SHA
    - helm repo add myrepo https://$DOCKER_REGISTRY/charts
    - helm push myapp-$CI_COMMIT_SHA.tgz myrepo

# 部署到测试环境
deploy-test:
  stage: deploy
  script:
    - helm upgrade --install myapp-test ./chart \
        --namespace test \
        --set image.tag=$CI_COMMIT_SHA \
        --wait --timeout 5m
    - helm test myapp-test --namespace test
  environment:
    name: test
  only:
    - merge_requests

# 部署到生产环境
deploy-prod:
  stage: deploy
  script:
    - helm upgrade --install myapp-prod ./chart \
        --namespace prod \
        --set image.tag=$CI_COMMIT_SHA \
        --wait --timeout 10m
    - helm test myapp-prod --namespace prod
  environment:
    name: production
  when: manual
  only:
    - main

5.3 生产避坑清单

问题解决方案参考
依赖版本冲突锁定 Chart.lock 文件到 Git 
values 传递错误严格遵循子 Chart 名称作为 key 
测试 Pod 残留设置 hook-delete-policy 
部署顺序混乱使用 Helm Hooks 控制执行顺序 
多环境配置分散使用 values-{env}.yaml 文件 

六、生产环境最佳实践

6.1 多环境 values 管理

# 目录结构
chart/
├── values.yaml              # 默认配置
├── values-dev.yaml          # 开发环境
├── values-test.yaml         # 测试环境
├── values-prod.yaml         # 生产环境
└── values-prod-region-cn.yaml  # 生产环境 - 中国区
# 部署命令
helm upgrade --install myapp ./chart \
  -f values.yaml \
  -f values-prod.yaml \
  -f values-prod-region-cn.yaml \
  --namespace prod

优先级:后加载的文件覆盖先加载的文件,命令行 --set 优先级最高 。

6.2 私有仓库搭建

# 使用 Harbor 搭建私有 Chart 仓库
helm repo add my-private https://harbor.company.com/chartrepo/myproject

# 推送 Chart
helm push myapp-1.0.0.tgz my-private

# 拉取依赖
helm dependency update

6.3 安全规范

  1. 敏感信息不入库:密码、Token 等使用 Kubernetes Secret 或外部密钥管理
  2. 镜像签名验证:启用 Harbor 镜像签名,Helm Chart 签名
  3. 最小权限原则:ServiceAccount 只授予必要权限
  4. 网络策略隔离:不同组件间使用 NetworkPolicy 限制通信

【进阶深度对比】

✅ 对比上一期学习边界

维度上期(第 2 篇)本期(第 3 篇)
管理对象单个 Chart多 Chart 应用栈
配置方式单 values.yaml多 values 文件 + 依赖传递
部署粒度单 Release多 Release 协同
验证机制手动验证自动化测试框架
集成能力手动执行CI/CD 流水线

✅ 识别新旧知识盲区

知识点上期覆盖本期新增容易混淆点
依赖声明❌✅ Chart.yaml dependencies与 Docker 依赖混淆
值传递❌✅ 父→子 values 传递规则alias 名称 vs 原名称
测试框架❌✅ helm test + Hook与普通 Pod 区别
多环境⚠️ 基础✅ 多文件叠加策略覆盖优先级
CI/CD❌✅ GitLab CI + Helm手动 vs 自动化

✅ 梳理容易混淆概念

概念 A概念 B区别
conditiontagscondition 控制单个依赖,tags 批量控制一组
aliasnamealias 是父 Chart 中的别名,name 是子 Chart 原名
global普通 valuesglobal 所有子 Chart 可见,普通 values 仅当前 Chart
helm dep uphelm install前者下载依赖,后者部署 Release
hook普通资源hook 在特定阶段执行,可设置删除策略

✅ 指明能力提升方向

下一阶段(第 4 篇)预告:

  • 🎯 Helm Hooks 深度解析:pre-install、post-upgrade、pre-delete 等 12 种 Hook 类型
  • 🎯 多环境治理:Helmfile 批量管理 100+ Chart
  • 🎯 GitOps 集成:ArgoCD + Helm 自动化同步
  • 🎯 生产故障排查:Release 卡住、Hook 超时、依赖循环依赖

能力进阶路径:

使用者视角(第 1-2 篇)
    ↓
Chart 开发者视角(第 3-4 篇)← 当前阶段
    ↓
生产架构治理视角(第 5-6 篇)

下期预告:《Helm Hooks 深度解析与 Helmfile 多环境治理》—— 掌握 12 种 Hook 类型,用 Helmfile 一键管理 100+ Chart 的多环境部署。


参考资料:

  • Helm Chart 依赖管理与 CI/CD 集成实战
  • GitLab CI + ArgoCD GitOps 架构
  • Helm3 部署配置规范
  • GitLab Runner Helm Chart 官方文档

参考来源

 

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐