誤刪節點或叢集怎麼辦?這裡有一顆後悔藥
阿新 • • 發佈:2020-07-15
本文來自[Rancher Labs](https://mp.weixin.qq.com/s/XDgo-3cPbNTB8GvKn5ZptA "Rancher Labs")
>作者介紹
>
>王海龍,Rancher中國社群技術經理,負責Rancher中國技術社群的維護和運營。擁有6年的雲端計算領域經驗,經歷了OpenStack到Kubernetes的技術變革,無論底層作業系統Linux,還是虛擬化KVM或是Docker容器技術都有豐富的運維和實踐經驗。
在實際使用Rancher過程中,偶爾會因為誤操作刪除了System Workload、節點或叢集, 導致叢集狀態異常而無法訪問。如果使用者不瞭解恢復方法,通常會重新新增節或重新搭建叢集。
本文將根據以下幾個場景來介紹如何恢復由於誤操作引起的Rancher叢集故障:
- 如何恢復System Project Workload
- 如何恢復從Rancher UI或kubectl誤刪的節點
- 如何恢復執行過清理節點指令碼的節點
- 如何恢復被刪除的`custom`叢集
## 重要說明
- 本文件基於Rancher 2.4.x測試,其他版本操作可能會略有不同
- 本文介紹的場景均是針對`custom`叢集
- 如果您在此過程中遇到問題,則應該熟悉Rancher架構/故障排除
- 您應該熟悉單節點安裝和高可用安裝之間的體系結構差異
## 如何恢復System Project Workload
System Project中包含了一些保證該叢集能夠正常執行的一些workload,如果刪除某些workload可能會對該集功能群造成影響。
通常情況下,通過RKE建立的`custom`叢集應包括以下workload:
![](https://oscimg.oschina.net/oscnet/up-cb6973129ebd2676ac280eb77e3fd1bc9fa.JPEG)
下面我們來分別介紹如果誤刪了這些workload之後應如何恢復。
### 恢復`cattle-cluster-agent`和`cattle-node-agent`
**模擬故障**
從System Project下刪除` cattle-cluster-agent`和`cattle-node-agent`
![](https://oscimg.oschina.net/oscnet/up-89169ffee0327b90928fdcc5b67e2f85313.JPEG)
**生成Kubeconfig和叢集yaml**
1.在Rancher UI上建立API token(使用者-> API & Keys)並儲存`Bearer Token`
![](https://oscimg.oschina.net/oscnet/up-7918fb11e3cbe20d993f0abc266ffdeeeb3.JPEG)
2.選擇集群后,在Rancher UI(格式為c-xxxxx)中找到其clusterid,並在位址列中找到它。
![](https://oscimg.oschina.net/oscnet/up-c6a5f945fc6dbd85e02459d73433ad72cf6.JPEG)
3.根據步驟1-2獲取的變數替換:`RANCHERURL`、`CLUSTERID`、`TOKEN`(主機需要安裝curl和jq)
```
# Rancher URL
RANCHERURL="https://192.168.99.201"
# Cluster ID
CLUSTERID="c-v6mtr"
# Token
TOKEN="token-klt5n:2smg6n5cb5vstn7qm797l9fbc7s9gljxjw528r7c5c4mwf2g7kr6nm"
# Valid certificates
curl -s -H "Authorization: Bearer ${TOKEN}" "${RANCHERURL}/v3/clusterregistrationtokens?clusterId=${CLUSTERID}" | jq -r '.data[] | select(.name != "system") | .command'
# Self signed certificates
curl -s -k -H "Authorization: Bearer ${TOKEN}" "${RANCHERURL}/v3/clusterregistrationtokens?clusterId=${CLUSTERID}" | jq -r '.data[] | select(.name != "system") | .insecureCommand'
```
以上命令執行成功後,將返回匯入叢集的命令,請做好備份,命令如下:
```
curl --insecure -sfL https://192.168.99.201/v3/import/2mgnx6f4tvgk5skfzgs6qlcrvn5nnwqh9kchqbf5lhlnswfcfrqwpr.yaml | kubectl apply -f -
```
### 恢復`cattle-cluster-agent`和`cattle-node-agent`
1、在具有`controlplane`角色的節點上生成kubeconfig
```
docker run --rm --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro --entrypoint bash $(docker inspect $(docker images -q --filter=label=io.cattle.agent=true) --format='{{index .RepoTags 0}}' | tail -1) -c 'kubectl --kubeconfig /etc/kubernetes/ssl/kubecfg-kube-node.yaml get configmap -n kube-system full-cluster-state -o json | jq -r .data.\"full-cluster-state\" | jq -r .currentState.certificatesBundle.\"kube-admin\".config | sed -e "/^[[:space:]]*server:/ s_:.*_: \"https://127.0.0.1:6443\"_"' > kubeconfig_admin.yaml
```
2、應用更新
>將`https://xxx/v3/import/dl75kfmmbp9vj876cfsrlvsb9x9grqhqjd44zvnfd9qbh6r7ks97sr.yaml` 替換為生成Kubeconfig和叢集yaml步驟中生成的yaml連線,本例為`https://192.168.99.201/v3/import/2mgnx6f4tvgk5skfzgs6qlcrvn5nnwqh9kchqbf5lhlnswfcfrqwpr.yaml`
```
docker run --rm --net=host -v $PWD/kubeconfig_admin.yaml:/root/.kube/config --entrypoint bash $(docker inspect $(docker images -q --filter=label=io.cattle.agent=true) --format='{{index .RepoTags 0}}' | tail -1) -c 'curl --insecure -sfL https://xxx/v3/import/dl75kfmmbp9vj876cfsrlvsb9x9grqhqjd44zvnfd9qbh6r7ks97sr.yaml | kubectl apply -f -'
```
![](https://oscimg.oschina.net/oscnet/up-d47bfa04b5a5115e477055a38a882b13c37.JPEG)
### 驗證
接下來通過Rancher UI或kubectl可以看到` cattle-cluster-agent`和`cattle-node-agent` 已經恢復。
![](https://oscimg.oschina.net/oscnet/up-8a6b655223e28564569ff00f50e07d33dda.JPEG)
![](https://oscimg.oschina.net/oscnet/up-50a2bffb9b2f5e7ebc8301a02e640ea97db.JPEG)
### 恢復`kube-api-auth`
預設情況下,RKE 叢集會預設啟用授權叢集端點。這個端點允許您使用 kubectl CLI 和 kubeconfig 檔案訪問下游的 Kubernetes 叢集,RKE 叢集預設啟用了該端點。
如果誤刪`kube-api-auth`,恢復的方法也很簡單,只需要編輯叢集,將“授權叢集訪問地址”修改成`禁用`,儲存叢集。然後再用相同的方法`啟用` “授權叢集訪問地址”即可。
1、編輯叢集
![](https://oscimg.oschina.net/oscnet/up-337de94a398a19e98b77080b1733ef86ef7.JPEG)
2、禁用授權叢集訪問地址,儲存
![](https://oscimg.oschina.net/oscnet/up-a5707e1604f1e7f13167d79e2c5ac02b1ac.JPEG)
3、再次編輯叢集,啟用授權叢集訪問地址,儲存
![](https://oscimg.oschina.net/oscnet/up-6280570d6adf78d9b3907b6b663b18117ed.JPEG)
### 恢復`nginx-ingress-controller`、`canal`、`coredns`、`metrics-server`元件
`nginx-ingress-controller`、`canal`、`coredns`、`metrics-server` 這些workload都是通過`kube-system`名稱空間下的各種job來建立的,所以如果要重建這些workload只需要重新執行對應的job即可。
本例使用`nginx-ingress-controller`做演示,其他workload的恢復步驟可以參考此恢復方案。
**模擬故障**
從System Project下刪除` kube-system` 下的`default-http-backend和nginx-ingress-controller`
![](https://oscimg.oschina.net/oscnet/up-117cf12e38e0e4b6d2420cfe2b3e593ccaa.JPEG)
**執行恢復**
1. 從`kube-system`名稱空間下刪除`rke-ingress-controller-deploy-job`(如果不刪除對應的job,更新集群后,不會重新觸發job重新執行)
2. 為了觸發叢集更新,可以編輯叢集,修改NodePort範圍,然後儲存。
**驗證**
叢集更新成功後,回到System Project下確認`default-http-backend`和`nginx-ingress-controller`已經重新建立。
![](https://oscimg.oschina.net/oscnet/up-0a0ed587b278d47f84085380a1ec57f12e3.JPEG)
## 如何恢復從Rancher UI或kubectl誤刪的節點
當節點處於“活動”狀態,從叢集中刪除節點將觸發一個程序來清理節點。如果沒有重啟伺服器,並不會完成所有的清除所有非持久化資料。
如果無意中將節點刪除,只需要使用相同的引數再次新增節點即可恢復叢集。
比如我的環境有兩個節點,分別具有`全部`和`Worker`角色
![](https://oscimg.oschina.net/oscnet/up-553a86e964b5852b0a1e1d1ca29c4353faa.JPEG)
從Rancher UI或kubectl將節點`rancher2`刪除,此時叢集中只剩下一個`rancher3`節點,由於叢集中缺少`Etcd`和`Control`角色,所以叢集提示:`Waiting for etcd and controlplane nodes to be registered`
![](https://oscimg.oschina.net/oscnet/up-d5ed134b1059d3c157bc2f042d38d7b412a.JPEG)
接下來,編輯叢集,並且設定相同的節點引數,這地方要注意,一定要設定和之前新增節點時相同的節點引數。
![](https://oscimg.oschina.net/oscnet/up-8a1b9519e142ec058b9e9e44f7b378edb82.JPEG)
複製新增節點命令在`rancher2`的SSH終端執行。
![](https://oscimg.oschina.net/oscnet/up-076bc33ac59f512a0aab602c5e4a8ef954d.JPEG)
過一會,再回到叢集叢集主機列表頁面,可以看到`rancher2`節點已經恢復
![](https://oscimg.oschina.net/oscnet/up-0c56a96171136375ea741751985cfd00975.JPEG)
## 如何恢復執行過清理節點指令碼的節點
中文官網提供了一個[清理節點的指令碼](https://rancher2.docs.rancher.cn/docs/cluster-admin/cleaning-cluster-nodes/_index "清理節點的指令碼"),這個指令碼會清理節點上的容器、卷、rancher/kubernetes目錄、網路、程序、iptables等。
如果由於誤操作,在正確的節點上執行了清理指令碼。針對這種場景,只有在rancher中建立過備份的叢集才可以恢復。
> 建立叢集備份參考中文官網:
>
>https://rancher2.docs.rancher.cn/docs/cluster-admin/backing-up-etcd/_index
在我的環境中,`demo`叢集有`rancher2`和`rancher3`兩個節點。
![](https://oscimg.oschina.net/oscnet/up-cf0bb517f326fc07f940e848121ef6cd256.JPEG)
### 建立備份
在Rancher UI上建立叢集快照,稍後恢復叢集的時候會用的到。
![](https://oscimg.oschina.net/oscnet/up-60fb7f3f208e99e944ee8d083f8486721ca.JPEG)
然後導航到`全域性`->`demo`->`工具`->`備份`檢視已經建立的ETCD備份,從備份建立時間可以看出,剛才建立的備份名稱為`c-v6mtr-ml-klt5n`。
![](https://oscimg.oschina.net/oscnet/up-be5f5ddf5b34f74aefc4f01196b62ad79e5.JPEG)
備份檔案存到了etcd(rancher2)節點對應的`/opt/rke/etcd-snapshots`目錄下。
![](https://oscimg.oschina.net/oscnet/up-9b589566865d59f31d5f3bcc316892367fb.JPEG)
### 清理節點
在rancher2節點執行中文官網節點清理指令碼,清理理完之後,不出所料,叢集崩了。
![](https://oscimg.oschina.net/oscnet/up-d967e7d16bc26b08d365f4086365d53f7fc.JPEG)
### 恢復叢集
節點清理指令碼並不會將/opt/rke目錄刪除,只是使用`mv /opt/rke /opt/rke-bak-$(date +"%Y%m%d%H%M")`做了個備份。接下來可以將快照備份恢復到預設的`/opt/rke`目錄下。
```
mv /opt/rke-bak-202007060903 /opt/rke
```
接下來,編輯叢集重新新增節點。這地方要注意,一定要設定和之前新增節點時相同的節點引數。
![](https://oscimg.oschina.net/oscnet/up-14e59c09f77f4a90011659a3d4842379e67.JPEG)
![](https://oscimg.oschina.net/oscnet/up-f3ea96e0d29e611cb48a80b886b619ec101.JPEG)
運⾏完命令之後,可以看到rancher agent已經正常工作起來了。
![](https://oscimg.oschina.net/oscnet/up-e29b17252502c1af71676eb3ab92aa0cfce.JPEG)
接下來,選擇之前的備份記錄,儲存,開始恢復叢集。
![](https://oscimg.oschina.net/oscnet/up-5dac049eebc051fffb581c7f76415c9c1f6.JPEG)
現在叢集的狀態變成了`Updating`,已經開始使用之前建立的快照進行恢復叢集了
![](https://oscimg.oschina.net/oscnet/up-43aec4efa61caea29fb04fb952d10600145.JPEG)
稍等片刻,可以看到kubernetes元件全部執行起來。
![](https://oscimg.oschina.net/oscnet/up-1ee1bfe9451c4ae13f2d069be40cb73c4cc.JPEG)
叢集狀態也變為了`Active`,此時,叢集已經成功恢復
![](https://oscimg.oschina.net/oscnet/up-3aba9677f31491608a0e1a787093a76b642.JPEG)
### 業務應用檢查
之前部署的名為nginx的nginx應⽤依舊存在,且執行正常。
![](https://oscimg.oschina.net/oscnet/up-d87080fb632493a4effd01f55df6560497a.JPEG)
![](https://oscimg.oschina.net/oscnet/up-e243191951abc57292f031e5a57957616c4.JPEG)
## 如何恢復被刪除的custom叢集
在Rancher UI中誤刪自定義的叢集,如果要恢復該叢集,必須需要有Rancher local叢集和自定義叢集的備份才可以恢復。
### 備份叢集
**備份custom叢集**
參考 https://rancher2.docs.rancher.cn/docs/cluster-admin/backing-up-etcd/_index 備份custom叢集,備份成功後,可以導航到叢集->工具->備份檢視備份。
![](https://oscimg.oschina.net/oscnet/up-3b75c97b17e5817b4cd6e2100caf28ecdf9.JPEG)
**備份local叢集**
參考 https://rancher2.docs.rancher.cn/docs/backups/_index 備份local叢集,備份成功後,將在本地生成一個tar.gz檔案。
![](https://oscimg.oschina.net/oscnet/up-772a3d03e8d40a3f541f751b982a43231f0.JPEG)
### 模擬故障
**備份custom叢集**
參考 https://rancher2.docs.rancher.cn/docs/cluster-admin/backing-up-etcd/_index 備份custom叢集,備份成功後,可以導航到叢集->工具->備份檢視備份。
![](https://oscimg.oschina.net/oscnet/up-465b19f0b4d75645e91f811087194215f64.JPEG)
**備份local叢集**
備份local叢集可參考:
https://rancher2.docs.rancher.cn/docs/backups/_index
備份成功後,將在本地生成一個tar.gz檔案。
![](https://oscimg.oschina.net/oscnet/up-9027d1603137004f502ca642773aae0776a.JPEG)
### 模擬故障
接下來可以在Rancher UI上將叢集刪除來模擬故障。
![](https://oscimg.oschina.net/oscnet/up-5aba587831f2f819677b1f15a0c477e567a.JPEG)
### 恢復local叢集
恢復local叢集,可參考:
https://rancher2.docs.rancher.cn/docs/backups/restorations/_index
local恢復成功後,重新登入Rancher UI,可以看到剛才被刪除的custom叢集又重新顯示了,但狀態是`Unavailable`
![](https://oscimg.oschina.net/oscnet/up-2bed6cb57e825666f5397ebbe2d3b34dee3.JPEG)
**恢復custom叢集**
接下來,可以根據之前建立的custom叢集快照恢復custom叢集。
恢復custom叢集參考:
https://rancher2.docs.rancher.cn/docs/cluster-admin/restoring-etcd/_index
![](https://oscimg.oschina.net/oscnet/up-b087b18ade8caa327ebb016ec15e7cd3c52.JPEG)
恢復後,叢集狀態變為`Updating`,稍等片刻,可以看到叢集狀態又變為`Active`,叢集恢復成功。
![](https://oscimg.oschina.net/oscnet/up-dc1f0b8384ef87685a101a8b8d3b29a122b.JPEG)
![](https://oscimg.oschina.net/oscnet/up-38cba90629a1947d5a54e6ea868bdad7a74.JPEG)
## 總 結
從以上幾個場景的恢復操作可以看出,大部分的恢復方案都依賴於叢集的備份,所以大家在生產環境中一定要做好定時備份,並且最好將備份檔案上傳到遠端備份伺服器,這樣可以在災難情況下保護您的