在Kubernetes中手動恢復Rook存儲集群
本文轉載自微信公眾號「新鈦云服」,作者祝祥 翻譯。轉載本文請聯系新鈦云服公眾號。
Rook介紹
Rook將文件、數據塊和對象存儲系統引入到Kubernetes集群,與其他正在使用存儲的應用程序和服務一起無縫運行。
通過這種方式,云原生集群可以在公有云和本地部署中自給自足并且具備可移植性。該項目的開發目的是使企業能夠通過動態應用編排,為在本地和公有云環境中運行的分布式存儲系統實現數據中心現代化。
Rook 將存儲軟件轉變成自我管理、自我擴展和自我修復的存儲服務,通過自動化部署、啟動、配置、供應、擴展、升級、遷移、災難恢復、監控和資源管理來實現。Rook 底層使用云原生容器管理、調度和編排平臺提供的能力來提供這些功能。
Rook由Operator和Cluster兩部分組成:
Operator:由一些CRD和一個All in one鏡像構成,包含包含啟動和監控存儲系統的所有功能。
Cluster:負責創建CRD對象,指定相關參數,包括ceph鏡像、元數據持久化位置、磁盤位置、dashboard等等…
Rook使Kubernetes集群中的存儲工作變得輕松了許多。但是,這種簡單性同時也帶來了一些復雜性。我們希望本文能幫助您避免其中的一些復雜性,從而使它們簡單化。
為了讓本文更加有趣,讓我們假設我們剛剛遇到了集群的一個問題……
故障場景
想象一下,您已經在K8s集群中配置并啟動了Rook。當前的所有任務操作都很正常,然后在某些時候出現了以下狀況:
- 新的Pod無法從Ceph掛載RBD鏡像;
- 諸如lsblk和df之類的命令在Kubernetes節點上不起作用。這表明掛載在節點上的RBD鏡像出了點問題。您無法讀取它們,這意味著Ceph Mon不可用。
- Ceph Mon和OSD/MGR Pod都無法在集群中運行。
現在是時候回答這個問題了,rook-ceph-operator Pod是什么時候開始啟動的?事實證明,這是最近才發生的。為什么?菜鳥運維人員可能會突然決定創建一個新的集群!那么,我們又該如何還原舊群集及其數據?
讓我們從一個更長更有趣的地方開始,一步一步地研究Rook的內部機制并手動恢復其組件。顯然,有一種更簡短、更恰當的方法:使用備份。如您所知,有兩種類型的管理員:一種是還沒有使用備份的管理員,另一種是已經痛苦地學會始終使用備份的管理員(我們稍后再討論)。
Rook的手工恢復歷程
恢復Ceph Monitor節點
首先,我們必須檢查ConfigMap的列表:rook-ceph-config和rook-config-override。它們是在部署集群成功后創建的。
注意:在新版本的Rook中,ConfigMaps不再是部署群集成功的唯一標志。
為了繼續下去,我們必須對所有安裝了RBD鏡像(ls/dev/RBD*)的服務器進行硬重啟。您可以使用sysrq。此步驟對于卸載所有已掛載的RBD鏡像是必須的,因為在這種情況下,常規重新啟動將不起作用(系統無法正常的卸載鏡像)。
如您所知,Ceph Monitor守護程序的正常運行是所有Ceph集群的先決條件。下面,讓我們來確認一下它。
Rook將以下組件安裝到Monitor的Pod中:
- Volumes:
- rook-ceph-config:
- Type: ConfigMap (a volume populated by a ConfigMap)
- Name: rook-ceph-config
- rook-ceph-mons-keyring:
- Type: Secret (a volume populated by a Secret)
- SecretName: rook-ceph-mons-keyring
- rook-ceph-log:
- Type: HostPath (bare host directory volume)
- Path: /var/lib/rook/kube-rook/log
- ceph-daemon-data:
- Type: HostPath (bare host directory volume)
- Path: /var/lib/rook/mon-a/data
- Mounts:
- /etc/ceph from rook-ceph-config (ro)
- /etc/ceph/keyring-store/ from rook-ceph-mons-keyring (ro)
- /var/lib/ceph/mon/ceph-a from ceph-daemon-data (rw)
- /var/log/ceph from rook-ceph-log (rw)
讓我們仔細看看這個rook-ceph-mons-keyring secret的內容:
- kind: Secret
- data:
- keyring: LongBase64EncodedString=
解碼后,我們將獲得具有管理員和Ceph Monitor權限的常規密鑰keyring:
- [mon.]
- key = AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==
- caps mon = "allow *"
- [client.admin]
- key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
- caps mds = "allow *"
- caps mon = "allow *"
- caps osd = "allow *"
- caps mgr = "allow *"
現在讓我們分析rook-ceph-admin-keyring secret的內容:
- kind: Secret
- data:
- keyring: anotherBase64EncodedString=
我們發現了啥?
- [client.admin]
- key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
- caps mds = "allow *"
- caps mon = "allow *"
- caps osd = "allow *"
- caps mgr = "allow *"
繼續查找……例如,以下的這個rook-ceph-mgr-a-keyring secret:
- [mgr.a]
- key = AQBZR19dbVeaIhBBXFYyxGyusGf8x1bNQunuew==
- caps mon = "allow *"
- caps mds = "allow *"
- caps osd = "allow *"
最終,我們在rook-ceph-monConfigMap中發現了更多secret:
- kind: Secret
- data:
- admin-secret: AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
- cluster-name: a3ViZS1yb29r
- fsid: ZmZiYjliZDMtODRkOS00ZDk1LTczNTItYWY4MzZhOGJkNDJhCg==
- mon-secret: AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==
它包含原始的keyrings列表,并且是上述所有keyrings的來源。
如你所知,Rook存儲在兩個不同的地方存儲這個數據。因此,讓我們看一下主機目錄中的keyring,這些keyring已安裝到包含Ceph Monitor和OSD的Pod中。為此,我們必須在/var/lib/rook/mon-a/data/keyring節點上找到相應的目錄并檢查其內容:
- # cat /var/lib/rook/mon-a/data/keyring
- [mon.]
- key = AXAbS19d8NNUXOBB+XyYwXqXI1asIzGcGlzMGg==
- caps mon = "allow *"
這里的secret不同于ConfigMap中的secret。
管理員keyring又是怎么的呢?它也是存在的:
- # cat /var/lib/rook/kube-rook/client.admin.keyring
- [client.admin]
- key = AXAbR19d8GGSMUBN+FyYwEqGI1aZizGcJlHMLgx=
- caps mds = "allow *"
- caps mon = "allow *"
- caps osd = "allow *"
- caps mgr = "allow *"
這也是當前問題所在。當發生了故障時:一切看起來都像是在重新創建集群,而實際上卻沒有。
顯然,secret包含新的keyring,并且與我們的舊群集不匹配。這就是為什么我們必須:
- 使用/var/lib/rook/mon-a/data/keyring文件(或備份)中的Ceph Monitorkeyring;
- 更換rook-ceph-mons-keyring secret中的keyring;
- 在rook-ceph-monConfigMap中指定admin和monitorkeyring;
- 刪除Ceph Monitor的Pod。
在短暫的等待之后,Ceph Monitor再次啟動并運行。這是一個比較好的開始!
還原OSD
現在我們需要進入rook-operatorPod。執行ceph mon dump后顯示所有Ceph Monitor均已就位,ceph -s表示它們已達到法定人數。但是,如果我們查看OSD Tree(ceph osd tree),則會發現一些奇怪的現象:OSD開始出現,但它們為空。看來我們必須以某種方式還原它們。但是如何做?
同時,在我們的ConfigMaps中,我們終于得到了我們所需要的rook-ceph-config,rook-config-override(以及其他比如名稱為rook-ceph osd-$nodename-config的ConfigMaps):
- kind: ConfigMap
- data:
- osd-dirs: '{"/mnt/osd1":16,"/mnt/osd2":18}'
如上,我們可以看到,osd掛載目錄與osd id都已經混亂!
讓我們將operator Pod的數量縮小到零,刪除OSD容器生成的Deployment文件,并修復這些ConfigMap。但是,我們從何處獲得節點之間OSD分布的正確映射關系?
- 如果我們深入研究節點上的/mnt/osd[1–2]目錄,也許,在那里可以找到一些東西。
- 在/mnt/osd1中有兩個子目錄,它們是osd0和osd16。第二個子文件夾與ConfigMap(16)中定義的子文件夾相同。
- 查看它們的大小,我們看到osd0比osd16更大。
我們得出結論,osd0是我們需要的“舊”OSD。它在ConfigMap中被定義為/mnt/osd1(因為我們使用基于目錄的osd)。
我們一步一步地深入研究節點并修復ConfigMap。完成后,我們可以運行rook-operator pod并分析其日志,會發現以下的流程:
- “我是集群的管理員”;
- “我在節點上找到物理磁盤”;
- “我發現了Ceph Monitor”;
- “好的,Ceph Monitor已達到法定人數;”
- “我正在開始OSD部署……”。
讓我們通過進入Rook operator的pod來檢查集群的狀況。好吧,看起來我們在幾個節點的OSD名稱上犯了一些錯誤!這沒什么大不了的:我們修復了ConfigMaps,刪除了新osd的冗余目錄,等等,最后,我們的集群狀態終于變成了HEALTH_OK!
讓我們檢查一下存儲池中的鏡像:
- # rbd ls -p kube
- pvc-9cfa2a98-b878-437e-8d57-acb26c7118fb
- pvc-9fcc4308-0343-434c-a65f-9fd181ab103e
- pvc-a6466fea-bded-4ac7-8935-7c347cff0d43
- pvc-b284d098-f0fc-420c-8ef1-7d60e330af67
- pvc-b6d02124-143d-4ce3-810f-3326cfa180ae
- pvc-c0800871-0749-40ab-8545-b900b83eeee9
- pvc-c274dbe9-1566-4a33-bada-aabeb4c76c32
- …
現在一切就緒,集群已恢復!
快速偷懶的恢復方法
對于已經做好備份的場景,恢復過程更簡單,歸結為以下幾點:
- 將Rook-operator的部署規模縮小到零;
- 刪除除Rook operator之外的所有部署;
- 從備份還原所有secret和ConfigMap;
- 恢復/var/lib/rook/mon-*節點上目錄的內容;
- 還原CephCluster,CephFilesystem,CephBlockPool,CephNFS,CephObjectStoreCRD(如果他們不知何故丟失);
- 將Rook-operator的部署擴展回1。
提示和技巧
始終進行備份!
以下是一些技巧,可避免在急需這些備份時避免這些情況:
- 如果您打算對集群進行一些涉及服務器重啟的大規模操作,我們建議將rook-operator部署縮減為零,以防止它“觸發故障”。
- 預先為Ceph Monitor指定nodeAffinity;
- 密切注意預配置 ROOK_MON_HEALTHCHECK_INTERVAL和ROOK_MON_OUT_TIMEOUT值。
結論
毫無疑問,Rook作為Kubernetes存儲的整體結構中的附加層簡化了基礎架構中的存儲管理,但是也使某些事情變得很復雜。你的每一個操作以及選擇都必須是經過深思熟慮的。
順便說一下,最近官方在Rook文檔(https://github.com/rook/rook/commit/b651239d3f9a793c95b5c06668b7f28771254082#diff-8c0c983d538cce2b49678395777c3cb9)中增加了“將現有Rook Ceph群集納入新的Kubernetes群集” 部分。
您可以在其中找到將現有Rook Ceph群集引入新的Kubernetes群集所需的步驟的詳細說明,以及如何恢復由于某種原因而失敗的集群。
原文:https://blog.flant.com/manual-recovery-of-a-rook-cluster-in-kubernetes/