CA 證書的手動輪換

本頁面介紹如何手動輪換證書頒發機構(CA)證書。

準備工作

你需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議你在至少有兩個非控制平面主機節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 教程環境之一。

  • 有關 Kubernetes 認證的更多資訊,請參閱 身份認證
  • 有關 CA 證書最佳實踐的更多資訊,請參閱 單一根 CA

手動輪換 CA 證書

  1. 將新的 CA 證書和私鑰(例如:ca.crtca.keyfront-proxy-ca.crtfront-proxy-ca.key)分發到所有控制平面節點上的 Kubernetes 證書目錄。

  2. 更新 kube-controller-manager--root-ca-file 標誌,以同時包含舊 CA 和新 CA,然後重啟 kube-controller-manager。

    此後建立的任何 ServiceAccount 都將獲取包含舊 CA 和新 CA 的 Secret。

  3. 等待控制器管理器更新服務賬號 Secret 中的 ca.crt,使其包含舊 CA 證書和新 CA 證書。

    如果在 API 伺服器使用新 CA 之前啟動了任何 Pod,則這些新 Pod 將獲得此更新並信任舊 CA 和新 CA。

  4. 重啟所有使用叢集內配置的 Pod(例如:kube-proxy、CoreDNS 等),以便它們可以使用連結到 ServiceAccount 的 Secret 中更新的證書頒發機構資料。

    • 確保 CoreDNS、kube-proxy 和其他使用叢集內配置的 Pod 正常工作。
  5. 將舊 CA 和新 CA 都新增到 kube-apiserver 配置中 --client-ca-file--kubelet-certificate-authority 標誌所指向的檔案中。

  6. 將舊 CA 和新 CA 都新增到 kube-scheduler 配置中 --client-ca-file 標誌所指向的檔案中。

  7. 透過分別替換 client-certificate-dataclient-key-data 的內容來更新使用者賬號的證書。

    有關為單個使用者賬號建立證書的資訊,請參閱 為使用者賬號配置證書

    此外,更新 kubeconfig 檔案中的 certificate-authority-data 部分,分別使用 Base64 編碼的舊證書頒發機構資料和新證書頒發機構資料。

  8. 更新 雲控制器管理器--root-ca-file 標誌,以同時包含舊 CA 和新 CA,然後重啟雲控制器管理器。

  9. 按滾動方式執行以下步驟。

    1. 重啟任何其他 聚合 API 伺服器 或 Webhook 處理程式,以信任新的 CA 證書。

    2. 透過更新所有節點上 kubelet 配置中的 clientCAFile 標誌所指向的檔案以及 kubelet.conf 中的 certificate-authority-data,以使用舊 CA 和新 CA,從而重啟 kubelet。

      如果你的 kubelet 未使用客戶端證書輪換,請更新所有節點上 kubelet.conf 中的 client-certificate-dataclient-key-data,以及通常位於 /var/lib/kubelet/pki 的 kubelet 客戶端證書檔案。

    3. 使用由新 CA 簽名的證書(apiserver.crtapiserver-kubelet-client.crtfront-proxy-client.crt)重啟 API 伺服器。你可以使用現有的私鑰或新的私鑰。如果更改了私鑰,請同時在 Kubernetes 證書目錄中更新它們。

      由於叢集中的 Pod 信任舊 CA 和新 CA,因此在 Pod 的 Kubernetes 客戶端重新連線到新的 API 伺服器後,將出現短暫的斷開連線。新的 API 伺服器使用由新 CA 簽名的證書。

      • 重啟 kube-scheduler,使其使用並信任新的 CA。
      • 確保控制平面元件日誌中沒有 TLS 錯誤。
    4. 標註任何 DaemonSet 和 Deployment,以更安全地觸發 Pod 的滾動替換。

    for namespace in $(kubectl get namespace -o jsonpath='{.items[*].metadata.name}'); do
        for name in $(kubectl get deployments -n $namespace -o jsonpath='{.items[*].metadata.name}'); do
            kubectl patch deployment -n ${namespace} ${name} -p '{"spec":{"template":{"metadata":{"annotations":{"ca-rotation": "1"}}}}}';
        done
        for name in $(kubectl get daemonset -n $namespace -o jsonpath='{.items[*].metadata.name}'); do
            kubectl patch daemonset -n ${namespace} ${name} -p '{"spec":{"template":{"metadata":{"annotations":{"ca-rotation": "1"}}}}}';
        done
    done
    
     Depending on how you use StatefulSets you may also need to perform similar rolling replacement.
    
  10. 如果你的叢集使用引導令牌加入節點,請使用新的 CA 更新 kube-public 名稱空間中的 ConfigMap cluster-info

    base64_encoded_ca="$(base64 -w0 /etc/kubernetes/pki/ca.crt)"
    
    kubectl get cm/cluster-info --namespace kube-public -o yaml | \
        /bin/sed "s/\(certificate-authority-data:\).*/\1 ${base64_encoded_ca}/" | \
        kubectl apply -f -
    
  11. 驗證叢集功能。

    1. 檢查控制平面元件以及 kubelet 和 kube-proxy 的日誌。確保這些元件沒有報告任何 TLS 錯誤;有關更多詳細資訊,請參閱 檢視日誌

    2. 驗證任何聚合 API 伺服器和使用叢集內配置的 Pod 的日誌。

  12. 一旦叢集功能成功驗證

    1. 更新所有服務賬號令牌,使其只包含新的 CA 證書。

      • 所有使用叢集內 kubeconfig 的 Pod 最終都需要重啟以獲取新的 Secret,這樣就沒有 Pod 依賴舊的叢集 CA 了。
    2. 透過分別從 kubeconfig 檔案以及 --client-ca-file--root-ca-file 標誌所指向的檔案中移除舊 CA 來重啟控制平面元件。

    3. 在每個節點上,透過從 clientCAFile 標誌所指向的檔案以及 kubelet kubeconfig 檔案中移除舊 CA 來重啟 kubelet。你應該以滾動更新的方式執行此操作。

      如果你的叢集允許你進行此更改,你也可以透過替換節點而不是重新配置它們來推出。

上次修改時間:2022 年 4 月 14 日下午 2:47 (太平洋標準時間):刪除手動更新服務帳戶 Secret 的不必要步驟 (b1a5f31dd5)