3. 手动节点扩容:通过 kubeadm 添加 Worker 节点、证书分发与 管理

在生产环境中,当业务负载增长或现有 Worker 节点资源不足时,需要向集群添加新的计算节点。kubeadm 提供了标准化的节点加入流程,核心步骤包括:控制平面生成 Join 、新节点执行 kubeadm join 命令、节点证书分发与信任建立。本章将详细拆解这一过程,并深入探讨 管理与证书分发的安全最佳实践。

3.1 节点加入的核心流程

使用 kubeadm 添加 Worker 节点本质上是一个“控制平面信任新节点”的过程。新节点需要向控制平面证明自己的身份,并获取加入集群所需的初始配置与证书。整个流程可以分为以下四个阶段:

  1. 生成:在控制平面节点上生成一个临时的 Bootstrap ,该 包含集群身份标识与密钥信息。
  2. 发现与验证:新节点通过 中的信息,发现控制平面 API Server 的地址,并验证其身份(通过 CA 证书哈希)。
  3. 证书签名请求(CSR):新节点向控制平面发起 CSR,请求签署自己的节点证书。
  4. 节点注册:控制平面批准 CSR 后,新节点获取签署后的证书,完成 kubelet 的启动与节点注册。
关键概念: Bootstrap 是一种“一次性”或“短生命周期”的认证机制,用于新节点的初始加入。一旦节点成功加入,kubelet 将使用其长期证书与 API Server 通信,不再依赖 。
kubeadm 节点加入流程 控制平面节点 kubeadm create 新 Worker 节点 kubeadm join 1. 分发 + CA Hash 2. 发现 & 验证 API Server 地址 / CA Hash 3. CSR 请求 证书签名请求 4. 批准 & 注册 kubelet 启动 / Node Ready

3.2 使用 kubeadm 管理加入凭证

kubeadm 命令是管理 Bootstrap 的核心工具。 由控制平面生成,默认有效期为 24 小时。在生产环境中,建议根据扩容窗口手动创建 ,并严格控制其生命周期。

3.2.1 创建与查看

在控制平面节点上执行以下命令创建新的 Bootstrap :

# 创建 ,并指定有效期(例如 6 小时)
kubeadm  create --ttl 6h

# 输出示例:
# 5b4d3c.2f8a1e6d9c0b7a4e

查看当前集群中所有有效的 :

kubeadm  list

# 输出示例:
#                      TTL         EXPIRES                USAGES                   DESCRIPTION
# 5b4d3c.2f8a1e6d9c0b7a4e   5h59m       2025-04-10T14:30:00Z   authentication,signing   <none>

3.2.2 获取 CA 证书哈希

新节点在加入时需要验证控制平面 API Server 的证书是否由可信的 CA 签发。CA 证书的哈希值通过以下命令获取:

# 获取 CA 证书的 SHA256 哈希
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
  openssl rsa -pubin -outform der 2>/dev/null | \
  openssl dgst -sha256 -hex | sed 's/^.* //'

# 输出示例:
# 8c7a3b5f2e1d4a6b9c0d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b
安全提示: 切勿将 和 CA 证书哈希通过不安全的渠道(如明文邮件、公共聊天工具)传输。建议使用加密通道(如 SSH、Vault)或安全的内部配置管理工具分发。

3.3 执行节点加入操作

在新 Worker 节点上,使用 kubeadm join 命令完成加入。命令需要提供 API Server 地址、 和 CA 证书哈希。

# 在新 Worker 节点上执行
kubeadm join 192.168.1.100:6443 \
  -- 5b4d3c.2f8a1e6d9c0b7a4e \
  --discovery--ca-cert-hash sha256:8c7a3b5f2e1d4a6b9c0d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b

# 成功输出示例:
# [preflight] Running pre-flight checks
# [preflight] Reading configuration from the cluster...
# [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
# [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
# [kubelet-start] Starting the kubelet
# [tls-bootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
# [tls-bootstrap] The kubelet is now performing the TLS Bootstrap
# [join] Node registration complete
# This node has joined the cluster:
# * Certificate signing request was sent to apiserver and a response was received.
# * The kubelet was informed of the new secure connection details.
# Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

3.4 证书分发与 TLS Bootstrap 机制

新节点加入时,kubelet 需要一份由集群 CA 签署的证书才能与 API Server 建立 TLS 连接。kubeadm 使用 TLS Bootstrap 机制自动完成证书的请求与分发,无需手动拷贝证书文件。

3.4.1 TLS Bootstrap 工作流程

步骤 描述 涉及组件
1 kubelet 使用 Bootstrap 向 API Server 发起 CSR kubelet → API Server
2 API Server 验证 有效性,创建 CertificateSigningRequest 资源 API Server → etcd
3 集群控制器(kube-controller-manager)自动批准 Node 角色的 CSR kube-controller-manager
4 CA 签署证书,kubelet 获取并保存到本地磁盘 API Server → kubelet
5 kubelet 使用新证书重启,建立安全的 TLS 连接 kubelet

3.4.2 证书文件位置

