通过巡检工具问题排查
1. 故障排查方法简介
1.1 使用内置工具(推荐)
Trident底座内置了故障排查工具——Lzero巡检工具,该工具会对集群进行周期性的巡检,检测容器底座的健康状态,并在发现故障时给出修复建议。
Lzero巡检工具的使用方法见第2章。
1.2 使用K8s原生命令
使用方法见第3章。
2. 故障排查工具使用指南
2.1 命令行模式
kubectl -n acs-system get opstask
您会得到如下所示输出,每一个条目被称作巡检任务,当前已支持的巡检任务列表请见第4章:
各字段含义:
NAME: 巡检任务名称
SUSPEND: 是否暂停
BROADCAST: 是否广播模式
PERIOD: 执行周期
SUCCEEDED: 巡检成功次数
FAILED: 巡检失败次数(“失败”是指遇到预期内的问题)
ERROR: 巡检错误次数(“错误”是指遇到预期外的问题)
LAST_PROBE: 最后一次执行的时间
LAST_PHASE: 最后一次执行的结果
如果LAST_PHASE为Succeeded,则成功,如果Failed,则失败:
kubectl -n acs-system get opstask check-k8s-node -oyaml
您会得到如下输出,.status.lastInstanceStatus里注明了详细的执行结果:
kubectl -n acs-system -l trident.apsara-stack.alibaba-inc.com/task-name=【巡检任务名称】 get opsinstance
# 以巡检任务check-k8s-node为例,您需要执行:
kubectl -n acs-system -l trident.apsara-stack.alibaba-inc.com/task-name=check-k8s-node get opsinstance
您将得到如下输出,每一个条目被称作一次巡检实例,这些实例中保存了之前的巡检历史,默认只保留最近7次:
查看某个巡检实例的记录:
kubectl -n acs-system get opsinstance 【巡检实例名称】 -oyaml
# 以巡检实例check-k8s-node-1609769229为例,您需要执行:
kubectl -n acs-system get opsinstance check-k8s-node-1609769229 -oyaml
您会得到如下输出,.status里注明了详细的执行结果
仔细观察的话,您会发现opsinstance的.status和opstask的.status.lastInstanceStatus的结构一致:
kubectl apply -f -<< EOF
apiVersion: trident.apsara-stack.alibaba-inc.com/v1alpha1
kind: OpsInstance
metadata:
name: 【巡检实例名称,不能和已有名称冲突】
namespace: acs-system
spec:
taskRef:
name: check-kubelet-evict
EOF
查看巡检结果:
kubectl -n acs-system get opsinstance 【巡检实例名称,不能和已有名称冲突】 -oyaml
kubectl -n acs-system edit opstask 【欲关闭的巡检名称】
找到.spec.suspend字段,改为true
3.K8s原生命令使用指南
kubectl get node -owide | grep -v STATUS | egrep -v '(Ready)'
kubectl get pod -A -owide | grep -v STATUS | egrep -v '(Completed|Running)'
kubectl describe po <pod_name> [-n ]
kubectl logs <pod_name> [-n <pod_namespace>] [-c <container_name>]
kubectl exec <pod_name> [-n <pod_namespace>] [-c <container_name>] -it sh
4. 当前已支持的巡检任务
4.1 总览
巡检任务 | Description |
check-docker-overlay-mount |
|
check-k8s-apiserver-crash |
|
check-k8s-cs |
|
check-kubelet-evict |
|
check-kube-proxy-pod |
|
check-k8s-namespace |
|
check-k8s-node |
|
check-k8s-pod |
|
check-network-control-plane |
|
check-node-network |
|
check-pod-network |
|
check-k8s-dns-hostnet |
|
4.2 详细说明
检查能否正常创建容器
docker overlay文件系统无法正常mount
部分节点上的Pod无法正常创建
高危操作
# ssh登录到有问题节点上
sudo systemctl stop docker
sudo rm -rf /var/lib/docker
sudo vim /etc/docker/daemon.json
{
"storage-driver": "overlay"
}
sudo systemctl start docker
检查K8s Apiserver是否正常运行
存在脱离K8s控制的Apiserver进程
部分Apiserver无法正常提供服务,导致kubectl整体失效
确认处于crash的apiserver pod在哪台节点上;
登录该节点,使用“docker ps -a |grep kube-apiserver”查看是否有不正常的apiserver;
如果有,使用docker stop xxx、docker rm xxx进行清理;
如果没有,使用“ps aux |grep kube-apiserver”查看是否有不受docker托管的apiserver进程,如果有,kill it;
如果仍然无法修复,请找研发。
检查K8s Components是否正常运行
etcd不正常
k8s apiserver不正常
k8s scheduler不正常
k8s controller manager不正常
K8s无法正常提供服务
kubectl无法正常使用
查看etcd的状态和日志分析异常
查看apiserver的状态和日志分析异常
查看scheduler的状态和日志分析异常
查看controller manager的状态和日志分析异常
如果仍然无法修复,请找研发。
检查是否有节点的kubelet发生驱逐现象
磁盘、CPU、内存等资源不足
该节点无法正常使用
根据巡检输出,使用kubectl describe node查看有问题的节点;
查看DiskPressure/PIDPressure/MemoryPressure的status是否为true;
对于有Pressure的节点,使用
df /var/lib/kubelet -h
,如果大于85%,则跳到第4步;使用
df /var/lib/docker -h
来查看,如果大于90%,则跳到第4步。
联系客户清理对应节点的无用数据。
检查K8s Proxy是否正常运行
底层iptables FORWARD配置错误
K8s service能力无法使用;
K8s集群内业务无法互相访问;
K8s集群无法对外暴露服务;
kubectl -n kube-system get pod | grep kube-proxy;
查看是否有不正常的Proxy Pod;
使用kubectl logs 查看其日志;
如果仍然无法修复,请找研发。
检查命名空间是否正常
有Terminating的Namespace
该Namespace无法使用
如果有处于Terminating的Namespace,使用
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --ignore-not-found -n default
,查看是否有不正常的Webhook服务;
如果有,请排查该Webhook服务为何不正常。
检查节点是否正常
节点kubelet不正常
节点docker不正常
磁盘压力
CPU压力
人为误删除
该节点无法正常使用
该节点已有应用可能会被驱逐到其他节点
检查node的cpu、内存、磁盘是否满
可尝试重启kubelet(高危,不建议直接操作)
检查异常Pod
业务自身问题
节点不正常
该Pod无法正常运行
kubectl describe pod查看详情
kubectl logs<pod_name>查看pod的日志
检查网络插件管控面是否正常
IaaS层网络配置错误问题
K8s容器网络能力无法使用;
K8s的应用无法互相访问
根据巡检任务的输出,查看不健康的网络组件Pod的日志
根据日志,定位IaaS层网络配置问题;
如果仍然无法修复,请找研发。
检查节点网络是否正常
IaaS层网络问题
K8s节点间无法正常通信
K8s集群无法正常工作
ping出问题的Node节点;
检查基础网络配置是否异常;
如果仍然无法修复,请找研发。
检查容器到节点、容器到容器、容器到Service网络、容器到NodePort是否正常
IaaS层网络问题
容器网络问题
K8s容器间、容器和节点无法正常通信
K8s集群无法正常工作
K8s集群内域名解析服务无法正常工作
查看网络插件的pod是否正常;
检查基础网络配置是否异常;
检查kube proxy是否正常;
检查节点是否有防火墙
如果仍然无法修复,请找研发。
检查能否正常访问DNS服务域名、DNS服务IP、DNS后端IP
k8s service不正常
k8s容器网络不正常
部分节点上的Pod无法正常使用DNS能力
检查DNS服务的Pod是否正常
检查网络是否正常
5. 运维知识库
1)toleration设置不合理导致pod无法自动迁移
=========================================================
适用版本:所有版本
=========================================================
通过kubectl get no
发现节点处于 NotReady 的情况,但是 Pod 还是继续往节点上进行调度。导致一些关键服务无法正常启动。
以 ipam为例,通过手动修改 ipam deployment的 toleration 来修复。
执行
kubectl -n kube-system get deploy ipam-controller -o yaml
可以看到 YAML 的 toleration 字段存在问题,该情况下任意节点(包括 NotReady 的情况)都会发生调度。
...
tolerations:
- operator: Exists
...
修改 Deployment 的 PodSpec
kubectl -n kube-system edit deploy
修改为:
...
tolerations:
- effect: NoSchedule
operator: Exists
key: node-role.kubernetes.io/master
...
修改后 Pod 重新创建后成功运行,问题解决。
2)PLEG问题导致节点NotReady
=========================================================
适用版本:所有
关键词:节点NotReady、PLEG、PLEG is not healthy
=========================================================
发现有NotReady的Node
对应Node的kubelet日志中发现:
kubelet.go:1794] skipping pod synchronization - [container runtime is down PLEG is not healthy: pleg was last seen active 21m18.877402888s ago; threshold is 3m0s]
以下依次执行,一旦解决就不用再执行后一个方案
方案1:重启docker服务:systemctl restart docker,在有的场景,这样就可以修复
方案2:删除这个节点所有的容器:
docker ps -a | awk '{print $1}' | xargs docker rm
方案3:如果前面两个都没有修复这个问题,则需要更彻底的方法:删除/var/lib/kubelet/pods/, /var/lib/docker并重启docker
原理:
• PLEG是Pod Lifecycle Event Generator的缩写,是Kubelet的一个内部组件
• 这个错误的根本原因和CNI请求有关,根本修复要K8s 1.16以后的版本(相关Github issue)
当前K8s版本是1.14,等K8s版本升级到1.16,这个问题就会修复了
文档:
国内的一个Blog:
https://blog.ittour.net/2019/09/25/container-runtime-is-down-pleg-is-not-healthy/
Github上的issue:
修复的PR:
3)启动 Docker Daemon 失败,报错 starting daemon: error initializing graphdriver: lstat xxx
=========================================================
适用版本:所有
关键词:节点NotReady、docker、graphdriver
=========================================================
Docker Daemon 启动失败,不断错误退出,查看 Docker Daemon 的状态和日志,出现 starting daemon: error initializing graphdriver: lstat xxx
该问题通常情况下是磁盘有问题,首先可以尝试进入该目录,查看情况。进入报错的目录:
cd /var/lib/docker/overlay2/xxxxxx
ls
通过查看 dmesg 查看定位:
dmesg | grep sdb
可以看到 I/O error 的情况
如果定位到上述现象,请联系客户更换磁盘。