溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Kubernetes集群證書被全部刪除后怎么修復

發(fā)布時間:2021-06-23 09:43:18 來源:億速云 閱讀:516 作者:chen 欄目:云計算

本篇內容介紹了“Kubernetes集群證書被全部刪除后怎么修復”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Kubernetes 是一個很牛很牛的平臺,Kubernetes 的架構可以讓你輕松應對各種故障,今天我們將來破壞我們的集群、刪除證書,然后再想辦法恢復我們的集群,進行這些危險的操作而不會對已經(jīng)運行的服務造成宕機。

如果你真的想要執(zhí)行接下來的操作,還是建議別在生產環(huán)境去折騰,雖然理論上不會造成服務宕機,但是如果出現(xiàn)了問題,可千萬別罵我~~~

我們知道 Kubernetes 的控制平面是由幾個組件組成的:

  • etcd:作為整個集群的數(shù)據(jù)庫使用

  • kube-apiserver:集群的 API 服務

  • kube-controller-manager:整個集群資源的控制操作

  • kube-scheduler:核心調度器

  • kubelet:是運行在節(jié)點上用來真正管理容器的組件

這些組件都由一套針對客戶端和服務端的 TLS 證書保護,用于組件之間的認證和授權,大部分情況下它們并不是直接存儲在 Kubernetes 的數(shù)據(jù)庫中的,而是以普通文件的形式存在。

# 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

控制面板的組件以靜態(tài) Pod (我這里用 kubeadm 搭建的集群)的形式運行在 master 節(jié)點上,默認資源清單位于 /etc/kubernetes/manifests 目錄下。通常來說這些組件之間會進行互相通信,基本流程如下所示:

Kubernetes集群證書被全部刪除后怎么修復

組件之間為了通信,他們需要使用到 TLS 證書。假設我們已經(jīng)有了一個部署好的集群,接下來讓我們開始我們的破壞行為。

rm -rf /etc/kubernetes/

在 master 節(jié)點上,這個目錄包含:

  • 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 的靜態(tài) Pod 資源清單文件(位于 /etc/kubernetes/manifests 目錄)

現(xiàn)在我們就上面這些全都刪除了,如果是在生產環(huán)境做了這樣的操作,可能你現(xiàn)在正瑟瑟發(fā)抖吧~

修復控制平面

首先我也確保下我們的所有控制平面 Pod 已經(jīng)停止了。

# 如果你用 docker 也是可以的crictl rm `crictl ps -aq`

注意:kubeadm 默認不會覆蓋現(xiàn)有的證書和 kubeconfigs,為了重新頒發(fā)證書,你必須先手動刪除舊的證書。

接下來我們首先恢復 etcd,執(zhí)行下面的命令生成 etcd 集群的證書:

kubeadm init phase certs etcd-ca

上面的命令將為我們的 etcd 集群生成一個新的 CA,由于所有其他證書都必須由它來簽署,我們也將把它和私鑰復制到其他 master 節(jié)點(如果你是多 master)。

/etc/kubernetes/pki/etcd/ca.{key,crt}

接下來讓我們在所有 master 節(jié)點上為它重新生成其余的 etcd 證書和靜態(tài)資源清單。

kubeadm init phase certs etcd-healthcheck-client
kubeadm init phase certs etcd-peer
kubeadm init phase certs etcd-server
kubeadm init phase etcd local

上面的命令執(zhí)行后,你應該已經(jīng)有了一個正常工作的 etcd 集群了。

# crictl psCONTAINER ID        IMAGE               CREATED             STATE               NAME                ATTEMPT             POD IDac82b4ed5d83a       0369cf4303ffd       2 seconds ago       Running             etcd                0                   bc8b4d568751b

接下來我們對 Kubernetes 服務做同樣的操作,在其中一個 master 節(jié)點上執(zhí)行如下的命令:

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 服務的靜態(tài) Pods 清單和 kubeconfigs 文件。

如果你使用 kubeadm 加入 kubelet,你還需要更新 kube-public 命名空間中的 cluster-info 配置,因為它仍然包含你的舊 CA 的哈希值。

kubeadm init phase bootstrap-token

由于其他 master 節(jié)點上的所有證書也必須由單一 CA 簽署,所以我們將其復制到其他控制面節(jié)點,并在每個節(jié)點上重復上述命令。

/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 節(jié)點:

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 會自動更新它。到在這個階段,我們已經(jīng)有了一個完整的控制平面了。

修復工作節(jié)點

現(xiàn)在我們可以使用下面的命令列出集群的所有節(jié)點:

kubectl get nodes

當然正常現(xiàn)在所有節(jié)點的狀態(tài)都是 NotReady,這是因為他們仍然還使用的是舊的證書,為了解決這個問題,我們將使用 kubeadm 來執(zhí)行重新加入集群節(jié)點。

systemctl stop kubelet
rm -rf /var/lib/kubelet/pki/ /etc/kubernetes/kubelet.conf
kubeadm init phase kubeconfig kubelet
kubeadm init phase kubelet-start

但要加入工作節(jié)點,我們必須生成一個新的 token。

kubeadm token create --print-join-command

然后在工作節(jié)點分別執(zhí)行下面的命令:

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 節(jié)點上的 /etc/kubernetes/pki 目錄,因為它已經(jīng)包含了所有需要的證書。

上面的操作會把你所有的 kubelet 重新加入到集群中,它并不會影響任何已經(jīng)運行在上面的容器,但是,如果集群中有多個節(jié)點并且不同時進行,則可能會遇到一種情況,即 kube-controller-mananger 開始從 NotReady 節(jié)點重新創(chuàng)建容器,并嘗試在活動節(jié)點上重新調度它們。

為了防止這種情況,我們可以暫時停掉 master 節(jié)點上的 controller-manager。

rm /etc/kubernetes/manifests/kube-controller-manager.yaml
crictl rmp `crictl ps --name kube-controller-manager -q`

一旦集群中的所有節(jié)點都被加入,你就可以為 controller-manager 生成一個靜態(tài)資源清單,在所有 master 節(jié)點上運行下面的命令。

kubeadm init phase control-plane controller-manager

如果 kubelet 被配置為請求由你的 CA 簽署的證書(選項serverTLSBootstrap: true),你還需要批準來自 kubelet 的 CSR:

kubectl get csr
kubectl certificate approve <csr>

修復 ServiceAccounts

因為我們丟失了 /etc/kubernetes/pki/sa.key ,這個 key 用于為集群中所有 ServiceAccounts 簽署 jwt tokens,因此,我們必須為每個 sa 重新創(chuàng)建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 命名空間執(zhí)行,因為 kube-proxy 和 CNI 插件都安裝在這個命名空間中,它們對于處理你的微服務之間的通信至關重要。

到這里我們的集群就恢復完成了。

“Kubernetes集群證書被全部刪除后怎么修復”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI