《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 用不同别名
repository Chart 仓库地址 支持远程仓库或本地路径
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 区别
condition tags condition 控制单个依赖,tags 批量控制一组
alias name alias 是父 Chart 中的别名,name 是子 Chart 原名
global 普通 values global 所有子 Chart 可见,普通 values 仅当前 Chart
helm dep up helm 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、测试、元服务和应用上架分发等。

更多推荐