通过巡检工具问题排查

更新时间: 2023-04-12 13:17:53

1. 故障排查方法简介

1.1 使用内置工具(推荐)

Trident底座内置了故障排查工具——Lzero巡检工具,该工具会对集群进行周期性的巡检,检测容器底座的健康状态,并在发现故障时给出修复建议。

Lzero巡检工具的使用方法见第2章。

1.2 使用K8s原生命令

使用方法见第3章。

2. 故障排查工具使用指南

2.1 命令行模式

kubectl -n acs-system get opstask

您会得到如下所示输出,每一个条目被称作巡检任务,当前已支持的巡检任务列表请见第4章:

image

各字段含义:

  • NAME: 巡检任务名称

  • SUSPEND: 是否暂停

  • BROADCAST: 是否广播模式

  • PERIOD: 执行周期

  • SUCCEEDED: 巡检成功次数

  • FAILED: 巡检失败次数(“失败”是指遇到预期内的问题)

  • ERROR: 巡检错误次数(“错误”是指遇到预期外的问题)

  • LAST_PROBE: 最后一次执行的时间

  • LAST_PHASE: 最后一次执行的结果

如果LAST_PHASE为Succeeded,则成功,如果Failed,则失败:

image
kubectl -n acs-system get opstask check-k8s-node -oyaml

您会得到如下输出,.status.lastInstanceStatus里注明了详细的执行结果:

image
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次:

image

查看某个巡检实例的记录:

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的结构一致:

image
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

  • 检查docker overlay文件系统是否可以正常mount

check-k8s-apiserver-crash

  • 检查k8s Apiserver是否有crash

check-k8s-cs

  • 检查k8s核心组件管控pod是否健康

check-kubelet-evict

  • 检查环境中是否有被驱逐的pod,检查kubelet是否有pressure

check-kube-proxy-pod

  • 检查kube proxy的管控pod是否健康

check-k8s-namespace

  • 检查k8s namespace是否正常

check-k8s-node

  • 检查k8s node是否正常

check-k8s-pod

  • 检查k8s pod是否正常

check-network-control-plane

  • 检查网络插件管控是否健康

check-node-network

  • 检查节点网络内的联通性

check-pod-network

  • 检查容器网络到节点网络的联通性

  • 检查容器网络内的联通性

  • 检查容器到Service ClusterIP的联通性

  • 检查容器到Service NodePort的联通性

  • 检查容器到DNS Domain的联通性

  • 检查容器到DNS ClusterIP的联通性

  • 检查容器到DNS Endpoint的联通性

check-k8s-dns-hostnet

  • 检查节点到DNS Domain的联通性

  • 检查节点到DNS Domain的联通性

  • 检查节点到DNS Endpoint的联通性

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整体失效

  1. 确认处于crash的apiserver pod在哪台节点上;

  2. 登录该节点,使用“docker ps -a |grep kube-apiserver”查看是否有不正常的apiserver;

  3. 如果有,使用docker stop xxx、docker rm xxx进行清理;

  4. 如果没有,使用“ps aux |grep kube-apiserver”查看是否有不受docker托管的apiserver进程,如果有,kill it;

  5. 如果仍然无法修复,请找研发。

检查K8s Components是否正常运行

  • etcd不正常

  • k8s apiserver不正常

  • k8s scheduler不正常

  • k8s controller manager不正常

K8s无法正常提供服务

kubectl无法正常使用

  1. 查看etcd的状态和日志分析异常

  2. 查看apiserver的状态和日志分析异常

  3. 查看scheduler的状态和日志分析异常

  4. 查看controller manager的状态和日志分析异常

  5. 如果仍然无法修复,请找研发。

检查是否有节点的kubelet发生驱逐现象

  • 磁盘、CPU、内存等资源不足

