Kubernetes 二进制部署集群证书更新完全手册

本文是一份专为二进制方式部署的 Kubernetes 集群设计的证书更新完全手册。与 kubeadm 部署的集群不同,二进制部署的集群需要我们手动管理和更新所有 TLS 证书。本文将详细介绍从根 CA 到各个核心组件证书的完整续期流程。

为什么需要更新证书?

Kubernetes 集群的安全性高度依赖于基于 TLS 的双向认证。控制平面组件(apiserver, etcd, controller-manager, scheduler)之间以及控制平面与数据平面(kubelet)之间的所有通信都由证书加密和验证。这些证书都有有效期,一旦过期,将导致:

  • kubectl 无法访问 kube-apiserver
  • kube-apiserver 无法访问 etcd,导致集群状态无法读写。
  • kubelet 无法与 apiserver 通信,节点变为 NotReady 状态。
  • 集群整体功能瘫痪。

因此,定期在证书过期前进行续期是保障集群稳定运行的核心运维任务。

手动续期总览

手动续期的核心思想是:使用旧的根 CA 私钥生成一个新的根 CA 证书,再用这个新的 CA 去签发所有组件的新证书

整个过程分为以下几个关键步骤:

  1. 准备工作:备份、检查证书路径和有效期。
  2. 续期根 CA:使用旧的 ca.key 生成新的 ca.crt
  3. 续期 Etcd 证书:为 Etcd 生成新的服务端和客户端证书。
  4. 续期 Master 组件证书:为 kube-apiserver, kube-controller-manager, kube-scheduler 生成新证书。
  5. 续期 Kubelet 证书:为每个节点的 kubelet 生成新的客户端证书。
  6. 更新 Kubeconfig 文件:为 admin 和其他用户生成新的配置文件。
  7. 分发证书并重启服务:将新证书部署到所有节点并重启相关服务。
  8. 验证:检查集群状态和新证书有效期。

详细操作步骤

步骤一:准备工作

1. 定位证书目录

首先,找到您的证书存放目录。通常,二进制部署的集群会将证书统一放在 master 节点的 /etc/kubernetes/pki 或类似的自定义目录中。

2. 备份!备份!备份!

这是整个过程中最重要的一步。在进行任何操作前,请务必完整备份您的证书目录。

1
2
# 在所有 master 节点上执行
sudo cp -a /etc/kubernetes/pki /etc/kubernetes/pki.bak-$(date +%F)

3. 检查当前证书有效期

使用 openssl 命令检查所有证书的到期时间,确定需要更新的证书。

1
2
3
4
5
6
7
8
# 示例:检查 apiserver 证书
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates

# 您可以编写一个脚本来批量检查所有证书
for cert in $(find /etc/kubernetes/pki -name "*.crt"); do 
  echo "--- ${cert} ---"; 
  openssl x509 -in ${cert} -noout -subject -dates; 
done

步骤二:续期根 CA (ca.crt)

根 CA 是信任的起点。续期根 CA 的本质是使用其现有的私钥(ca.key)重新签发一张具有更长有效期的新证书。为了确保新证书保留所有必要的 CA 属性(例如 keyCertSign 权限),我们采用一个更严谨的三步流程。

1. 从现有 CA 证书创建 CSR

首先,我们将现有的 CA 证书(ca.crt)转换回一个证书签名请求(CSR)。

1
2
3
4
5
6
# 进入证书目录
cd /etc/kubernetes/pki

# 从 ca.crt 和 ca.key 创建 ca.csr
# 这会保留原始证书的主题(Subject)信息
sudo openssl x509 -x509toreq -in ca.crt -signkey ca.key -out ca.csr

2. 创建 CA 扩展配置文件 (ca.conf)

为了确保新生成的根证书具备正确的 CA 属性,我们需要创建一个 OpenSSL 扩展配置文件。

创建一个名为 ca.conf 的文件,内容如下:

1
2
3
4
5
[ v3_ca ]
keyUsage = critical, cRLSign, keyCertSign
basicConstraints = critical,CA:TRUE,pathlen:2
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
  • keyUsage: 声明该证书用于签署其他证书和 CRL。
  • basicConstraints: 声明这是一个 CA 证书。

3. 签发新的根 CA 证书

最后,我们使用根私钥(ca.key)和扩展配置文件(ca.conf)来签署 CSR,生成新的根证书。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 使用 ca.key、ca.csr 和 ca.conf 生成新的 ca-new.crt
# 将有效期设置为 10 年 (3650 天)
sudo openssl x509 -req -extfile ./ca.conf -extensions v3_ca -in ca.csr -out ca-new.crt -signkey ca.key -days 3650

# (可选)验证新证书
openssl x509 -in ca-new.crt -noout -text

# 确认无误后,用新证书覆盖旧证书
# 再次强调,请确保已备份!
sudo mv ca-new.crt ca.crt

步骤三:续期 Etcd 证书

与续期根 CA 类似,续期组件证书的最佳实践是重用现有的私钥,并从现有证书生成 CSR,以确保主题信息不变。以下以 etcd-server 证书为例,etcd-peerapiserver-etcd-client 的续期流程完全相同。

1. 从现有证书创建 CSR

使用 etcd-server.crtetcd-server.key 生成新的证书签名请求。

1
2
# 确保证书和私钥在当前目录或使用绝对路径
sudo openssl x509 -x509toreq -in etcd-server.crt -signkey etcd-server.key -out etcd-server.csr

2. 准备/验证 OpenSSL 扩展配置文件

Etcd 服务端证书需要一个包含所有节点地址的 SANs 列表。我们可以创建一个 etcd-server.cnf 文件来定义这些扩展属性。

