手动续订过期的集群证书

本文档介绍如何为 GKE on Bare Metal 手动续订过期的证书。传输层安全协议 (TLS) 证书供 GKE on Bare Metal 的控制平面组件使用。这些证书过期后,您将无法管理工作负载,并且集群生命周期会被阻止,直到证书可以续订为止。如需详细了解过期证书的影响,请参阅证书过期

默认情况下,TLS 证书的有效期为 1 年。GKE on Bare Metal 会在集群升级期间以及轮替证书授权机构时自动续订这些证书。我们建议您定期升级集群,以确保其安全且受支持,并防止 TLS 证书过期。

证书过期导致的错误

如果集群上的 TLS 证书过期,则核心控制器无法与 Kubernetes API 服务器建立 TLS 连接。缺少连接会导致以下错误:

  • Unable to connect to the server: x509: Unable to connect to the server

    使用 kubectl 获取集群节点时,响应中包含一个引用证书过期时间的错误:

    kubectl get nodes --kubeconfig KUBECONFIG_PATH
    

    KUBECONFIG_PATH 替换为集群的 kubeconfig 文件的路径。

    证书过期后,响应会如下所示:

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • could not connect: x509rejected connection

    过期的证书会阻止对 etcd 集群的访问,因为对等方无法相互通信。etcd 日志可能包含如下错误条目:

    W | rafthttp: health check for peer 6221a1d241bb2d0a could not connect: x509: certificate
    has expired or is not yet valid
    I | embed: rejected connection from "10.200.0.4:46108" (error "remote error: tls: bad
    certificate", ServerName "")
    

检查证书过期时间

本部分介绍了如何检查集群使用的证书的过期时间。请在每个控制平面节点上执行以下步骤。

如需检查证书过期时间,请执行以下操作:

  1. 登录其中一个控制平面节点机器,然后运行以下命令:

    sudo kubeadm certs check-expiration
    

    命令输出会列出由 kubeadm 为控制平面组件创建的证书及其过期时间:

    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Nov 28, 2021 19:09 UTC   53m                                     no
    apiserver                  Nov 28, 2021 19:09 UTC   53m             ca                      no
    apiserver-etcd-client      Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    apiserver-kubelet-client   Nov 28, 2021 19:09 UTC   53m             ca                      no
    controller-manager.conf    Nov 28, 2021 19:09 UTC   53m                                     no
    etcd-healthcheck-client    Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-peer                  Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-server                Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    front-proxy-client         Nov 28, 2021 19:09 UTC   53m             front-proxy-ca          no
    scheduler.conf             Nov 28, 2021 19:09 UTC   53m                                     no
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Nov 26, 2031 18:06 UTC   9y              no
    etcd-ca                 Nov 26, 2031 18:06 UTC   9y              no
    front-proxy-ca          Nov 26, 2031 18:06 UTC   9y              no
    
  2. 运行以下命令以检查 kubelet 证书的过期时间:

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    每个命令的响应如以下输出所示:

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    如果同时引导了所有控制平面节点,则证书过期时间彼此之间的间隔不超过几分钟。此时间关系适用于所有控制平面节点。您可以通过在每个控制平面节点上运行上述命令来验证过期时间。

  3. 在管理员工作站上运行以下命令,以检查集群 kubeconfig 文件中的客户端证书的过期时间:

    grep 'client-certificate-data' KUBECONFIG_PATH | \
        awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

    响应如以下示例输出所示:

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    
  4. 运行以下命令以查找管理员集群中的集群 kubeconfig 的证书过期时间:

    kubectl get secret/CLUSTER_NAME-kubeconfig -n CLUSTER_NAMESPACE -o --kubeconfig=ADMIN_KUBECONFIG jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    
    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    管理员集群中的 kubeconfig 证书和管理员工作站上 kubeconfig 文件中的证书相同。因此,此命令的输出与上一步中命令的输出必须匹配。

手动续订证书

如需手动为集群续订 TLS 证书,请按照以下部分中的说明操作。

在每个控制平面节点上续订证书

请在受影响的集群的每个控制平面节点上执行以下步骤:

  1. 备份 /etc/kubernetes 文件夹。

  2. 运行以下 kubeadm 命令以续订所有证书:

    该命令会使用机器上的现有证书授权机构 (CA) 续订证书。

    sudo kubeadm certs renew all
    

    命令输出应如以下示例所示:

    certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
    certificate for serving the Kubernetes API renewed
    certificate the apiserver uses to access etcd renewed
    certificate for the API server to connect to kubelet renewed
    certificate embedded in the kubeconfig file for the controller manager to use renewed
    certificate for liveness probes to healthcheck etcd renewed
    certificate for etcd nodes to communicate with each other renewed
    certificate for serving etcd renewed
    certificate for the front proxy client renewed
    certificate embedded in the kubeconfig file for the scheduler manager to use renewed
    
  3. 通过运行以下命令来验证证书是否有新的过期时间:

    sudo kubeadm certs check-expiration
    
  4. 使用以下命令重启容器:

    并非所有控制平面组件都支持动态证书重新加载,因此此步骤会重启容器 kube-apiserverkube-schedulerkube-controller-manageretcd 来获取续订的证书。

    对四个容器中的每个容器重复以下步骤:

    1. 找到每个容器的 ID:

      sudo crictl ps | grep CONTAINER_NAME
      

      CONTAINER_NAME 替换为容器 kube-apiserverkube-schedulerkube-controller-manageretcd(不是 etcd-defrag)的名称。

      响应如以下输出所示:

      c331ade490cb6       28df10594cd92      26 hours ago       Running          kube-apiserver ...
      

      容器 ID 是第一列中的值。

    2. 停止每个容器:

      sudo crictl stop CONTAINER_ID
      

      CONTAINER_ID 替换为上一步中的容器 ID。

      当已停止的容器退出时,kubelet 会在其位置创建一个新容器,然后删除已停止的容器。如果遇到错误,例如 context deadline exceeded(错误代码 DeadlineExceeded),请重新运行该命令。

验证连接已恢复

此时,应在所有控制平面节点上续订 kubeadm 证书。如果您要续订已过期的证书,请执行以下步骤。

  • 如需验证与 Kubernetes API 服务器的连接,请在任何控制平面节点上运行以下 kubectl 命令:

    kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf
    

响应应返回集群的节点列表。如果您的证书已正确续订,则系统不会返回 TLS 或证书错误。

替换集群 kubeconfig 文件

如需将集群的 kubeconfig 文件替换为包含已续订证书的 kubeconfig 文件,请按照以下步骤操作:

  1. 如需创建新的 kubeconfig 文件,请在管理员工作站上运行以下 kubectl 命令:

    kubectl --kubeconfig="ADMIN_KUBECONFIG" get secret/CLUSTER_NAME-kubeconfig  \
        -n "CLUSTER_NAMESPACE"  -o jsonpath='{.data.value}'  | base64 --decode > new_kubeconfig.conf
    

    替换以下内容:

    • ADMIN_KUBECONFIG:管理员集群 kubeconfig 文件的路径。

    • CLUSTER_NAME:您要为其续订证书的集群的名称。

    • CLUSTER_NAMESPACE:您要为其续订证书的集群的命名空间。

    new_kubeconfig.conf 文件包含更新后的证书数据。

  2. 使用新凭据,通过运行任何 kubectl 命令来验证新 kubeconfig 是否有效:

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  3. 将管理员工作站上集群目录中保存的旧 kubeconfig 文件的内容替换为新 kubeconfig 文件 new-kubeconfig.conf 的内容。

    默认情况下,集群配置文件的路径为 bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig

验证 kubelet 证书并重启 etcd-defrag

如需完成手动续订集群证书的过程,请对每个控制平面节点执行以下步骤:

  1. 登录控制平面节点,然后通过运行以下命令来验证 kubelet 客户端和服务证书过期时间:

    只要控制平面可访问,Kubelet 证书就会自动轮替。kubelet 证书的自动续订期比控制平面组件证书的有效期短。因此,kubelet 证书之前可能已经续订

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    任一命令的输出如以下示例所示:

    Validity
        Not Before: Nov 28 18:04:57 2022 GMT
        Not After : Nov 28 19:04:57 2023 GMT
    
  2. 使用以下命令重启 etcd-defrag 容器:

    etcd-defrag 容器使用 apiserver-etcd 客户端证书与 etcd 通信,并且必须重启才能获取更新后的证书。

    kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
    

您已完成续订集群证书的手动步骤。验证所有 pod 是否正常运行,以及系统是否未报告控制平面容器的 TLS 错误。