一、引言
Helm作为Kubernetes生态中最受欢迎的包管理工具,自2016年发布以来经历了重大演进。从Helm 2.0到3.0的转变是一次革命性的架构升级,核心变化是移除了Tiller组件,带来了更简洁、更安全的使用体验。本文将深入剖析Helm 2.0与3.0的核心差异,并提供生产环境迁移的最佳实践。
二、SCQA分析框架
情境(Situation)
- Helm已成为Kubernetes应用部署的标准工具
- 企业大量使用Helm 2.0管理生产环境应用
- 社区已停止对Helm 2.0的支持
冲突(Complication)
- Helm 2.0的Tiller组件存在安全风险
- 多团队共享Tiller导致权限管理复杂
- 从Helm 2.0迁移到3.0需要考虑兼容性和数据迁移
问题(Question)
- Helm 2.0和3.0的核心架构差异是什么?
- Chart格式有哪些不兼容的变化?
- 如何安全地将生产环境从Helm 2.0迁移到3.0?
- 迁移后如何确保应用稳定性?
答案(Answer)
- Helm 3.0移除Tiller,采用Client-Only架构
- Chart API版本从v1升级到v2,requirements.yaml合并到Chart.yaml
- 使用helm-2to3工具进行平滑迁移
- 建立完善的测试和验证流程
三、Helm核心概念回顾
什么是Helm?
Helm是Kubernetes的包管理工具,类似于Linux系统的apt、yum或Python的pip。它将Kubernetes资源打包成Chart,实现应用的一键部署、升级和管理。
核心概念
| 概念 | 定义 | 说明 |
|---|---|---|
| Chart | 应用打包模板 | 包含部署所需的所有Kubernetes资源定义 |
| Release | Chart的部署实例 | 同一个Chart可以部署多个Release |
| Repository | Chart仓库 | 存储和共享Chart的地方 |
| Values | 配置参数 | 部署时传入的配置值 |
基本使用流程
# 1. 添加仓库
helm repo add stable https://charts.helm.sh/stable
# 2. 更新仓库索引
helm repo update
# 3. 搜索Chart
helm search repo nginx
# 4. 安装Chart
helm install my-nginx stable/nginx \
--set service.type=NodePort \
--namespace web
# 5. 查看Release
helm list -n web
# 6. 更新配置
helm upgrade my-nginx stable/nginx \
--set replicaCount=3
# 7. 回滚版本
helm rollback my-nginx 1
# 8. 删除Release
helm uninstall my-nginx -n web
四、Helm 2.0架构详解
Client-Server架构
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes集群 │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ kube-system │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ Tiller │ │ │
│ │ │ - Deployment (pod) │ │ │
│ │ │ - ServiceAccount (高权限) │ │ │
│ │ │ - gRPC Server │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ │ API Server │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 其他命名空间 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Release1 │ │Release2 │ │Release3 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
▲
│ gRPC
┌─────────────────────────────┴─────────────────────────────┐
│ Helm Client │
│ helm install / upgrade / delete / rollback │
└───────────────────────────────────────────────────────────┘
Tiller核心职责
- 接收客户端请求:通过gRPC接收helm命令
- 模板渲染:将Chart模板与Values合并
- 资源管理:创建、更新、删除Kubernetes资源
- 状态存储:将Release信息存储在ConfigMap中
安全隐患分析
| 风险点 | 描述 | 影响 |
|---|---|---|
| 权限集中 | Tiller需要集群级权限 | 单点入侵可控制整个集群 |
| 多租户冲突 | 所有用户共享同一Tiller | 权限边界模糊 |
| 单点故障 | Tiller宕机导致无法操作 | 影响所有应用部署 |
| 审计困难 | 操作日志集中在Tiller | 难以追踪责任人 |
五、Helm 3.0架构革新
Client-Only架构
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes集群 │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 各个命名空间 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Release1 │ │Release2 │ │Release3 │ │ │
│ │ │ Secret │ │ Secret │ │ Secret │ ← 状态存储 │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ │ API Server │
└──────────────────────────────┼──────────────────────────────────┘
▲
│ kubectl / REST API
┌─────────────────────────────┴─────────────────────────────┐
│ Helm Client │
│ helm install / upgrade / delete / rollback │
│ ↓ │
│ 直接连接API Server,继承用户kubeconfig权限 │
└───────────────────────────────────────────────────────────┘
核心改进
1. Tiller移除
- 简化架构,减少组件依赖
- 消除单点故障风险
- 降低部署和维护复杂度
2. 安全性提升
- 继承Kubernetes RBAC权限模型
- 每个用户使用自己的权限操作
- 支持细粒度的命名空间级别权限控制
3. 状态存储优化
- Release信息存储从ConfigMap改为Secret
- 支持加密存储敏感配置
- 更好的命名空间隔离
4. 功能增强
- 全面支持CRD资源
- 改进的Chart依赖管理
- 增强的模板引擎功能
六、关键差异对比表
| 维度 | Helm 2.0 | Helm 3.0 | 说明 |
|---|---|---|---|
| 架构模式 | Client-Server | Client-Only | 移除Tiller组件 |
| 状态存储 | ConfigMap | Secret | 安全性更好 |
| Chart API版本 | v1 | v2 | 不兼容变更 |
| 依赖管理 | requirements.yaml | Chart.yaml内嵌 | 简化配置 |
| 命名空间 | 默认default | 强隔离 | 必须指定 |
| 安全性 | Tiller高权限 | 用户RBAC | 权限分散 |
| CRD支持 | 有限 | 全面支持 | 扩展能力强 |
| Release名称 | 全局唯一 | 命名空间内唯一 | 更灵活 |
| 回滚机制 | 基于revision | 增强版revision | 更可靠 |
| 日志输出 | 基础 | 结构化JSON | 便于集成 |
七、Chart格式迁移指南
Chart.yaml变更
# Helm 2.0
apiVersion: v1
name: mychart
version: 1.0.0
description: A Helm chart for Kubernetes
maintainers:
- name: John Doe
email: john@example.com
# Helm 3.0
apiVersion: v2 # 必须升级
name: mychart
version: 1.0.0
description: A Helm chart for Kubernetes
maintainers:
- name: John Doe
email: john@example.com
dependencies: # 依赖直接定义在此
- name: nginx
version: "1.16.0"
repository: "@stable"
requirements.yaml合并
# Helm 2.0 - 单独文件 requirements.yaml
dependencies:
- name: nginx
version: "1.16.0"
repository: "https://kubernetes-charts.storage.googleapis.com"
condition: nginx.enabled
tags:
- frontend
# Helm 3.0 - 合并到 Chart.yaml
# 以上内容直接移到 Chart.yaml 的 dependencies 字段
模板语法变化
# Helm 2.0 语法
# Helm 3.0 语法(兼容)
# Helm 3.0 新增
八、生产环境迁移实战
迁移前准备
1. 环境检查
# 检查Helm 2版本
helm version
# 检查Helm 3版本
helm3 version
# 检查现有Release
helm list --all-namespaces
# 备份配置
helm repo list > helm2-repos.txt
helm list -a > helm2-releases.txt
2. Chart兼容性检查
# 使用helm3 lint检查
helm3 lint ./mychart/
# 检查API版本
grep apiVersion ./mychart/Chart.yaml
# 检查是否存在requirements.yaml
ls -la ./mychart/requirements.yaml
迁移工具使用
使用helm-2to3插件
# 安装插件
helm3 plugin install https://github.com/helm/helm-2to3
# 迁移配置
helm3 2to3 move config
# 迁移Release(推荐先dry-run)
helm3 2to3 convert my-release --dry-run
# 实际迁移
helm3 2to3 convert my-release
# 验证迁移结果
helm3 list -n my-namespace
迁移策略选择
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 原地迁移 | 非核心应用 | 操作简单 | 风险较高 |
| 蓝绿迁移 | 核心应用 | 风险低 | 资源消耗大 |
| 重新部署 | Chart有重大变更 | 干净彻底 | 需要重新测试 |
迁移后验证
# 检查Release状态
helm3 list -n my-namespace
# 验证Pod状态
kubectl get pods -n my-namespace
# 验证服务可用性
curl http://service-ip
# 对比配置差异
helm3 get values my-release
九、生产环境最佳实践
1. RBAC权限配置
# 创建专用ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: helm-operator
namespace: devops
---
# 创建Role(命名空间级别)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-operator
namespace: devops
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
# 绑定Role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-operator
namespace: devops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: helm-operator
subjects:
- kind: ServiceAccount
name: helm-operator
2. Chart仓库管理
# 添加官方仓库
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 添加私有仓库(Harbor示例)
helm repo add private https://harbor.example.com/chartrepo/library
helm repo add --username admin --password secret private https://harbor.example.com/chartrepo/library
# 更新仓库索引
helm repo update
# 清理旧仓库
helm repo remove old-repo
3. Values配置管理
# values.yaml - 分层配置
global:
imageRegistry: registry.example.com
namespace: default
image:
repository: nginx
tag: "1.21.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
# 环境特定配置
# values-prod.yaml
resources:
limits:
cpu: 500m
memory: 512Mi
# 部署时指定配置
helm install my-app ./mychart \
-f values.yaml \
-f values-prod.yaml \
--set image.tag=1.21.1 \
-n production
4. 持续集成流程
# GitHub Actions示例
name: Helm CI/CD
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Helm
uses: azure/setup-helm@v1
with:
version: '3.8.0'
- name: Lint Chart
run: helm lint ./charts/mychart
- name: Package Chart
run: helm package ./charts/mychart
- name: Publish to Repository
run: |
helm repo add private https://charts.example.com \
--username $ \
--password $
helm push mychart-1.0.0.tgz private
十、常见问题与解决方案
问题一:Chart安装失败,提示API版本不兼容
原因:Chart.yaml的apiVersion仍为v1
解决方案:
# 修改apiVersion
sed -i 's/apiVersion: v1/apiVersion: v2/' ./mychart/Chart.yaml
# 或者使用helm convert工具
helm convert ./mychart/ --api-version v2
问题二:迁移后Release状态异常
原因:ConfigMap到Secret的迁移不完整
解决方案:
# 检查Release状态
helm3 status my-release
# 如果状态异常,重新部署
helm3 uninstall my-release
helm3 install my-release ./mychart
问题三:权限不足导致操作失败
原因:当前用户的kubeconfig权限不够
解决方案:
# 检查当前上下文
kubectl config current-context
# 切换到有权限的上下文
kubectl config use-context admin@cluster
# 或者使用ServiceAccount
kubectl apply -f helm-sa.yaml
kubectl config set-context helm-context --user=helm-operator --namespace=devops
问题四:依赖解析失败
原因:requirements.yaml未合并到Chart.yaml
解决方案:
# 合并依赖
cat requirements.yaml
# 将dependencies部分复制到Chart.yaml
# 删除requirements.yaml
rm requirements.yaml
# 更新依赖
helm dependency update ./mychart/
十一、迁移检查清单
- 备份Helm 2配置和Release信息
- 升级所有Chart的apiVersion到v2
- 合并requirements.yaml到Chart.yaml
- 测试Chart兼容性(helm lint)
- 在测试环境进行迁移演练
- 使用dry-run模式验证迁移命令
- 执行正式迁移
- 验证所有Release状态正常
- 验证应用功能和性能
- 清理Helm 2相关资源
十二、总结与展望
Helm 3.0通过移除Tiller组件,实现了更简洁、更安全的架构设计。从Helm 2.0迁移到3.0需要关注Chart格式兼容性、Release状态迁移和RBAC权限配置。采用helm-2to3工具可以大大简化迁移过程。
未来,Helm将继续演进,提供更好的安全性、可观测性和集成能力。建议企业尽快完成迁移,以获得更好的性能和安全性保障。
本文对应的面试题:Helm 2.0 和 3.0 的区别?
文档信息
- 本文作者:soveran zhong
- 本文链接:https://blog.clockwingsoar.cn/2026/06/06/helm-v2-v3-difference/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)