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)组件的机器,执行如下命令检查存储:
[[email protected] ~]# ceph -s
cluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9
health HEALTH_WARN
clock skew detected on mon.k8sdemo-ceph2, mon.k8sdemo-ceph3
too many PGs per OSD (1472 > max 300)
mds k8sdemo-ceph1 is laggy
Monitor clock skew detected
monmap 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-ceph3
fsmap e1045: 1/1/1 up {0=k8sdemo-ceph1=up:active(laggy or crashed)}
osdmap e311: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v1226550: 1472 pgs, 5 pools, 119 GB data, 41716 objects
376 GB used, 3433 GB / 3809 GB avail
1472 active+clean
client io 2457 B/s wr, 0 op/s rd, 0 op/s wr
[[email protected] ~]# #在故障的情况下,这里的osdmap 3 down,经过激活osd盘之后状态变成了up
[[email protected] ~]# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1 3.71986 root default
-2 1.52179 host k8sdemo-ceph1
0 1.52179 osd.0 up 1.00000 1.00000
-3 1.52179 host k8sdemo-ceph2
1 1.52179 osd.1 up 1.00000 1.00000
-4 0.67628 host k8sdemo-ceph3
2 0.67628 osd.2 up 1.00000 1.00000
[[email protected] ~]# #在故障的情况下,这里的状态都是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节点故障之后,执行如下检查命令:
[[email protected] ~]# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1 3.71986 root default
-2 1.52179 host k8sdemo-ceph1
0 1.52179 osd.0 up 1.00000 1.00000
-3 1.52179 host k8sdemo-ceph2
1 1.52179 osd.1 up 1.00000 1.00000
-4 0.67628 host k8sdemo-ceph3
2 0.67628 osd.2 up 1.00000 1.00000
[[email protected] ~]# ceph -s
cluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9
health HEALTH_WARN
clock skew detected on mon.k8sdemo-ceph2, mon.k8sdemo-ceph3
too many PGs per OSD (1472 > max 300)
mds k8sdemo-ceph1 is laggy
Monitor clock skew detected
monmap 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-ceph3
fsmap e1045: 1/1/1 up {0=k8sdemo-ceph1=up:active(laggy or crashed)}
osdmap e311: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v1226550: 1472 pgs, 5 pools, 119 GB data, 41716 objects
376 GB used, 3433 GB / 3809 GB avail
1472 active+clean
client io 2457 B/s wr, 0 op/s rd, 0 op/s wr
发现我们的ceph存储OSD节点状态已经是UP了。通过查看kubernetes里面的服务,大部分服务已经正常启动了。但是发现还有一部分服务没有正常启动。通过排查这些应用都是依赖于cephfs这个sc的.
[[email protected] 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类型的存储还没有好。后面的排查思路是:
[[email protected] 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: cephfs
volume.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
[[email protected] cephfs_provisioner]#
# 通过查看依赖于cephfs StorageClass的pvc,发现pv创建不成功,告警如上
[[email protected] ~]# 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的第三方插件控制器的资源都重启一下:
[[email protected] rbac]# pwd
/data/cephfs_provisioner/external-storage/ceph/cephfs/deploy/rbac
[[email protected] 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
[[email protected] rbac]# kubectl delete -f ./
[[email protected] rbac]# kubectl create -f ./
发现问题依旧,说明不是第三方存储provisioner的问题。需要找cephfs端的问题;
2. 在ceph端另建一个cephfs文件系统进行测试:
当我在ceph端另建一个cephfs文件系统的时候,还发生了一个小插曲。其实ceph官方文档中有说明不建议在ceph存储上面创建两个cephfs,容易造成数据丢失等问题;
为了测试,我还是建立一个cephfs2,操作命令如下:
ceph osd pool create fs_kube_data2 128 #创建第二个ceph数据卷
ceph osd pool create fs_kube_metadata2 128 #创建第二个ceph元数据卷
ceph fs flag set enable_multiple true # 由于ceph不建议开启两个cephfs,所以需要开启运行多个cephfs的选项
ceph fs new cephfs2 fs_kube_metadata2 fs_kube_data2 #创建第二个cephfs文件系统,如果创建了第二个cephfs文件系统,还需要设置default的cephfs才可以别k8s调用
ceph fs set_default cephfs2 #设置刚才创建的cephfs2文件系统为默认的文件系统
然后我在测试k8s里面调用cephfs的接口创建pv和在虚拟机里面挂载cephfs都可以了
[[email protected] ~]# 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
[[email protected] 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 [email protected]
#重启所有服务cdph-mds,解决了问题
刚才我也说过ceph官方是建议一个ceph存储只能创建一个cephfs文件系统,所以我们刚才测试创建的第二个cephfs2文件系统,也给系统造成了比较多的报错,主要如下:
# cephfs状态异常:
[[email protected] 9.1_head]# ceph -s
cluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9
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
monmap 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-ceph3
fsmap e1056: cephfs-0/1/1 up cephfs2-1/1/1 up {[cephfs2:0]=k8sdemo-ceph1=up:active}, 1 failed
osdmap e329: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v1240137: 1984 pgs, 9 pools, 119 GB data, 41828 objects
376 GB used, 3432 GB / 3809 GB avail
1984 active+clean
client io 1831 B/s wr, 0 op/s rd, 0 op/s wr
[[email protected] 9.1_head]#
[[email protected] 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
[[email protected] 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
[[email protected] 9.1_head]#
[[email protected] 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
[[email protected] 9.1_head]#
# 有多个状态输出命令包含了mds rank 0 has failed的报错,其实归根接地是因为我们创建了第二个cephfs2文件系统,删除掉这个cephfs2就没有问题了
ceph fs rm cephfs2 --yes-i-really-mean-it
#删除第二个cephfs2文件系统
[[email protected] 9.1_head]# ceph -s
cluster 119b3a1c-17ad-43c8-9378-a625b8dd19d9
health HEALTH_WARN
clock skew detected on mon.k8sdemo-ceph2
too many PGs per OSD (1984 > max 300)
Monitor clock skew detected
monmap 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-ceph3
fsmap e1062: 1/1/1 up {0=k8sdemo-ceph1=up:active}
osdmap e331: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v1242816: 1984 pgs, 9 pools, 119 GB data, 41816 objects
376 GB used, 3432 GB / 3809 GB avail
1984 active+clean
client 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的名字
[[email protected] ~]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins
namespace: kube-system
spec:
accessModes:
- ReadWriteOnce
# - ReadWriteMany
storageClassName: dynamic
volumeName: pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c
resources:
requests:
storage: 8Gi
[[email protected] ~]
#注意这里的pvc名字,命名空间,sc的名字,pv的名字,容量 这些都需要对应上那个丢失pvc的pv的值
# 3. 修改pv的状态
kubectl edit pv pvc-24cdfbe7-6b3b-11e9-b64b-5065f3457c8c 将以下内容给删除掉
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: jenkins
namespace: kube-system
resourceVersion: "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. 查看密钥
[[email protected] ceph]# ceph auth get-key client.admin | base64
QVFEdkJhZGN6ZW41SFJtestUQ5RzNJSVU0djlJVXRRQzZRZjBnNXc9PQ==
[[email protected] ceph]#
# 3. 更新RBD StorageClass依赖的secret的key
[[email protected] ceph]# cat ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
namespace: kube-system
data:
key: QVFEdkJhZGN6ZW41SFJtestUQ5RzNJSVU0djlJVXRRQzZRZjBnNXc9PQ==
type: kubernetes.io/rbd
[[email protected] ceph]# cat ceph-user-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-user-secret
namespace: 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 [email protected]:/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存储服务器
- 自启动服务一定要检查完整,保证依赖的服务都可以开机自启动。目前我总结的开机自启动的服务包括:
k8s master节点:
kube-apiserver.service
kube-controller-manager.service
kube-proxy.service
kube-scheduler.service
k8s node节点:
kube-proxy.service
kubelet.service
docker.service
ceph节点:
[email protected]
[email protected]
[email protected]
[[email protected] ~]# cat /etc/rc.d/rc.local
#!/bin/bash
touch /var/lock/subsys/local
ulimit -SHn 102400
echo "8192" > /sys/block/sda/queue/read_ahead_kb
/usr/sbin/ceph-disk -v activate --mark-init systemd --mount /dev/sda4
- 在做技术的过程中,一定要总结文档,只有总结了文档才可以形成知识共享和积累,对于后续的同样问题能够及时得到解决;并且再解决问题的过程中,建议多看官方文档和google搜索答案;
博文的更详细内容请关注我的个人微信公众号 “云时代IT运维”,本公众号旨在共享互联网运维新技术,新趋势; 包括IT运维行业的咨询,运维技术文档分享。重点关注devops、jenkins、zabbix监控、kubernetes、ELK、各种中间件的使用,比如redis、MQ等;shell和python等运维编程语言;本人从事IT运维相关的工作有十多年。2008年开始专职从事Linux/Unix系统运维工作;对运维相关技术有一定程度的理解。本公众号所有博文均是我的实际工作经验总结,基本都是原创博文。我很乐意将我积累的经验、心得、技术与大家分享交流!希望和大家在IT运维职业道路上一起成长和进步;
原文地址:https://blog.51cto.com/zgui2000/2396803