小贴士: 您可以从旧证书中自动提取 SANs 信息来生成此文件,这是最可靠的方法。

1
2
3
4
5
# 1. 查看旧证书的 SANs
openssl x509 -in etcd-server.crt -noout -text | grep -A1 'Subject Alternative Name'

# 2. 根据输出创建 cnf 文件
#    注意:[dn] 部分不再需要,因为 CSR 已包含主题信息

etcd-server.cnf 文件示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]

[v3_req]
subjectAltName = @alt_names

[alt_names]
# --- 将从旧证书查到的 DNS 和 IP 填入这里 ---
DNS.1 = etcd-node1.example.com
DNS.2 = localhost
IP.1 = 192.168.1.11
IP.2 = 127.0.0.1
# -----------------------------------------

3. 签发新证书

使用根 CA、CSR 和扩展配置文件来签发新的 Etcd 证书。

1
2
3
4
5
6
sudo openssl x509 -req -in etcd-server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out etcd-server-new.crt -days 365 \
  -extensions v3_req -extfile etcd-server.cnf

# 验证并替换
sudo mv etcd-server-new.crt etcd-server.crt

步骤四:续期 Master 组件证书

Master 组件(apiserver, controller-manager, scheduler)的证书续期也遵循相同的原则。

1. kube-apiserver 证书

apiserver 的证书续期流程与 Etcd 完全一致,但其 SANs 列表通常更复杂。

  1. 创建 CSR:
    1
    
    sudo openssl x509 -x509toreq -in apiserver.crt -signkey apiserver.key -out apiserver.csr
  2. 准备 apiserver.cnf: apiserver 的 SANs 必须包含所有 Master 节点 IP、主机名、负载均衡器地址以及 kubernetes.default.svc 等。同样,强烈建议从旧证书提取。
    1
    
    openssl x509 -in apiserver.crt -noout -text | grep -A1 'Subject Alternative Name'
  3. 签发新证书:
    1
    2
    3
    4
    5
    
    sudo openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key \
      -CAcreateserial -out apiserver-new.crt -days 365 \
      -extensions v3_req -extfile apiserver.cnf
    
    sudo mv apiserver-new.crt apiserver.crt

2. Controller Manager 和 Scheduler 证书

这两个组件使用的是客户端证书,续期流程更简单。以 controller-manager 为例:

  1. 创建 CSR:
    1
    2
    
    sudo openssl x509 -x509toreq -in kube-controller-manager.crt \
      -signkey kube-controller-manager.key -out kube-controller-manager.csr
  2. 签发新证书: 由于这些是纯客户端证书,通常不需要复杂的扩展。
    1
    2
    3
    4
    
    sudo openssl x509 -req -in kube-controller-manager.csr -CA ca.crt -CAkey ca.key \
      -CAcreateserial -out kube-controller-manager-new.crt -days 365
    
    sudo mv kube-controller-manager-new.crt kube-controller-manager.crt

kube-scheduler 的续期过程完全相同,只需替换相应的文件名。

步骤五:续期 Kubelet 证书

每个节点的 kubelet 证书都是一个客户端证书,其 CN 格式为 system:node:<node-name>。续期操作应在每个 Node 节点上或在管理节点上为每个 Node 单独执行。

  1. 创建 CSR:
    1
    2
    3
    
    # 以 my-worker-node-1 为例
    sudo openssl x509 -x509toreq -in my-worker-node-1.crt \
      -signkey my-worker-node-1.key -out my-worker-node-1.csr
  2. 签发新证书:
    1
    2
    3
    4
    
    sudo openssl x509 -req -in my-worker-node-1.csr -CA ca.crt -CAkey ca.key \
      -CAcreateserial -out my-worker-node-1-new.crt -days 365
    
    sudo mv my-worker-node-1-new.crt my-worker-node-1.crt

步骤六:更新 Kubeconfig 文件

管理员的 kubeconfig (admin.conf) 也需要更新。

1
2
3
4
5
6
7
8
9
# 生成 admin 用户的私钥和 CSR
openssl genrsa -out admin.key 2048
openssl req -new -key admin.key -out admin.csr -subj "/CN=kubernetes-admin/O=system:masters"

# 签发证书
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out admin.crt -days 3650

# 此后,需要使用新生成的 admin.crt 和 admin.key 来创建新的 kubeconfig 文件
# (此步骤通常涉及 `kubectl config set-cluster`, `set-credentials`, `set-context` 命令)

步骤七:分发证书并重启服务

  1. 分发证书:将新生成的 ca.crtetcd-*.crt/keyapiserver.crt/key 等所有新证书和私钥安全地分发到所有相应节点的目标位置,覆盖旧文件。

  2. 重启服务:按照正确的顺序重启所有组件。

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 在所有 Master 节点上
    sudo systemctl restart etcd
    sudo systemctl restart kube-apiserver
    sudo systemctl restart kube-controller-manager
    sudo systemctl restart kube-scheduler
    
    # 在所有 Worker 节点上
    sudo systemctl restart kubelet

步骤八:验证

  1. 检查组件状态
    1
    2
    
    sudo systemctl status etcd kube-apiserver ...
    kubectl get componentstatuses
  2. 检查节点状态
    1
    
    kubectl get nodes
  3. 检查新证书: 再次使用 openssl 检查证书的有效期,确保它们已更新。

总结

为二进制部署的 Kubernetes 集群手动更新证书是一项精确且严谨的工作。整个过程的核心在于保持根 CA 私钥不变,用它生成新的根 CA 证书,并重新签发所有组件证书。务必在操作前进行充分备份,并在操作后进行仔细验证。

0%