该节点无法正常使用

  1. 根据巡检输出,使用kubectl describe node查看有问题的节点;

  2. 查看DiskPressure/PIDPressure/MemoryPressure的status是否为true;

  3. 对于有Pressure的节点,使用

    df /var/lib/kubelet -h

    ,如果大于85%,则跳到第4步;使用

    df /var/lib/docker -h

    来查看,如果大于90%,则跳到第4步。

  4. 联系客户清理对应节点的无用数据。

检查K8s Proxy是否正常运行

  • 底层iptables FORWARD配置错误

K8s service能力无法使用;

K8s集群内业务无法互相访问;

K8s集群无法对外暴露服务;

  1. kubectl -n kube-system get pod | grep kube-proxy;

  2. 查看是否有不正常的Proxy Pod;

  3. 使用kubectl logs 查看其日志;

  4. 如果仍然无法修复,请找研发。

检查命名空间是否正常

  • 有Terminating的Namespace

该Namespace无法使用

  1. 如果有处于Terminating的Namespace,使用

    kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --ignore-not-found -n default

    ,查看是否有不正常的Webhook服务;

  2. 如果有,请排查该Webhook服务为何不正常。

检查节点是否正常

  • 节点kubelet不正常

  • 节点docker不正常

  • 磁盘压力

  • CPU压力

  • 人为误删除

该节点无法正常使用

该节点已有应用可能会被驱逐到其他节点

  1. 检查node的cpu、内存、磁盘是否满

  2. 可尝试重启kubelet(高危,不建议直接操作)

检查异常Pod

  • 业务自身问题

  • 节点不正常

该Pod无法正常运行

  1. kubectl describe pod查看详情

  2. kubectl logs<pod_name>查看pod的日志

检查网络插件管控面是否正常

  • IaaS层网络配置错误问题

K8s容器网络能力无法使用;

K8s的应用无法互相访问

  1. 根据巡检任务的输出,查看不健康的网络组件Pod的日志

  2. 根据日志,定位IaaS层网络配置问题;

  3. 如果仍然无法修复,请找研发。

检查节点网络是否正常

  • IaaS层网络问题

K8s节点间无法正常通信

K8s集群无法正常工作

  1. ping出问题的Node节点;

  2. 检查基础网络配置是否异常;

  3. 如果仍然无法修复,请找研发。

检查容器到节点、容器到容器、容器到Service网络、容器到NodePort是否正常

  • IaaS层网络问题

  • 容器网络问题

K8s容器间、容器和节点无法正常通信

K8s集群无法正常工作

K8s集群内域名解析服务无法正常工作

  1. 查看网络插件的pod是否正常;

  2. 检查基础网络配置是否异常;

  3. 检查kube proxy是否正常;

  4. 检查节点是否有防火墙

  5. 如果仍然无法修复,请找研发。

检查能否正常访问DNS服务域名、DNS服务IP、DNS后端IP

  • k8s service不正常

  • k8s容器网络不正常

部分节点上的Pod无法正常使用DNS能力

  1. 检查DNS服务的Pod是否正常

  2. 检查网络是否正常

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. 方案1:重启docker服务:systemctl restart docker,在有的场景,这样就可以修复

  2. 方案2:删除这个节点所有的容器:

    docker ps -a | awk '{print $1}' | xargs docker rm

  3. 方案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,这个问题就会修复了

文档:

3)启动 Docker Daemon 失败,报错 starting daemon: error initializing graphdriver: lstat xxx

=========================================================

适用版本:所有

关键词:节点NotReady、docker、graphdriver

=========================================================

Docker Daemon 启动失败,不断错误退出,查看 Docker Daemon 的状态和日志,出现 starting daemon: error initializing graphdriver: lstat xxx

image

该问题通常情况下是磁盘有问题,首先可以尝试进入该目录,查看情况。进入报错的目录:

cd /var/lib/docker/overlay2/xxxxxx
ls

通过查看 dmesg 查看定位:

dmesg | grep sdb

可以看到 I/O error 的情况

image

如果定位到上述现象,请联系客户更换磁盘。

阿里云首页 云原生应用交付平台 相关技术圈