手動續訂過期的叢集憑證

本文說明如何手動續訂 Google Distributed Cloud 的過期憑證。Google Distributed Cloud 的控制層元件會使用傳輸層安全標準 (TLS) 憑證。這些憑證過期後,您將無法管理工作負載和叢集生命週期,直到憑證續約為止。如要進一步瞭解憑證過期的影響,請參閱「憑證到期」。

本頁內容適用於管理基礎技術架構生命週期,以及在服務等級目標 (SLO) 未達成或應用程式失敗時,回應快訊和頁面的管理員、架構師和營運人員。如要進一步瞭解內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。 Google Cloud

根據預設,TLS 憑證 (包括 etcd 憑證) 的效期為 1 年。Google Distributed Cloud 會在叢集升級期間和您輪替憑證授權單位時,更新這些憑證。這些憑證不會自行定期更新。建議您定期升級叢集,確保叢集安全無虞、受到支援,並防止 TLS 憑證過期。

憑證過期導致的錯誤

如果叢集上的 TLS 憑證過期,核心控制器就無法與 Kubernetes API 伺服器建立 TLS 連線。連線中斷會導致下列錯誤:

  • 無法連線至伺服器:x509

    使用 kubectl 取得叢集節點時,回應會包含憑證已過期的錯誤,類似於下列範例輸出內容:

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • 無法連線:x509連線遭拒

    憑證過期會導致無法存取 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 \
      --kubeconfig=ADMIN_KUBECONFIG \
      -o jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

    更改下列內容:

    * ADMIN_KUBECONFIG: the
      path to the admin cluster kubeconfig file.
    
    * CLUSTER_NAME:
      the name of the cluster that you're renewing certificates for.
    
    * CLUSTER_NAMESPACE:
      the namespace of the cluster that you're renewing certificates for.
    

    回應類似下列輸出範例:

    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 密鑰

admin.conf 檔案的內容更新 kubeconfig 密鑰。

如要將新的 kubeconfig 更新至密鑰,請在控制層節點上執行下列指令:

CLUSTER_KUBECONFIG_BASE64=$(base64 /etc/kubernetes/admin.conf -w 0)

kubectl get secret/CLUSTER_NAME-kubeconfig \
  -n CLUSTER_NAMESPACE \
  –kubeconfig /etc/kubernetes/admin.conf -o json | jq \
  --arg conf "${CLUSTER_KUBECONFIG_BASE64}" '.data."value" |= $conf' | kubectl apply -f - 

取代叢集 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 錯誤。

後續步驟

如需其他協助,請與 Cloud Customer Care 團隊聯絡。如要進一步瞭解支援資源,包括下列項目,請參閱「取得支援」: