Pod挂载、卸载数据卷出现问题的原因很多,有存储卷设计的缺陷、有相关组件实现的bug、有使用方式不当的可能,面对复杂的应用、存储交互系统,我们需要从两个方面对待数据卷问题:
尽量别出问题:减少存储组件的自身稳定性 && 规范的使用方式。
如何面对问题:首要是快速恢复业务,然后分析问题。
本文阐述的是业务快速恢复方案:当Pod因为数据卷挂载重启失败时,暂不去解决节点挂载的问题,而是让pod先在其他节点启动成功,快速恢复业务,待业务恢复后再去分析出问题的节点。
更新一个Pod,卡在了 ContainerCreating 状态:
例如:你在Deployment类型应用中挂载NAS数据卷,Pod在启动的时候报错为挂载失败:
Warning FailedMount 18s kubelet, cn-shenzhen.192.168.1.24 Unable to mount volumes for pod "nas-static-796b49b5f8-svbvh_default(2d483078-1400-11ea-a9b7-00163e084110)":
timeout expired waiting for volumes to attach or mount for pod "default"/"nas-static-796b49b5f8-svbvh".
list of unmounted volumes=[pvc-nas]. list of unattached volumes=[pvc-nas default-token-9v9hl]
更新前数据卷使用是正常的,而更新后pod启动不了,并有上述信息显示数据卷挂载不上,有一个可能性为:当前pod所在节点对此pv/pvc出现状态异常。具体异常原因暂不深究。
通过把pod调度到其他节点快速启动pod,参考如下步骤:
1. 确定pod所在节点:
根据上述错误信息即可拿到节点为:cn-shenzhen.192.168.1.24
也可以通过下面步骤拿到:
# podname="nas-static-796b49b5f8-svbvh"
# namespace="default"
# kubectl describe pod $podname -n $namespace | grep Node: | awk '{print $2}'
cn-shenzhen.192.168.1.24/192.168.1.24
2. 设置节点不可调度:
您可以使用控制台来配置节点调度状态,参考
也可以使用下面命令行执行给当前挂载有问题的节点打上污点标签,确保pod不会再往这个节点调度:
# kubectl taint nodes cn-shenzhen.192.168.1.24 key=value:NoSchedule
node/cn-shenzhen.192.168.1.24 tainted
3. 重启问题Pod:
这时重启问题Pod,新建的Pod就不会调度到刚才有问题的节点了:
删除问题Pod:
# kubectl delete pod nas-static-796b49b5f8-svbvh
pod "nas-static-796b49b5f8-svbvh" deleted
新的pod启动成功,且调度到新节点:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nas-static-857b99fcc9-vvzkx 1/1 Running 0 14s
# kubectl describe pod nas-static-857b99fcc9-vvzkx | grep Node
Node: cn-shenzhen.192.168.1.25/192.168.1.25
4. 后续处理:
上述步骤目的是保证您您的业务快速恢复,但问题节点的问题还存在,您可以通过存储常见问题进行排查分析。
如果您无法解决节点问题,可以联系阿里云容器服务技术支持。节点问题解决后,您可以通过控制台或者命令行将问题节点配置为可调度状态;
# kubectl taint nodes cn-shenzhen.192.168.1.24 key:NoSchedule-
node/cn-shenzhen.192.168.1.24 untainted
更新一个pod,卡在 Terminating 状态:
例如:你使用statefulset创建应用,并挂载了云盘数据卷;当更新应用的时候,pod一直处于Terminating状态从而导致新的pod无法正常启动。
# kubectl delete pod web-0
# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 0/1 Terminating 0 47m
到pod所在节点查看下面日志文件:
# tailf /var/log/alicloud/flexvolume_disk.log
# tailf /var/log/messages | grep kubelet
如果发现报错原因为数据卷Umount/Detach等失败,例如:
unmount command failed, status: Failure, reason:
device is busy 字样
或
target is busy 字样
或
Orphan Pod字样
等等
如果在没有找到如何解决问题时急于恢复业务,可以先将问题pod强制删除,优先恢复业务。
1. 使用强制删除命令结束当前pod:
# kubectl delete pod web-0 --force=true --grace-period=0
pod "web-0" force deleted
此命令会强制删除Etcd数据库中的pod信息,从而为创建新pod提供可能(StatefulSet中,老pod没有删除前新pod不会重建)。
2. 如果新建pod启动的时候失败,卡在 ContainerCreating:
可以参考 “更新一个Pod,卡在了 ContainerCreating 状态” 做法,为node配置不可调度,快速恢复pod运行。
3. 登陆问题节点,分析原因:
登陆问题所在节点,通过存储常见问题进行排查分析。无法解决时可能联系阿里云容器服务技术支持。