手動續約過期的叢集憑證

傳輸層安全標準 (TLS) 憑證到期時,您可以手動更新憑證,還原 Google Distributed Cloud 的控制層作業。必須更新過期的 TLS 憑證,才能管理工作負載和叢集生命週期。如要進一步瞭解憑證到期的影響,請參閱「憑證到期」。

TLS 憑證 (包括 etcd 憑證) 的預設到期期限為 1 年,且不會自動更新。為避免憑證過期,並確保叢集安全無虞且受到支援,建議您定期升級叢集。Google Distributed Cloud 會在叢集升級和輪替憑證授權單位時更新這些憑證。如果憑證在升級前失效,您可以按照這項指南復原叢集。如需相關詳細資料,請參閱「常見的 GKE 使用者角色和工作」。

憑證過期導致的錯誤

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

  • Unable to connect to the server: x509

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

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • could not connect: x509 或 rejected 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 \
        --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:管理員叢集 kubeconfig 檔案的路徑。

    • CLUSTER_NAME:要更新憑證的叢集名稱。

    • CLUSTER_NAMESPACE:要更新憑證的叢集命名空間。

    回應內容大致如下:

    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-apiserver、kube-scheduler 和 kube-controller-manager 容器。

    對四個容器分別重複下列步驟:

    1. 找出每個容器的容器 ID:

      sudo crictl ps | grep CONTAINER_NAME
      

      將 CONTAINER_NAME 替換為下列容器的名稱:kube-apiserver、kube-scheduler 或 kube-controller-manager。

      回應大致如下:

      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 密鑰。不過,更新後的 admin.conf 檔案內容無法直接使用。您必須先複製 admin.conf 檔案,並進行一些必要編輯。

如要將新的 kubeconfig 更新至 Secret,請在控制層節點上執行下列步驟:

  1. 使用 sed 將 admin.conf 檔案中的 kubernetes 替換為叢集名稱,並將變更寫入新檔案 kubeconfig_secret.conf:

    sed "s/kubernetes/CLUSTER_NAME/g" \
        /etc/kubernetes/admin.conf > /etc/kubernetes/kubeconfig_secret.conf
    
  2. 使用 diff 確認 kubeconfig_secret.conf 檔案已更新:

    diff /etc/kubernetes/admin.conf /etc/kubernetes/kubeconfig_secret.conf
    

    回應會顯示 kubeconfig_secret.conf 檔案與更新後的 admin.conf 檔案不同的所有位置。舉例來說,如果您對名為 demo-cluster 的叢集執行上述步驟,輸出內容會類似下列內容:

    6c6
    <   name: kubernetes
    ---
    >   name: demo-cluster
    9,12c9,12
    <     cluster: kubernetes
    <     user: kubernetes-admin
    <   name: kubernetes-admin@kubernetes
    < current-context: kubernetes-admin@kubernetes
    ---
    >     cluster: demo-cluster
    >     user: demo-cluster-admin
    >   name: demo-cluster-admin@demo-cluster
    > current-context: demo-cluster-admin@demo-cluster
    16c16
    < - name: kubernetes-admin
    ---
    > - name: demo-cluster-admin
    
  3. 執行下列指令,更新叢集中的 kubeconfig 密鑰:

    CLUSTER_KUBECONFIG_BASE64=$(base64 /etc/kubernetes/kubeconfig_secret.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 \
        --kubeconfig /etc/kubernetes/admin.conf -f -
    

取代叢集 kubeconfig 檔案

如要將叢集的 kubeconfig 檔案替換為含有更新憑證的檔案,請按照下列步驟操作:

  1. 將 admin.conf 檔案從其中一個叢集控制層節點複製到管理員工作站。

    如前幾節所述,admin.conf 檔案位於叢集控制層節點的 etc/kubernetes 目錄中。

  2. 如要建立新的 kubeconfig 檔案,請在管理員工作站上執行下列 kubectl 指令:

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

    更改下列內容:

    • ADMIN_CONF_PATH:從控制層節點複製到管理員工作站的 admin.conf 檔案路徑。

    • CLUSTER_NAME:要更新憑證的叢集名稱。

    • CLUSTER_NAMESPACE:要更新憑證的叢集命名空間。

    new_kubeconfig.conf 檔案包含更新後的憑證資料。

  3. 使用新憑證執行任何 kubectl 指令,確認新的 kubeconfig 是否正常運作:

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  4. 將儲存在管理員工作站叢集目錄中的舊 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 團隊聯絡。您也可以參閱「取得支援」,進一步瞭解支援資源,包括:

  • 建立客服案件的需求條件。
  • 工具:協助您疑難排解,例如您的環境設定、記錄和指標。
  • 支援的元件。