如何找出正在访问pvc挂载点的容器进程

2024-04-01 14:47:18 浏览数 (1)

如果一个pod在被销毁时其pvc挂载节点无法解挂会导致pod一直处于Terminating状态无法删除,出现这种情况时在系统/var/log/messages搜索pod 的uid能找到到umount对应pvc报Resouce busy。

#kubectl get pods $podname -n $namespace -o yaml | grep uid

uid: b943671a-fd85-4687-84f5-c88e49a0339a

通过uid搜索/var/log/messages日志可以看到类似如下报错信息:

umount: can't unmount /var/lib/kubelet/pods/b943671a-fd85-4687-84f5-c88e49a0339a/volumes/kubernetes.io~csi/test-pv/mount: Resource busyn"

此时手工去umount该挂载点也会报device is busy解挂失败:

# umount /var/lib/kubelet/pods/b943671a-fd85-4687-84f5-c88e49a0339a/volumes/kubernetes.io~csi/test-pv/mount

umount.nfs4: /var/lib/kubelet/pods/b943671a-fd85-4687-84f5-c88e49a0339a/volumes/kubernetes.io~csi/test-pv/mount: device is busy

由于使用lsof D的方式会输出较多的干扰信息,这个时候可以使用如下脚本来快速找到是什么进程访问了该挂载点,其原理是通过遍历/proc/下所有进程的fd找到对应匹配的描述符信息

代码语言:javascript复制
#!/bin/bash

if [[ -z "$1" ]]; then
  echo "Usage: $0 <search_string>"
  exit 1
fi

search_string="$1"

for pid in /proc/[0-9]*; do
  if [[ -e "$pid" ]]; then
    result=$(ls -al "$pid/fd" 2>/dev/null | grep "$search_string")
    if [[ -n "$result" ]]; then
      process_name=$(cat "$pid/comm" 2>/dev/null)
      echo "PID: $(basename $pid) - Process Name: $process_name"
    fi
  fi
done

拷贝脚本到节点上运行,输入参数是待解挂的挂载点路径名字符串(这里是b943671a-fd85-4687-84f5-c88e49a0339a)

代码语言:javascript复制
# ./find_pid.sh b943671a-fd85-4687-84f5-c88e49a0339a
PID: 2499756 - Process Name: loglistener

如果容器内的进程还存在,还可以通过pid的cgroup找到该进程对应的容器ID以及对应的pod:

代码语言:javascript复制
# cat /proc/2499756/cgroup | grep pids
8:pids:/kubepods/burstable/pod3afd6ff6-5151-4afa-b62c-e58d4bc35413/83a9e3006ac35e8c19bc4d98b373f9224fcfbf445b7809c8646e040a3f27f676
# docker ps | grep 83a9e300
83a9e3006ac3        hkccr.ccs.tencentyun.com/images/test-pod               "/docker-entrypoint.…"    31 hours ago        Up 31 hours                             k8s_test-pod-xp6vw_kube-system_3afd6ff6-5151-4afa-b62c-e58d4bc35413_0 

# docker inspect 83a9e3006ac3  | grep -i pid
            "Pid": 2499756,  

进入容器同样可以查看:

代码语言:javascript复制
进入容器
#docker exec -ti 83a9e3006ac3 bash 
容器镜像如果没有lsof命令同样可以通过查看进程的fd找到其打开的文件路径
# ls /proc/1/fd -al | grep b943671a-fd85-4687-84f5-c88e49a0339a
lr-x------ 1 root root 64 Nov 21 15:39 17 -> /rootfs/var/lib/kubelet/pods/b943671a-fd85-4687-84f5-c88e49a0339a/volumes/kubernetes.io~csi/test-pv/mount/log/test.log

0 人点赞