傳輸層安全標準 (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 validcould 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 "")
查看憑證到期時間
如要檢查憑證到期時間,請在每個控制層節點上執行下列步驟:
登入其中一部控制層節點機器,然後執行下列指令:
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執行下列指令,檢查
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如果所有控制層節點都同時啟動,憑證到期時間就會相差幾分鐘。這項時間關係適用於所有控制層節點。您可以在每個控制層節點上執行上述指令,驗證到期時間。
在管理員工作站執行下列指令,檢查叢集 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執行下列指令,查詢管理員叢集中叢集 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 憑證,請按照下列各節的說明操作。
更新每個控制層節點上的憑證
在受影響叢集的每個控制層節點上,執行下列步驟:
備份
/etc/kubernetes資料夾。執行下列
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執行下列指令,確認憑證有新的到期時間:
sudo kubeadm certs check-expiration並非所有控制層元件都支援動態重新載入憑證。為取得更新後的憑證,請按照下列步驟重新啟動
kube-apiserver、kube-scheduler和kube-controller-manager容器。對四個容器分別重複下列步驟:
找出每個容器的容器 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 是第一欄中的值。
停止各個容器:
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,請在控制層節點上執行下列步驟:
使用
sed將admin.conf檔案中的kubernetes替換為叢集名稱,並將變更寫入新檔案kubeconfig_secret.conf:sed "s/kubernetes/CLUSTER_NAME/g" \ /etc/kubernetes/admin.conf > /etc/kubernetes/kubeconfig_secret.conf使用
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執行下列指令,更新叢集中的 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 檔案替換為含有更新憑證的檔案,請按照下列步驟操作:
將
admin.conf檔案從其中一個叢集控制層節點複製到管理員工作站。如前幾節所述,
admin.conf檔案位於叢集控制層節點的etc/kubernetes目錄中。如要建立新的 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檔案包含更新後的憑證資料。使用新憑證執行任何
kubectl指令,確認新的 kubeconfig 是否正常運作:kubectl get nodes --kubeconfig new_kubeconfig.conf將儲存在管理員工作站叢集目錄中的舊 kubeconfig 檔案內容,替換為新 kubeconfig 檔案
new-kubeconfig.conf的內容。根據預設,叢集設定檔的路徑為
bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig。
驗證 kubelet 憑證並重新啟動 etcd-defrag
如要手動完成叢集憑證更新程序,請對每個控制層節點執行下列步驟:
登入控制層節點,然後執行下列指令,驗證 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使用下列指令重新啟動
etcd-defrag容器:etcd-defrag容器會使用apiserver-etcd用戶端憑證與 etcd 通訊,因此必須重新啟動,才能採用更新後的憑證。kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
完成這些手動步驟來更新叢集憑證後,請確認所有 Pod 都正常運作,且控制層容器未回報任何 TLS 錯誤。
後續步驟
如需其他協助,請與 Cloud Customer Care 團隊聯絡。您也可以參閱「取得支援」,進一步瞭解支援資源,包括: