kubernetes一次生产故障日记
test## 1. 一次K8S測試環境故障處理過程: ##
1. 故障描述:
?? 51放假期間公司停電,關掉所有k8s測試機器,包括3臺k8s master,5臺k8s node,3臺ceph機器。放假來電之后啟動k8s機器和所有的ceph機器;
開機之后,發現很多k8s服務無法啟動,經過判斷發現是ceph的存儲問題。后續解決ceph存儲osd節點down狀態問題。但是發現依賴cephfs文件系統的pvc還是不能掛載。因為我們這個環境有兩個storageClass,一個是RBD,一個是cephfs。 RBD是剛開始搭建的,因為是kubernetes集群默認提供的RBD控制器,所以配置簡單,但是不支持多個主機同時讀寫的策略。cephfs文件系統的StorageClass可以支持多個主機同時讀寫,但是不足之處在于Kubernetes默認不支持cephfs存儲控制器,所以需要用到第三方的cephfs控制器,才可以創建cephfs的StorageClass。最終也解決了cephfs文件系統的故障問題,K8S所有服務順利啟動,沒有造成數據丟失;
2. 故障排查過程記錄:
??2.1 確認ceph存儲故障:
?? 啟動k8s集群之后首先發現很多服務都沒有自動啟動成功,包括我們的一些公共組件,比如jenkins、prometheus、業務容器等。通過以下命令排查出存儲故障:
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)組件的機器,執行如下命令檢查存儲:
[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,經過激活osd盤之后狀態變成了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 ~]# #在故障的情況下,這里的狀態都是down,激活osd之后這里的狀態都是up??遇到這種情況我的解決方法如下:
ceph-deploy osd activate k8sdemo-ceph1:/dev/sda4 k8sdemo-ceph2:/dev/sda4 k8sdemo-ceph3:/dev/sda4 #在安裝有ceph-deploy管理機器上面執行??后續經過找一下ceph存儲的牛人進行確認,因為我們的ceph版本是10.2.11,這個可能是一個BUG。就是重啟之后OSD節點不會自動激活,需要手動激活。我們也可以采用啟動自動執行激活命令的方式來實現自動激活。解決方案如下:
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節點上面增加如上內容:??2.1 確認cephfs文件系統類型的StorageClass故障:
??當我解決了OSD節點故障之后,執行如下檢查命令:
??發現我們的ceph存儲OSD節點狀態已經是UP了。通過查看kubernetes里面的服務,大部分服務已經正常啟動了。但是發現還有一部分服務沒有正常啟動。通過排查這些應用都是依賴于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存儲已經好了,但是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,發現pv創建不成功,告警如上[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沒有關系,就是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 ./??發現問題依舊,說明不是第三方存儲provisioner的問題。需要找cephfs端的問題;
2. 在ceph端另建一個cephfs文件系統進行測試:
??當我在ceph端另建一個cephfs文件系統的時候,還發生了一個小插曲。其實ceph官方文檔中有說明不建議在ceph存儲上面創建兩個cephfs,容易造成數據丟失等問題;
為了測試,我還是建立一個cephfs2,操作命令如下:
??然后我在測試k8s里面調用cephfs的接口創建pv和在虛擬機里面掛載cephfs都可以了
[root@node-01 ~]# mount -t ceph 10.83.32.224:/ /mnt/cephfs -o name=admin,secret=AQDvBadczen5HRAAD9G3IIU4v9IUtQC6Qf0g5w== 成功了 #掛載第一個cephfs文件系統異常,更改為第二個cephfs2文件系統之后再次掛載就成功了.這里的密鑰是如何查出來的?cd /etc/ceph/ #登錄ceph的管理機器,然后進入到/etc/ceph目錄 #查看 ceph.client.admin.keyring 文件內容 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 #將密鑰文件推送到節點1,然后在節點1的機器上面/etc/ceph目錄下面就會有這些密鑰文件 #然后就可以通過mount -t ceph mon服務器地址:/ mount_point -o name=用戶名,secret=密鑰文件內容 #也可以使用ceph-fuse -m 10.83.32.234:6789 /mnt 但是一定要安裝ceph-fuse軟件才可以 ;??通過這個步驟的驗證可以確認,就是cephfs這個文件有問題,重新創建一個cephfs2的文件系統就沒有問題了。但是因為我們的cephfs文件系統里面有數據,包括我們k8s的harbor存儲都是運行在cephfs文件系統的sc上面。所以還是要解決cephfs這個名稱的sc問題;
3. 找到解決方案徹底解決問題:
??最后經過高人的指點,原來是因為我們的mds服務沒有啟動成功的原因。mds服務沒有啟動成功的原因又是因為當初的OSD盤down的原因。但是修復了OSD盤之后為啥MDS服務不會自動啟動就不知道啥原因了,可能也是ceph的一個BUG吧。
ceph mds stat #此命令可以查出那臺機器是mds元數據服務器,然后登錄那臺機器執行下面的命令 systemctl restart ceph-mds@target #重啟所有服務cdph-mds,解決了問題??剛才我也說過ceph官方是建議一個ceph存儲只能創建一個cephfs文件系統,所以我們剛才測試創建的第二個cephfs2文件系統,也給系統造成了比較多的報錯,主要如下:
# cephfs狀態異常:[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]## 有多個狀態輸出命令包含了mds rank 0 has failed的報錯,其實歸根接地是因為我們創建了第二個cephfs2文件系統,刪除掉這個cephfs2就沒有問題了ceph fs rm cephfs2 --yes-i-really-mean-it #刪除第二個cephfs2文件系統[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. 總結的一些經驗和技巧:
??4.1 pvc刪除了,pv是好的,如何恢復pvc?
# 1.設置pv的數據回收策略是Retain,默認用helm安裝的都是delete策略,pvc刪除的話數據就會丟失; kubectl patch pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c -p '{"spec": {"persistentVolumeReclaimPolicy": "Retain" }}'2. 創建一個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的名字,容量 這些都需要對應上那個丟失pvc的pv的值# 3. 修改pv的狀態kubectl edit pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c 將以下內容給刪除掉claimRef:apiVersion: v1kind: PersistentVolumeClaimname: jenkinsnamespace: kube-systemresourceVersion: "10532614"uid: 24cdfbe7-6b3b-11e9-b64b-5065f3457c8c# 再次查看pv就是屬于available狀態,并且沒有關聯的pvc名字4. kubectl apply -f pvc.yaml #重新建立同名的pvc??4.2 ceph存儲端權限變更了,如何更新k8s里面的secrets
#1. 修改用戶的權限 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. 推送相關的密鑰文件到k8s node節點 ceph-deploy --overwrite-conf admin node-01 scp -r ceph.client.kube.keyring root@node-01:/etc/ceph/??4.3 更新helm的時候,如果已經有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,將內容修改為現有的pvc jenkins??4.4 在k8s里面如何使用命令擴展?
# kubectl這個命令行工具非常重要,與之相關的命令也很多,我們也記不住那么多的命令,而且也會經常寫錯,所以命令自動補全是非常有必要的,kubectl命令行工具本身就支持complication,只需要簡單的設置下就可以了。以下是linux系統的設置命令:source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc??4.5 還有一些個人的經驗如下:
有狀態應用盡量不要放在K8S集群,比如RabbitMQ、Redis、Mysql等。因為這些應用是有狀態應用,比如RabbitMQ有3個Pod,這3個Pod都需要有順序的啟動。只有按照順序啟動之后才能保持集群的狀態。
共享存儲對于K8S集群至關重要,如果存儲出現故障,所有依賴于存儲的服務都無法正常啟動。特別是一些公共組件肯定會依賴于共享存儲,比如 jenkins prometheus監控 EFK日志平臺 RabbitMQ、Redis、Mysql GitLab等等。
Ceph存儲的學習成本非常高,我們目前的能力只是能夠搭建Ceph集群,一旦Ceph集群出現故障排查問題的能力遠遠不夠;
在K8S集群里面使用的PV有一個數據回收策略,默認是DELETE,一定要將這個策略調整成Retain.可以通過打補丁的方式完成:
kubectl patch pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c -p '{"spec": {"persistentVolumeReclaimPolicy": "Retain" }}'
在K8S集群關機和開機的過程中,有一個啟動的優先順序,應該按照啟動順序來啟動服務器;我個人理解的順序如下:
啟動: ceph存儲服務器—》K8S master節點—》K8S node節點; 關機: K8S node節點—》K8S master節點 ---》ceph存儲服務器博文的更詳細內容請關注我的個人微信公眾號 “云時代IT運維”,本公眾號旨在共享互聯網運維新技術,新趨勢; 包括IT運維行業的咨詢,運維技術文檔分享。重點關注devops、jenkins、zabbix監控、kubernetes、ELK、各種中間件的使用,比如redis、MQ等;shell和python等運維編程語言;本人從事IT運維相關的工作有十多年。2008年開始專職從事Linux/Unix系統運維工作;對運維相關技術有一定程度的理解。本公眾號所有博文均是我的實際工作經驗總結,基本都是原創博文。我很樂意將我積累的經驗、心得、技術與大家分享交流!希望和大家在IT運維職業道路上一起成長和進步;
轉載于:https://blog.51cto.com/zgui2000/2396803
總結
以上是生活随笔為你收集整理的kubernetes一次生产故障日记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第12周学习进度总结
- 下一篇: 位运算世界畅游指南