成功加入后,Worker 节点上的证书文件存储在以下路径:

/etc/kubernetes/
├── kubelet.conf          # kubelet 的 kubeconfig 文件,包含客户端证书
├── pki/
│   ├── ca.crt            # 集群 CA 证书(用于验证 API Server)
│   └── kubelet.crt       # kubelet 的客户端证书(由 CA 签署)
│   └── kubelet.key       # kubelet 的私钥

3.5 验证节点加入状态

在控制平面节点上,使用 kubectl 验证新节点是否成功加入并处于 Ready 状态:

kubectl get nodes -o wide

# 输出示例:
# NAME           STATUS   ROLES           AGE   VERSION   INTERNAL-IP      EXTERNAL-IP
# master-1       Ready    control-plane   10d   v1.28.0   192.168.1.100    <none>
# worker-1       Ready    <none>          5m    v1.28.0   192.168.1.101    <none>
# worker-2       Ready    <none>          2m    v1.28.0   192.168.1.102    <none>
排障提示: 如果节点状态为 NotReady,请检查以下常见原因:
  • kubelet 服务未启动:systemctl status kubelet
  • 容器运行时(如 containerd)未运行:systemctl status containerd
  • 网络插件(如 Calico、Flannel)未部署或 Pod 网络 CIDR 冲突
  • 节点证书过期或 CSR 未被批准:kubectl get csr

3.6 管理与安全最佳实践

在生产环境中, 管理是集群安全的重要一环。以下实践建议可有效降低 泄露带来的风险:

  • 短生命周期:为每次扩容操作创建新的 ,并设置 --ttl 为最小必要时间(如 1-6 小时)。
  • 及时撤销:扩容完成后,立即使用 kubeadm delete <> 删除 。
  • 使用 Secret 存储:避免在命令行直接暴露 ,可通过 Kubernetes Secret 或外部密钥管理服务(如 HashiCorp Vault)分发。
  • 限制 用途:通过 --usages 参数限制 仅用于 authentication 和 signing,避免滥用。
  • 审计日志:启用 API Server 的审计日志,记录所有 相关的创建、使用和删除操作。
生命周期管理 1. 创建 kubeadm create 2. 安全分发 SSH / Vault / Secret 3. 节点加入 kubeadm join 4. 撤销 kubeadm delete 最佳实践 每次扩容使用新 → 设置 TTL 为最小必要时间 → 扩容完成后立即删除

3.7 手动证书分发场景(非 TLS Bootstrap)

在某些受限环境(如离线集群、自定义 CA 或安全合规要求),可能无法使用自动的 TLS Bootstrap 机制。此时需要手动将控制平面节点的证书拷贝到 Worker 节点。

3.7.1 手动分发步骤

  1. 在控制平面节点上打包证书目录:
    tar czf k8s-certs.tar.gz -C /etc/kubernetes/pki ca.crt ca.key
  2. 安全传输到 Worker 节点:
    scp k8s-certs.tar.gz worker-1:/tmp/
  3. 在 Worker 节点上解压并放置证书:
    mkdir -p /etc/kubernetes/pki
    tar xzf /tmp/k8s-certs.tar.gz -C /etc/kubernetes/pki
  4. 执行加入命令时跳过 TLS Bootstrap:
    kubeadm join 192.168.1.100:6443 \
      -- 5b4d3c.2f8a1e6d9c0b7a4e \
      --discovery--ca-cert-hash sha256:... \
      --tls-bootstrap=false
安全风险: 手动分发 CA 私钥(ca.key)会带来极大的安全风险。任何持有 CA 私钥的节点都可以签署任意证书。仅在完全可信的网络环境或离线场景下使用此方法,并确保传输过程加密。

3.8 常见问题与排障

问题现象 可能原因 解决方案
kubeadm join 超时 网络不通、API Server 未监听、防火墙规则 检查网络连通性:telnet <api-server-ip> 6443
Error: is invalid 已过期、 被删除、 格式错误 重新创建 :kubeadm create
CA hash mismatch CA 证书哈希值错误或 API Server 证书已更换 重新获取 CA 哈希:openssl x509 -pubkey ...
节点状态 NotReady kubelet 未启动、容器运行时异常、CNI 插件未就绪 检查 kubelet 日志:journalctl -u kubelet -f
CSR 未被批准 自动批准控制器未启用、节点角色不匹配 手动批准 CSR:kubectl certificate approve <csr-name>

3.9 本章小结

通过 kubeadm 手动添加 Worker 节点是 Kubernetes 集群扩容的基础操作。核心要点包括:

  • 使用 kubeadm create 生成短生命周期的 Bootstrap 。
  • 通过 kubeadm join 命令配合 和 CA 哈希完成节点加入。
  • TLS Bootstrap 机制自动处理证书分发,无需手动干预。
  • 管理遵循“最小权限、最短时间、及时撤销”的安全原则。
  • 在离线或受限环境中,可手动分发证书,但需注意 CA 私钥的保护。

掌握手动节点扩容流程,是后续学习自动化扩容、节点池管理和弹性伸缩策略的基础。