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 握手流程如下:

mTLS 握手步骤:
  1. 客户端向 Tiller:44134 发起 TCP 连接。
  2. Tiller 发送其服务器证书(含公钥)和 CA 证书链。
  3. 客户端使用本地存储的 CA 证书验证服务器证书的签名和有效期。
  4. 客户端发送自身客户端证书,Tiller 使用 CA 证书验证客户端身份。
  5. 双方协商对称加密密钥(TLS 会话密钥),后续 gRPC 通信使用该密钥加密。
  6. gRPC 通道建立,开始传输 Release 数据。
Helm v2 helm init → Tiller mTLS 握手流程 Helm 客户端 gRPC 客户端 Tiller 服务端 gRPC 服务端 ① TCP 连接 (44134) ② 服务器证书 + CA 链 ③ 验证服务器证书 (CA 签名 + 有效期) ④ 客户端证书 ⑤ 验证客户端证书 (CA 签名 + 身份) ⑥ 协商对称密钥 ⑦ 加密 gRPC 通道建立 Release 数据通过 AES-GCM 加密传输 ⚠ 若未启用 --tiller-tls,步骤 ③~⑥ 全部跳过,gRPC 以明文传输,任何能访问 44134 端口的进程均可劫持 Release 数据

4.2 Helm v3 的 helm repo add:仓库索引获取与认证

Helm v3 移除了 Tiller,控制平面初始化简化为本地仓库配置。helm repo add 的核心任务是:验证仓库 URL 的可达性、获取 index.yaml 并缓存到本地。其网络握手流程如下:

4.2.1 仓库添加的 HTTP 握手步骤

  1. DNS 解析: 客户端解析仓库域名(如 https://charts.bitnami.com/bitnami)为 IP 地址。
  2. TLS 握手: 客户端验证仓库服务器的 HTTPS 证书(CA 签名、域名匹配、有效期)。
  3. HTTP GET 请求: 客户端向 /index.yaml 路径发送 GET 请求,携带 User-Agent: Helm/x.y.z 头。
  4. 服务器响应: 仓库返回 index.yaml(YAML 格式的 Chart 索引),包含所有 Chart 的版本、URL、校验和(SHA-256)。
  5. 本地缓存: 客户端将 index.yaml 写入 ~/.cache/helm/repository/,后续 helm search 直接读取缓存。
安全警告: 如果仓库使用自签名证书或私有 CA,必须使用 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。

helm repo add 网络握手与 index.yaml 获取流程 Helm 客户端 helm repo add DNS 解析 域名 → IP Chart 仓库 HTTPS 服务器 ① 域名查询 ② TLS 握手 ③ 服务器证书 (CA 验证) ④ GET /index.yaml ⑤ 返回 index.yaml (含 SHA-256) ⑥ 缓存到 ~/.cache/helm/repository/ 后续 helm search 读取本地缓存 ⑦ 安装时校验 Chart 包 SHA-256 防止下载被篡改的 Chart ⚠ 私有仓库需额外配置认证:helm repo add myrepo https://repo.example.com --username admin --password '${PASSWORD}'

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,防止其他用户读取仓库结构。