您好,登錄后才能下訂單哦!
本篇內容介紹了“Kubernetes集群證書被全部刪除后怎么修復”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Kubernetes 是一個很牛很牛的平臺,Kubernetes 的架構可以讓你輕松應對各種故障,今天我們將來破壞我們的集群、刪除證書,然后再想辦法恢復我們的集群,進行這些危險的操作而不會對已經運行的服務造成宕機。
如果你真的想要執行接下來的操作,還是建議別在生產環境去折騰,雖然理論上不會造成服務宕機,但是如果出現了問題,可千萬別罵我~~~
我們知道 Kubernetes 的控制平面是由幾個組件組成的:
etcd:作為整個集群的數據庫使用
kube-apiserver:集群的 API 服務
kube-controller-manager:整個集群資源的控制操作
kube-scheduler:核心調度器
kubelet:是運行在節點上用來真正管理容器的組件
這些組件都由一套針對客戶端和服務端的 TLS 證書保護,用于組件之間的認證和授權,大部分情況下它們并不是直接存儲在 Kubernetes 的數據庫中的,而是以普通文件的形式存在。
# tree /etc/kubernetes/pki//etc/kubernetes/pki/ ├── apiserver.crt ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key ├── apiserver.key ├── apiserver-kubelet-client.crt ├── apiserver-kubelet-client.key ├── ca.crt ├── ca.key ├── CTNCA.pem ├── etcd │ ├── ca.crt │ ├── ca.key │ ├── healthcheck-client.crt │ ├── healthcheck-client.key │ ├── peer.crt │ ├── peer.key │ ├── server.crt │ └── server.key ├── front-proxy-ca.crt ├── front-proxy-ca.key ├── front-proxy-client.crt ├── front-proxy-client.key ├── sa.key └── sa.pub
控制面板的組件以靜態 Pod (我這里用 kubeadm 搭建的集群)的形式運行在 master 節點上,默認資源清單位于 /etc/kubernetes/manifests
目錄下。通常來說這些組件之間會進行互相通信,基本流程如下所示:
組件之間為了通信,他們需要使用到 TLS 證書。假設我們已經有了一個部署好的集群,接下來讓我們開始我們的破壞行為。
rm -rf /etc/kubernetes/
在 master 節點上,這個目錄包含:
etcd 的一組證書和 CA(在 /etc/kubernetes/pki/etcd
目錄下)
一組 kubernetes 的證書和 CA(在 /etc/kubernetes/pki
目錄下)
還有 kube-controller-manager、kube-scheduler、cluster-admin 以及 kubelet 這些使用的 kubeconfig 文件
etcd、kube-apiserver、kube-scheduler 和 kube-controller-manager 的靜態 Pod 資源清單文件(位于 /etc/kubernetes/manifests
目錄)
現在我們就上面這些全都刪除了,如果是在生產環境做了這樣的操作,可能你現在正瑟瑟發抖吧~
首先我也確保下我們的所有控制平面 Pod 已經停止了。
# 如果你用 docker 也是可以的crictl rm `crictl ps -aq`
注意:kubeadm 默認不會覆蓋現有的證書和 kubeconfigs,為了重新頒發證書,你必須先手動刪除舊的證書。
接下來我們首先恢復 etcd,執行下面的命令生成 etcd 集群的證書:
kubeadm init phase certs etcd-ca
上面的命令將為我們的 etcd 集群生成一個新的 CA,由于所有其他證書都必須由它來簽署,我們也將把它和私鑰復制到其他 master 節點(如果你是多 master)。
/etc/kubernetes/pki/etcd/ca.{key,crt}
接下來讓我們在所有 master 節點上為它重新生成其余的 etcd 證書和靜態資源清單。
kubeadm init phase certs etcd-healthcheck-client kubeadm init phase certs etcd-peer kubeadm init phase certs etcd-server kubeadm init phase etcd local
上面的命令執行后,你應該已經有了一個正常工作的 etcd 集群了。
# crictl psCONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD IDac82b4ed5d83a 0369cf4303ffd 2 seconds ago Running etcd 0 bc8b4d568751b
接下來我們對 Kubernetes 服務做同樣的操作,在其中一個 master 節點上執行如下的命令:
kubeadm init phase certs all kubeadm init phase kubeconfig all kubeadm init phase control-plane all cp -f /etc/kubernetes/admin.conf ~/.kube/config
上面的命令將生成 Kubernetes 的所有 SSL 證書,以及 Kubernetes 服務的靜態 Pods 清單和 kubeconfigs 文件。
如果你使用 kubeadm 加入 kubelet,你還需要更新 kube-public
命名空間中的 cluster-info 配置,因為它仍然包含你的舊 CA 的哈希值。
kubeadm init phase bootstrap-token
由于其他 master 節點上的所有證書也必須由單一 CA 簽署,所以我們將其復制到其他控制面節點,并在每個節點上重復上述命令。
/etc/kubernetes/pki/{ca,front-proxy-ca}.{key,crt} /etc/kubernetes/pki/sa.{key,pub}
順便說一下,作為手動復制證書的替代方法,你也可以使用 Kubernetes API,如下所示的命令:
kubeadm init phase upload-certs --upload-certs
該命令將加密并上傳證書到 Kubernetes,時間為2小時,所以你可以按以下方式注冊 master 節點:
kubeadm join phase control-plane-prepare all kubernetes-apiserver:6443 --control-plane --token cs0etm.ua7fbmwuf1jz946l --discovery-token-ca-cert-hash sha256:555f6ececd4721fed0269d27a5c7f1c6d7ef4614157a18e56ed9a1fd031a3ab8 --certificate-key 385655ee0ab98d2441ba8038b4e8d03184df1806733eac131511891d1096be73 kubeadm join phase control-plane-join all
需要注意的是,Kubernetes API 還有一個配置,它為 front-proxy
客戶端持有 CA 證書,它用于驗證從 apiserver 到 webhooks 和聚合層服務的請求。不過 kube-apiserver 會自動更新它。到在這個階段,我們已經有了一個完整的控制平面了。
現在我們可以使用下面的命令列出集群的所有節點:
kubectl get nodes
當然正常現在所有節點的狀態都是 NotReady,這是因為他們仍然還使用的是舊的證書,為了解決這個問題,我們將使用 kubeadm 來執行重新加入集群節點。
systemctl stop kubelet rm -rf /var/lib/kubelet/pki/ /etc/kubernetes/kubelet.conf kubeadm init phase kubeconfig kubelet kubeadm init phase kubelet-start
但要加入工作節點,我們必須生成一個新的 token。
kubeadm token create --print-join-command
然后在工作節點分別執行下面的命令:
systemctl stop kubelet rm -rf /var/lib/kubelet/pki/ /etc/kubernetes/pki/ /etc/kubernetes/kubelet.conf kubeadm join phase kubelet-start kubernetes-apiserver:6443 --token cs0etm.ua7fbmwuf1jz946l --discovery-token-ca-cert-hash sha256:555f6ececd4721fed0269d27a5c7f1c6d7ef4614157a18e56ed9a1fd031a3ab8
注意:你不需要刪除 master 節點上的
/etc/kubernetes/pki
目錄,因為它已經包含了所有需要的證書。
上面的操作會把你所有的 kubelet 重新加入到集群中,它并不會影響任何已經運行在上面的容器,但是,如果集群中有多個節點并且不同時進行,則可能會遇到一種情況,即 kube-controller-mananger 開始從 NotReady 節點重新創建容器,并嘗試在活動節點上重新調度它們。
為了防止這種情況,我們可以暫時停掉 master 節點上的 controller-manager。
rm /etc/kubernetes/manifests/kube-controller-manager.yaml crictl rmp `crictl ps --name kube-controller-manager -q`
一旦集群中的所有節點都被加入,你就可以為 controller-manager 生成一個靜態資源清單,在所有 master 節點上運行下面的命令。
kubeadm init phase control-plane controller-manager
如果 kubelet 被配置為請求由你的 CA 簽署的證書(選項serverTLSBootstrap: true),你還需要批準來自 kubelet 的 CSR:
kubectl get csr kubectl certificate approve <csr>
因為我們丟失了 /etc/kubernetes/pki/sa.key
,這個 key 用于為集群中所有 ServiceAccounts
簽署 jwt tokens
,因此,我們必須為每個 sa 重新創建tokens。
這可以通過類型為 kubernetes.io/service-account-token
的 Secret 中刪除 token 字段來完成。
kubectl get secret --all-namespaces | awk '/kubernetes.io\/service-account-token/ { print "kubectl patch secret -n " $1 " " $2 " -p {\\\"data\\\":{\\\"token\\\":null}}"}' | sh -x
刪除之后,kube-controller-manager 會自動生成用新密鑰簽名的新令牌。不過需要注意的是并非所有的微服務都能即時更新 tokens,因此很可能需要手動重新啟動使用 tokens 的容器。
kubectl get pod --field-selector 'spec.serviceAccountName!=default' --no-headers --all-namespaces | awk '{print "kubectl delete pod -n " $1 " " $2 " --wait=false --grace-period=0"}'
例如,這個命令會生成一個命令列表,會將所有使用非默認的 serviceAccount 的 Pod 刪除,我建議從 kube-system 命名空間執行,因為 kube-proxy 和 CNI 插件都安裝在這個命名空間中,它們對于處理你的微服務之間的通信至關重要。
到這里我們的集群就恢復完成了。
“Kubernetes集群證書被全部刪除后怎么修復”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。