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,然後重新啟動 kube-controller-manager。

    在此時間點之後建立的任何服務帳戶都將取得包含舊的和新的 CA 的密鑰。

  3. 等待控制器管理器更新服務帳戶密鑰中的 ca.crt,以包含舊的和新的 CA 憑證。

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

  4. 重新啟動所有使用叢集內配置的 Pod (例如:kube-proxy、CoreDNS 等),以便它們可以使用來自連結到 ServiceAccount 的密鑰的更新憑證授權機構資料。

    • 確保 CoreDNS、kube-proxy 和其他使用叢集內配置的 Pod 運作正常。
  5. 將舊的和新的 CA 都附加到 kube-apiserver 配置中針對 --client-ca-file--kubelet-certificate-authority 旗標的檔案。

  6. 將舊的和新的 CA 都附加到 kube-scheduler 配置中針對 --client-ca-file 旗標的檔案。

  7. 更新使用者帳戶的憑證,方法是分別替換 client-certificate-dataclient-key-data 的內容。

    如需建立個別使用者帳戶憑證的相關資訊,請參閱設定使用者帳戶憑證

    此外,請更新 kubeconfig 檔案中的 certificate-authority-data 區段,分別使用 Base64 編碼的舊版和新版憑證授權單位資料。

  8. 更新雲端控制器管理員--root-ca-file 標記,以同時包含舊版和新版 CA,然後重新啟動 cloud-controller-manager。

  9. 請以滾動方式按照以下步驟操作。

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

    2. 透過更新 kubelet 組態中的 clientCAFile 檔案,以及 kubelet.conf 中的 certificate-authority-data,以在所有節點上同時使用舊版和新版 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,因此在 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 PST:移除不必要的手動更新服務帳戶密鑰的步驟 (b1a5f31dd5)