【问题小排查】关于device or Resource Busy如何排查

背景 在 kubernetes 环境中,可能会遇到因目录被占用导致 pod 一直 terminating: 1 Aug 27 15:52:22 VM-244-70-centos kubelet[906978]: E0827 15:52:22.816125 906978 nestedpendingoperations.go:270] Operation for "\"kubernetes.io/secret/b45f3af4-3574-472e-b263-c2b71c3b2ea0-default-token-fltdk\" (\"b45f3af4-3574-472e-b263-c2b71c3b2ea0\")" failed. No retries permitted until 2021-08-27 15:54:24.816098325 +0800 CST m=+108994.575932846 (durationBeforeRetry 2m2s). Error: "UnmountVolume.TearDown failed for volume \"default-token-fltdk\" (UniqueName: \"kubernetes.io/secret/b45f3af4-3574-472e-b263-c2b71c3b2ea0-default-token-fltdk\") pod \"b45f3af4-3574-472e-b263-c2b71c3b2ea0\" (UID: \"b45f3af4-3574-472e-b263-c2b71c3b2ea0\") : unlinkat /var/lib/kubelet/pods/b45f3af4-3574-472e-b263-c2b71c3b2ea0/volumes/kubernetes.io~secret/default-token-fltdk: device or resource busy" 本文记录下排查方法。 找出目录被谁占用的 看下目录哪个进程 mount 了: 1 2 $ find /proc/*/mounts -exec grep /var/lib/kubelet/pods/0104ab85-d0ea-4ac5-a5f9-5bdd12cca589/volumes/kubernetes.io~secret/kube-proxy-token-nvthm {} + 2>/dev/null /proc/6076/mounts:tmpfs /var/lib/kubelet/pods/0104ab85-d0ea-4ac5-a5f9-5bdd12cca589/volumes/kubernetes.io~secret/kube-proxy-token-nvthm tmpfs rw,relatime 0 0 根据找出的进程号,看看是谁干的:
Read more...

【问题小排查】针对containerd V1.4.3拉取镜像的问题

问题描述

在 containerd 运行时的 kubernetes 线上环境中,出现了镜像无法下载的情况,具体报错如下:

1
Failed to pull image `  `"ccr.ccs.tencentyun.com/tkeimages/tke-hpc-controller:v1.0.0"`  `: rpc error: code = NotFound desc = failed to pull and unpack image `  `"ccr.ccs.tencentyun.com/tkeimages/tke-hpc-controller:v1.0.0"`  `: failed to unpack image on snapshotter overlayfs: failed to extract layer sha256:d72a74c56330b347f7d18b64d2effd93edd695fde25dc301d52c37efbcf4844e: failed to get reader from content store: content digest sha256:2bf487c4beaa6fa7ea6e46ec1ff50029024ebf59f628c065432a16a940792b58: not found

containerd 的日志中也有相关日志:

1
2
containerd[136]: time="2020-11-19T16:11:56.975489200Z" level=info msg="PullImage \"redis:2.8.23\""
containerd[136]: time="2020-11-19T16:12:00.140053300Z" level=warning msg="reference for unknown type: application/octet-stream" digest="sha256:481995377a044d40ca3358e4203fe95eca1d58b98a1d4c2d9cec51c0c4569613" mediatype=application/octet-stream size=5946

尝试复现

分析环境信息:

  • container v1.4.3 运行时。
  • 基于 1.10 版本的 docker 制作的镜像(比如 dockerhub 镜像仓库中的 redis:2.8.23)。

然后根据以上版本信息构造相同环境,通过如下命令拉取镜像:

1
2
$ crictl pull docker.io/libraryredis:2.8.23
FATA[0001] pulling image failed: rpc error: code = NotFound desc = failed to pull and unpack image "docker.io/library/redis:2.8.23": failed to unpack image on snapshotter overlayfs: failed to extract layer sha256:4dcab49015d47e8f300ec33400a02cebc7b54cadd09c37e49eccbc655279da90: failed to get reader from content store: content digest sha256:51f5c6a04d83efd2d45c5fd59537218924bc46705e3de6ffc8bc07b51481610b: not found

问题复现,基本确认跟 containerd 版本与打包镜像的 docker 版本有关。

Read more...

【问题小排查】排查 CLOSE_WAIT 堆积

TCP 连接的 CLOSE_WAIT 状态,正常情况下是短暂的,如果出现堆积,一般说明应用有问题。

CLOSE_WAIT 堆积的危害

每个CLOSE_WAIT连接会占据一个文件描述,堆积大量的CLOSE_WAIT可能造成文件描述符不够用,导致建连或打开文件失败,报错too many open files:

1
dial udp 9.215.0.48:9073: socket: too many open files

如何判断?

检查系统CLOSE_WAIT连接数:

1
lsof | grep CLOSE_WAIT | wc -l

检查指定进程CLOSE_WAIT连接数:

1
lsof -p $PID | grep CLOSE_WAIT | wc -l

为什么会产生大量 CLOSE_WAIT?

我们看下 TCP 四次挥手过程:

tcp_established

Read more...

【问题小排查】Service无法解析

检查kube-dns或CoreDNS服务是否正常

  1. kubelet 启动参数 –cluster-dns 可以看到 dns 服务的 cluster ip:
1
2
$ ps -ef | grep kubelet  
... /usr/bin/kubelet --cluster-dns=172.16.14.217 ...
  1. 找到 dns 的 service:
1
2
$ kubectl get svc -n kube-system | grep 172.16.14.217  
kube-dns              ClusterIP   172.16.14.217   <none>        53/TCP,53/UDP              47d
  1. 看是否存在 endpoint:
1
2
3
$ kubectl -n kube-system describe svc kube-dns | grep -i endpoints  
Endpoints:         172.16.0.156:53,172.16.0.167:53  
Endpoints:         172.16.0.156:53,172.16.0.167:53
  1. 检查 endpoint 的 对应 pod 是否正常:
1
2
$ kubectl -n kube-system get pod -o wide | grep 172.16.0.156  
kube-dns-898dbbfc6-hvwlr            3/3       Running   0          8d        172.16.0.156   10.0.0.3
Read more...

【问题小排查】关于怎么查IO高负载

系统如果出现 IO WAIT 高,说明 IO 设备的速度跟不上 CPU 的处理速度,CPU 需要在那里干等, 这里的等待实际也占用了 CPU 时间,导致系统负载升高,可能就会影响业务进程的处理速度,导致业务超时。

如何判断 ?

使用top命令看下当前负载:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
top - 19:42:06 up 23:59,  2 users,  load average: 34.64, 35.80, 35.76
Tasks: 679 total,   1 running, 678 sleeping,   0 stopped,   0 zombie
Cpu(s): 15.6%us,  1.7%sy,  0.0%ni, 74.7%id,  7.9%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  32865032k total, 30989168k used,  1875864k free,   370748k buffers
Swap:  8388604k total,     5440k used,  8383164k free,  7982424k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9783 mysql     20   0 17.3g  16g 8104 S 186.9 52.3   3752:33 mysqld
 5700 nginx     20   0 1330m  66m 9496 S  8.9  0.2   0:20.82 php-fpm
 6424 nginx     20   0 1330m  65m 8372 S  8.3  0.2   0:04.97 php-fpm

%wa(wait) 表示 IO WAIT 的 cpu 占用,默认看到的是所有核的平均值,要看每个核的%wa值需要按下 “1”:

Read more...

【问题小排查】Linux任务计划crontab不执行的问题排查

朋友弄了一个小项目,要我帮忙做下 Linux 系统运维,上线一段时间后,发现项目偶尔会挂掉导致服务不可用。 开发朋友一时之间也没空去研究项目奔溃的根因,只好由我这个运维先写一个项目进程自拉起脚本, 通过 Linux 任务计划每分钟检查一下进程是否存在来避免项目挂了没人管的情况。

自拉起脚本很简单,随便写几行就搞定了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash
processcount=$(pgrep my_app|wc -l)
cd $(cd $(dirname $0) && pwd)
if [[ 0 -eq $processcount ]]
then
        echo "[ $(date) ] : my_app is down, start it!" | tee -ai ./checkprocess.log
        bash ./start.sh #这里是项目的重启脚本
else
        echo my_app is OK!
fi

然后丢到 crontab,1 分钟执行一次:

1
* * * * * bash /data/app_server/checkprocess.sh >/dev/null 2>&1

-_-不过进程还是挂了

Read more...