kubernetes一次生产故障日记
test## 1. 一次K8S測試環(huán)境故障處理過程: ##
1. 故障描述:
?? 51放假期間公司停電,關(guān)掉所有k8s測試機器,包括3臺k8s master,5臺k8s node,3臺ceph機器。放假來電之后啟動k8s機器和所有的ceph機器;
開機之后,發(fā)現(xiàn)很多k8s服務(wù)無法啟動,經(jīng)過判斷發(fā)現(xiàn)是ceph的存儲問題。后續(xù)解決ceph存儲osd節(jié)點down狀態(tài)問題。但是發(fā)現(xiàn)依賴cephfs文件系統(tǒng)的pvc還是不能掛載。因為我們這個環(huán)境有兩個storageClass,一個是RBD,一個是cephfs。 RBD是剛開始搭建的,因為是kubernetes集群默認提供的RBD控制器,所以配置簡單,但是不支持多個主機同時讀寫的策略。cephfs文件系統(tǒng)的StorageClass可以支持多個主機同時讀寫,但是不足之處在于Kubernetes默認不支持cephfs存儲控制器,所以需要用到第三方的cephfs控制器,才可以創(chuàng)建cephfs的StorageClass。最終也解決了cephfs文件系統(tǒng)的故障問題,K8S所有服務(wù)順利啟動,沒有造成數(shù)據(jù)丟失;
2. 故障排查過程記錄:
??2.1 確認ceph存儲故障:
?? 啟動k8s集群之后首先發(fā)現(xiàn)很多服務(wù)都沒有自動啟動成功,包括我們的一些公共組件,比如jenkins、prometheus、業(yè)務(wù)容器等。通過以下命令排查出存儲故障:
kubectl describe pods -n kube-system jenkins-55c4dcb555-fwpcp Events:Type Reason Age From Message---- ------ ---- ---- -------Warning FailedMount 12m (x257 over 11h) kubelet, 10.83.32.233 Unable to mount volumes for pod "jenkins-55c4dcb555-fwpcp_kube-system(8b5cda6f-6ffe-11e9-974d-480fcf482f56)": timeout expired waiting for volumes to attach or mount for pod "kube-system"/"jenkins-55c4dcb555-fwpcp". list of unmounted volumes=[jenkins-home]. list of unattached volumes=[plugins tmp jenkins-config plugin-dir secrets-dir jenkins-home jenkins-token-vb27p]??然后我登錄存儲的管理機器(就是安裝ceph-deploy)組件的機器,執(zhí)行如下命令檢查存儲:
[root@k8sdemo-ceph1 ~]# ceph -scluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9health HEALTH_WARNclock skew detected on mon.k8sdemo-ceph2, mon.k8sdemo-ceph3too many PGs per OSD (1472 > max 300)mds k8sdemo-ceph1 is laggyMonitor clock skew detectedmonmap e2: 3 mons at {k8sdemo-ceph1=10.83.32.224:6789/0,k8sdemo-ceph2=10.83.32.225:6789/0,k8sdemo-ceph3=10.83.32.234:6789/0}election epoch 4792, quorum 0,1,2 k8sdemo-ceph1,k8sdemo-ceph2,k8sdemo-ceph3fsmap e1045: 1/1/1 up {0=k8sdemo-ceph1=up:active(laggy or crashed)}osdmap e311: 3 osds: 3 up, 3 inflags sortbitwise,require_jewel_osdspgmap v1226550: 1472 pgs, 5 pools, 119 GB data, 41716 objects376 GB used, 3433 GB / 3809 GB avail1472 active+cleanclient io 2457 B/s wr, 0 op/s rd, 0 op/s wr [root@k8sdemo-ceph1 ~]# #在故障的情況下,這里的osdmap 3 down,經(jīng)過激活osd盤之后狀態(tài)變成了up[root@k8sdemo-ceph1 ~]# ceph osd tree ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY -1 3.71986 root default -2 1.52179 host k8sdemo-ceph10 1.52179 osd.0 up 1.00000 1.00000 -3 1.52179 host k8sdemo-ceph21 1.52179 osd.1 up 1.00000 1.00000 -4 0.67628 host k8sdemo-ceph32 0.67628 osd.2 up 1.00000 1.00000 [root@k8sdemo-ceph1 ~]# #在故障的情況下,這里的狀態(tài)都是down,激活osd之后這里的狀態(tài)都是up??遇到這種情況我的解決方法如下:
ceph-deploy osd activate k8sdemo-ceph1:/dev/sda4 k8sdemo-ceph2:/dev/sda4 k8sdemo-ceph3:/dev/sda4 #在安裝有ceph-deploy管理機器上面執(zhí)行??后續(xù)經(jīng)過找一下ceph存儲的牛人進行確認,因為我們的ceph版本是10.2.11,這個可能是一個BUG。就是重啟之后OSD節(jié)點不會自動激活,需要手動激活。我們也可以采用啟動自動執(zhí)行激活命令的方式來實現(xiàn)自動激活。解決方案如下:
vim /etc/rc.d/rc.local /usr/sbin/ceph-disk -v activate --mark-init systemd --mount /dev/sda4 chmod +x /etc/rc.d/rc.local #在每一臺ceph OSD節(jié)點上面增加如上內(nèi)容:??2.1 確認cephfs文件系統(tǒng)類型的StorageClass故障:
??當我解決了OSD節(jié)點故障之后,執(zhí)行如下檢查命令:
??發(fā)現(xiàn)我們的ceph存儲OSD節(jié)點狀態(tài)已經(jīng)是UP了。通過查看kubernetes里面的服務(wù),大部分服務(wù)已經(jīng)正常啟動了。但是發(fā)現(xiàn)還有一部分服務(wù)沒有正常啟動。通過排查這些應(yīng)用都是依賴于cephfs這個sc的.
[root@master-01 gitlab]# kubectl get sc NAME PROVISIONER AGE cephfs ceph.com/cephfs 26d dynamic (default) kubernetes.io/rbd 31d??我們的k8s集群有兩個sc,dynamic這個名稱的RBD類型的ceph存儲已經(jīng)好了,但是cephfs這個名稱的cephfs類型的存儲還沒有好。后面的排查思路是:
[root@master-01 cephfs_provisioner]# kubectl describe pvc -n kube-system claim2 Name: claim2 Namespace: kube-system StorageClass: cephfs Status: Pending Volume: Labels: <none> Annotations: volume.beta.kubernetes.io/storage-class: cephfsvolume.beta.kubernetes.io/storage-provisioner: ceph.com/cephfs Finalizers: [kubernetes.io/pvc-protection] Capacity: Access Modes: Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Provisioning 97s ceph.com/cephfs_cephfs-provisioner-79d97b7bdf-rq8lm_58dc76ce-6dc4-11e9-8803-6e4d7afb9686 External provisioner is provisioning volume for claim "kube-system/claim2"Normal ExternalProvisioning 1s (x9 over 97s) persistentvolume-controller waiting for a volume to be created, either by external provisioner "ceph.com/cephfs" or manually created by system administrator Mounted By: test-pod2 [root@master-01 cephfs_provisioner]# # 通過查看依賴于cephfs StorageClass的pvc,發(fā)現(xiàn)pv創(chuàng)建不成功,告警如上[root@node-01 ~]# mount -t ceph 10.83.32.224:/ /mnt/cephfs -o name=admin,secret=AQDvBadczen5HRAAD9G3IIU4v9IUtQC6Qf0g5w== mount: special device 10.83.32.224:/ does not exist # 然后我不用k8s掉cephfs存儲的接口,直接在一臺虛擬機上面mount cephfs也是不成功,可以確認和k8s沒有關(guān)系,就是cephfs的問題;1. 先把cephfs的第三方插件控制器的資源都重啟一下:
[root@master-01 rbac]# pwd /data/cephfs_provisioner/external-storage/ceph/cephfs/deploy/rbac [root@master-01 rbac]# ll total 24 -rw-r--r--. 1 root root 288 Apr 9 18:12 clusterrolebinding.yaml -rw-r--r-- 1 root root 743 May 6 11:07 clusterrole.yaml -rw-r--r--. 1 root root 670 Apr 9 18:16 deployment.yaml -rw-r--r--. 1 root root 268 Apr 9 18:12 rolebinding.yaml -rw-r--r--. 1 root root 321 Apr 9 18:12 role.yaml -rw-r--r--. 1 root root 98 Apr 9 18:12 serviceaccount.yaml [root@master-01 rbac]# kubectl delete -f ./ [root@master-01 rbac]# kubectl create -f ./??發(fā)現(xiàn)問題依舊,說明不是第三方存儲provisioner的問題。需要找cephfs端的問題;
2. 在ceph端另建一個cephfs文件系統(tǒng)進行測試:
??當我在ceph端另建一個cephfs文件系統(tǒng)的時候,還發(fā)生了一個小插曲。其實ceph官方文檔中有說明不建議在ceph存儲上面創(chuàng)建兩個cephfs,容易造成數(shù)據(jù)丟失等問題;
為了測試,我還是建立一個cephfs2,操作命令如下:
??然后我在測試k8s里面調(diào)用cephfs的接口創(chuàng)建pv和在虛擬機里面掛載cephfs都可以了
[root@node-01 ~]# mount -t ceph 10.83.32.224:/ /mnt/cephfs -o name=admin,secret=AQDvBadczen5HRAAD9G3IIU4v9IUtQC6Qf0g5w== 成功了 #掛載第一個cephfs文件系統(tǒng)異常,更改為第二個cephfs2文件系統(tǒng)之后再次掛載就成功了.這里的密鑰是如何查出來的?cd /etc/ceph/ #登錄ceph的管理機器,然后進入到/etc/ceph目錄 #查看 ceph.client.admin.keyring 文件內(nèi)容 total 16 -rw------- 1 root root 129 May 6 14:40 ceph.client.admin.keyring -rw-r--r-- 1 root root 286 May 6 14:40 ceph.conf -rw-r--r-- 1 root root 3394 May 6 15:17 ceph-deploy-ceph.log -rw-r--r-- 1 root root 92 Jul 10 2018 rbdmap -rw------- 1 root root 0 Apr 5 15:37 tmp9rbpHS [root@k8sdemo-ceph1 ceph]# ceph-deploy --overwrite-conf admin node-01 #將密鑰文件推送到節(jié)點1,然后在節(jié)點1的機器上面/etc/ceph目錄下面就會有這些密鑰文件 #然后就可以通過mount -t ceph mon服務(wù)器地址:/ mount_point -o name=用戶名,secret=密鑰文件內(nèi)容 #也可以使用ceph-fuse -m 10.83.32.234:6789 /mnt 但是一定要安裝ceph-fuse軟件才可以 ;??通過這個步驟的驗證可以確認,就是cephfs這個文件有問題,重新創(chuàng)建一個cephfs2的文件系統(tǒng)就沒有問題了。但是因為我們的cephfs文件系統(tǒng)里面有數(shù)據(jù),包括我們k8s的harbor存儲都是運行在cephfs文件系統(tǒng)的sc上面。所以還是要解決cephfs這個名稱的sc問題;
3. 找到解決方案徹底解決問題:
??最后經(jīng)過高人的指點,原來是因為我們的mds服務(wù)沒有啟動成功的原因。mds服務(wù)沒有啟動成功的原因又是因為當初的OSD盤down的原因。但是修復(fù)了OSD盤之后為啥MDS服務(wù)不會自動啟動就不知道啥原因了,可能也是ceph的一個BUG吧。
ceph mds stat #此命令可以查出那臺機器是mds元數(shù)據(jù)服務(wù)器,然后登錄那臺機器執(zhí)行下面的命令 systemctl restart ceph-mds@target #重啟所有服務(wù)cdph-mds,解決了問題??剛才我也說過ceph官方是建議一個ceph存儲只能創(chuàng)建一個cephfs文件系統(tǒng),所以我們剛才測試創(chuàng)建的第二個cephfs2文件系統(tǒng),也給系統(tǒng)造成了比較多的報錯,主要如下:
# cephfs狀態(tài)異常:[root@k8sdemo-ceph1 9.1_head]# ceph -scluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9health HEALTH_ERRclock skew detected on mon.k8sdemo-ceph2too many PGs per OSD (1984 > max 300)mds rank 0 has failedmds cluster is degradedMonitor clock skew detectedmonmap e2: 3 mons at {k8sdemo-ceph1=10.83.32.224:6789/0,k8sdemo-ceph2=10.83.32.225:6789/0,k8sdemo-ceph3=10.83.32.234:6789/0}election epoch 4798, quorum 0,1,2 k8sdemo-ceph1,k8sdemo-ceph2,k8sdemo-ceph3fsmap e1056: cephfs-0/1/1 up cephfs2-1/1/1 up {[cephfs2:0]=k8sdemo-ceph1=up:active}, 1 failedosdmap e329: 3 osds: 3 up, 3 inflags sortbitwise,require_jewel_osdspgmap v1240137: 1984 pgs, 9 pools, 119 GB data, 41828 objects376 GB used, 3432 GB / 3809 GB avail1984 active+cleanclient io 1831 B/s wr, 0 op/s rd, 0 op/s wr [root@k8sdemo-ceph1 9.1_head]#[root@k8sdemo-ceph1 9.1_head]# ceph fs get cephfs Filesystem 'cephfs' (1) fs_name cephfs epoch 1049 flags 0 created 2019-04-09 15:58:55.124618 modified 2019-04-15 13:07:31.060391 tableserver 0 root 0 session_timeout 60 session_autoclose 300 max_file_size 1099511627776 last_failure 0 last_failure_osd_epoch 328 compat compat={},rocompat={},incompat={1=base v0.20,2=client writeable ranges,3=default file layouts on dirs,4=dir inode in separate object,5=mds uses versioned encoding,6=dirfrag is stored in omap,8=file layout v2} max_mds 1 in 0 up {} failed 0 damaged stopped data_pools 3 metadata_pool 4 inline_data disabled[root@k8sdemo-ceph1 9.1_head]# ceph health HEALTH_ERR clock skew detected on mon.k8sdemo-ceph2; too many PGs per OSD (1984 > max 300); mds rank 0 has failed; mds cluster is degraded; Monitor clock skew detected [root@k8sdemo-ceph1 9.1_head]#[root@k8sdemo-ceph1 9.1_head]# ceph mds stat e1061: cephfs-1/1/1 up cephfs2-0/1/1 up {[cephfs:0]=k8sdemo-ceph1=up:active}, 1 failed [root@k8sdemo-ceph1 9.1_head]## 有多個狀態(tài)輸出命令包含了mds rank 0 has failed的報錯,其實歸根接地是因為我們創(chuàng)建了第二個cephfs2文件系統(tǒng),刪除掉這個cephfs2就沒有問題了ceph fs rm cephfs2 --yes-i-really-mean-it #刪除第二個cephfs2文件系統(tǒng)[root@k8sdemo-ceph1 9.1_head]# ceph -scluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9health HEALTH_WARNclock skew detected on mon.k8sdemo-ceph2too many PGs per OSD (1984 > max 300)Monitor clock skew detectedmonmap e2: 3 mons at {k8sdemo-ceph1=10.83.32.224:6789/0,k8sdemo-ceph2=10.83.32.225:6789/0,k8sdemo-ceph3=10.83.32.234:6789/0}election epoch 4798, quorum 0,1,2 k8sdemo-ceph1,k8sdemo-ceph2,k8sdemo-ceph3fsmap e1062: 1/1/1 up {0=k8sdemo-ceph1=up:active}osdmap e331: 3 osds: 3 up, 3 inflags sortbitwise,require_jewel_osdspgmap v1242816: 1984 pgs, 9 pools, 119 GB data, 41816 objects376 GB used, 3432 GB / 3809 GB avail1984 active+cleanclient io 3723 B/s wr, 0 op/s rd, 2 op/s wr#告警解除4. 總結(jié)的一些經(jīng)驗和技巧:
??4.1 pvc刪除了,pv是好的,如何恢復(fù)pvc?
# 1.設(shè)置pv的數(shù)據(jù)回收策略是Retain,默認用helm安裝的都是delete策略,pvc刪除的話數(shù)據(jù)就會丟失; kubectl patch pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c -p '{"spec": {"persistentVolumeReclaimPolicy": "Retain" }}'2. 創(chuàng)建一個pvc的清單文件,引用pv的名字[root@master-01 ~]# cat pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata:name: jenkinsnamespace: kube-system spec:accessModes:- ReadWriteOnce# - ReadWriteManystorageClassName: dynamicvolumeName: pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8cresources:requests:storage: 8Gi [root@master-01 ~]#注意這里的pvc名字,命名空間,sc的名字,pv的名字,容量 這些都需要對應(yīng)上那個丟失pvc的pv的值# 3. 修改pv的狀態(tài)kubectl edit pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c 將以下內(nèi)容給刪除掉claimRef:apiVersion: v1kind: PersistentVolumeClaimname: jenkinsnamespace: kube-systemresourceVersion: "10532614"uid: 24cdfbe7-6b3b-11e9-b64b-5065f3457c8c# 再次查看pv就是屬于available狀態(tài),并且沒有關(guān)聯(lián)的pvc名字4. kubectl apply -f pvc.yaml #重新建立同名的pvc??4.2 ceph存儲端權(quán)限變更了,如何更新k8s里面的secrets
#1. 修改用戶的權(quán)限 Ceph auth caps client.kube mon 'allow rwx' osd 'allow rw pool=fs_kube_data' mds 'allow rwp' # 2. 查看密鑰 [root@k8sdemo-ceph1 ceph]# ceph auth get-key client.admin | base64 QVFEdkJhZGN6ZW41SFJtestUQ5RzNJSVU0djlJVXRRQzZRZjBnNXc9PQ== [root@k8sdemo-ceph1 ceph]# # 3. 更新RBD StorageClass依賴的secret的key[root@master-01 ceph]# cat ceph-secret.yaml apiVersion: v1 kind: Secret metadata:name: ceph-secretnamespace: kube-system data:key: QVFEdkJhZGN6ZW41SFJtestUQ5RzNJSVU0djlJVXRRQzZRZjBnNXc9PQ== type: kubernetes.io/rbd [root@master-01 ceph]# cat ceph-user-secret.yaml apiVersion: v1 kind: Secret metadata:name: ceph-user-secretnamespace: kube-system data:key: QVFDTks2ZGNjcEZoQmhtestWs4anVvbmVXZnZUeitvMytPbGZ6OFE9PQ== type: kubernetes.io/rbd# 4. 重建secret和sc kubectl replace -f ceph-secret.yaml --force kubectl replace -f ceph-user-secret.yaml --force kubectl replace -f ceph-storageclass.yaml --force# 5. 推送相關(guān)的密鑰文件到k8s node節(jié)點 ceph-deploy --overwrite-conf admin node-01 scp -r ceph.client.kube.keyring root@node-01:/etc/ceph/??4.3 更新helm的時候,如果已經(jīng)有PVC了,如何使用原有的PVC
# 修改jenkins helm value.yaml文件,existingClaim: "jenkins"## jenkins data Persistent Volume Storage Class## jenkins data Persistent Volume Storage Class## If defined, storageClassName: <storageClass>## If set to "-", storageClassName: "", which disables dynamic provisioning## If undefined (the default) or set to null, no storageClassName spec is## set, choosing the default provisioner. (gp2 on AWS, standard on## GKE, AWS & OpenStack)### storageClass: "dynamic"# 注釋storageClass的值,開啟existingClaim,將內(nèi)容修改為現(xiàn)有的pvc jenkins??4.4 在k8s里面如何使用命令擴展?
# kubectl這個命令行工具非常重要,與之相關(guān)的命令也很多,我們也記不住那么多的命令,而且也會經(jīng)常寫錯,所以命令自動補全是非常有必要的,kubectl命令行工具本身就支持complication,只需要簡單的設(shè)置下就可以了。以下是linux系統(tǒng)的設(shè)置命令:source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc??4.5 還有一些個人的經(jīng)驗如下:
有狀態(tài)應(yīng)用盡量不要放在K8S集群,比如RabbitMQ、Redis、Mysql等。因為這些應(yīng)用是有狀態(tài)應(yīng)用,比如RabbitMQ有3個Pod,這3個Pod都需要有順序的啟動。只有按照順序啟動之后才能保持集群的狀態(tài)。
共享存儲對于K8S集群至關(guān)重要,如果存儲出現(xiàn)故障,所有依賴于存儲的服務(wù)都無法正常啟動。特別是一些公共組件肯定會依賴于共享存儲,比如 jenkins prometheus監(jiān)控 EFK日志平臺 RabbitMQ、Redis、Mysql GitLab等等。
Ceph存儲的學(xué)習(xí)成本非常高,我們目前的能力只是能夠搭建Ceph集群,一旦Ceph集群出現(xiàn)故障排查問題的能力遠遠不夠;
在K8S集群里面使用的PV有一個數(shù)據(jù)回收策略,默認是DELETE,一定要將這個策略調(diào)整成Retain.可以通過打補丁的方式完成:
kubectl patch pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c -p '{"spec": {"persistentVolumeReclaimPolicy": "Retain" }}'
在K8S集群關(guān)機和開機的過程中,有一個啟動的優(yōu)先順序,應(yīng)該按照啟動順序來啟動服務(wù)器;我個人理解的順序如下:
啟動: ceph存儲服務(wù)器—》K8S master節(jié)點—》K8S node節(jié)點; 關(guān)機: K8S node節(jié)點—》K8S master節(jié)點 ---》ceph存儲服務(wù)器博文的更詳細內(nèi)容請關(guān)注我的個人微信公眾號 “云時代IT運維”,本公眾號旨在共享互聯(lián)網(wǎng)運維新技術(shù),新趨勢; 包括IT運維行業(yè)的咨詢,運維技術(shù)文檔分享。重點關(guān)注devops、jenkins、zabbix監(jiān)控、kubernetes、ELK、各種中間件的使用,比如redis、MQ等;shell和python等運維編程語言;本人從事IT運維相關(guān)的工作有十多年。2008年開始專職從事Linux/Unix系統(tǒng)運維工作;對運維相關(guān)技術(shù)有一定程度的理解。本公眾號所有博文均是我的實際工作經(jīng)驗總結(jié),基本都是原創(chuàng)博文。我很樂意將我積累的經(jīng)驗、心得、技術(shù)與大家分享交流!希望和大家在IT運維職業(yè)道路上一起成長和進步;
轉(zhuǎn)載于:https://blog.51cto.com/zgui2000/2396803
總結(jié)
以上是生活随笔為你收集整理的kubernetes一次生产故障日记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第12周学习进度总结
- 下一篇: 位运算世界畅游指南