4. 控制平面初始化:helm init / helm repo add 命令背后的网络握手与认证流程
在 Helm v2 时代,helm init 是部署 Tiller 服务端并初始化本地环境的起点;而在 Helm v3 移除 Tiller 后,helm repo add 成为控制平面与 Chart 仓库建立信任关系的核心操作。本章深入剖析这两个命令背后的网络握手、证书交换与认证机制,帮助架构师理解控制平面初始化阶段的安全基线。
4.1 Helm v2 的 helm init:Tiller 部署与双向 TLS 握手
helm init 在 v2 中承担双重职责:在集群内创建 Tiller 服务端,并在本地初始化 Helm 客户端配置。其网络握手流程分为两个阶段:
| 阶段 | 动作 | 协议/端口 | 认证方式 |
|---|---|---|---|
| 阶段一 | Helm 客户端通过 kubeconfig 向 API Server 提交 Deployment 定义,创建 Tiller Pod | HTTPS (6443) | Kubernetes RBAC + 客户端证书 |
| 阶段二 | Helm 客户端与 Tiller 建立 gRPC 连接,交换证书并验证身份 | gRPC (44134) | 双向 TLS(mTLS) |
helm init --tiller-tls --tiller-tls-cert --tiller-tls-key --tiller-tls-verify 启用 mTLS,否则 Tiller 默认监听在 0.0.0.0:44134 且不验证客户端身份,存在严重安全风险。
4.1.1 阶段一:Tiller 部署到集群
Helm 客户端读取 ~/.kube/config 中的集群地址、CA 证书和客户端凭据,向 API Server 发送以下资源创建请求:
# helm init 实际构造的 Deployment 对象(简化)
apiVersion: apps/v1
kind: Deployment
metadata:
name: tiller-deploy
namespace: kube-system
spec:
replicas: 1
template:
spec:
containers:
- name: tiller
image: gcr.io/kubernetes-helm/tiller:v2.17.0
ports:
- containerPort: 44134
env:
- name: TILLER_NAMESPACE
value: kube-system
- name: TILLER_HISTORY_MAX
value: "10"
API Server 验证客户端证书后,将 Tiller 调度到工作节点。此时 Tiller 启动并生成自签名 CA 和服务器证书(除非用户提供外部证书)。
4.1.2 阶段二:gRPC 双向 TLS 握手
客户端执行 helm list 或 helm install 时,触发与 Tiller 的 gRPC 连接。完整的 mTLS 握手流程如下:
- 客户端向 Tiller:44134 发起 TCP 连接。
- Tiller 发送其服务器证书(含公钥)和 CA 证书链。
- 客户端使用本地存储的 CA 证书验证服务器证书的签名和有效期。
- 客户端发送自身客户端证书,Tiller 使用 CA 证书验证客户端身份。
- 双方协商对称加密密钥(TLS 会话密钥),后续 gRPC 通信使用该密钥加密。
- gRPC 通道建立,开始传输 Release 数据。
4.2 Helm v3 的 helm repo add:仓库索引获取与认证
Helm v3 移除了 Tiller,控制平面初始化简化为本地仓库配置。helm repo add 的核心任务是:验证仓库 URL 的可达性、获取 index.yaml 并缓存到本地。其网络握手流程如下:
4.2.1 仓库添加的 HTTP 握手步骤
- DNS 解析: 客户端解析仓库域名(如
https://charts.bitnami.com/bitnami)为 IP 地址。 - TLS 握手: 客户端验证仓库服务器的 HTTPS 证书(CA 签名、域名匹配、有效期)。
- HTTP GET 请求: 客户端向
/index.yaml路径发送 GET 请求,携带User-Agent: Helm/x.y.z头。 - 服务器响应: 仓库返回
index.yaml(YAML 格式的 Chart 索引),包含所有 Chart 的版本、URL、校验和(SHA-256)。 - 本地缓存: 客户端将
index.yaml写入~/.cache/helm/repository/,后续helm search直接读取缓存。
helm repo add --ca-file 指定 CA 证书,否则 TLS 握手失败。切勿使用 --insecure-skip-tls-verify 跳过验证,这会使中间人攻击成为可能。
4.2.2 认证方式对比
| 认证方式 | helm repo add 参数 | 传输安全 | 适用场景 |
|---|---|---|---|
| 无认证 | 无额外参数 | 依赖 HTTPS | 公共仓库(Bitnami、stable) |
| 基本认证 | --username + --password |
Base64 编码,需 HTTPS 加密 | 私有仓库(Harbor、Nexus) |
| Bearer | --password 传入 |
在 Authorization 头中 | OAuth2 代理仓库 |
| 客户端证书 | --cert-file + --key-file |
mTLS 双向认证 | 企业级安全要求 |
4.2.3 index.yaml 校验机制
Helm 客户端在下载 index.yaml 后,不会自动验证其完整性(因为仓库本身是可信源)。但 helm install 或 helm pull 时会校验 Chart 包的 SHA-256:
# index.yaml 中的条目示例
apiVersion: v1
entries:
nginx:
- name: nginx
version: 13.2.0
urls:
- https://charts.bitnami.com/bitnami/nginx-13.2.0.tgz
digest: sha256:7a3c3b3e8e5c5b5a5b5c5d5e5f5a5b5c5d5e5f5a5b5c5d5e5f5a5b5c5d5e5f
当用户执行 helm install nginx bitnami/nginx 时,客户端下载 Chart 包后计算 SHA-256,与 index.yaml 中的 digest 比对,防止下载被篡改的 Chart。
4.3 控制平面初始化安全最佳实践
- Helm v2 用户: 务必使用
helm init --tiller-tls --tiller-tls-cert --tiller-tls-key --tiller-tls-verify,并将 CA 证书分发给所有客户端。 - Helm v3 用户: 所有仓库必须使用 HTTPS,避免 HTTP 明文传输导致 index.yaml 被篡改。
- 私有仓库: 使用
--ca-file指定私有 CA,或使用--cert-file+--key-file实现 mTLS。 - 凭证管理: 不要在命令行直接输入密码,使用环境变量或 Helm 的
--password-stdin选项。 - 缓存安全:
~/.cache/helm/repository/包含仓库索引,确保该目录权限为 700,防止其他用户读取仓库结构。