获取进程或者容器ID 根据 容器 id 获取进程
1 crictl inspect -o go-template --template='{{index .info "pid"}}' ef80e5fd299001c62a1b039797c74cb9cac8bfc88488edd576ea64396c6b93ba
根据进程获取容器信息
1 2 3 ContainerID=`cat /proc/34056/cgroup | awk -F '/' '{print $NF}' | sed 's/cri-containerd-\(.*\).scope/\1/' |uniq` podName=crictl inspect -o go-template --template='{{index .status.labels "io.kubernetes.pod.name"}}' $ContainerID # crictl inspect $ContainerID # 查看容器信息
nsenter 使用 默认都有安装 yum install util-linux -y 自行安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 nsenter --help 用法: nsenter [options] <program> [<argument>...] Run a program with namespaces of other processes. 选项: -t, --target <pid> 要获取名字空间的目标进程 -m, --mount[=<file>] enter mount namespace -u, --uts[=<file>] enter UTS namespace (hostname etc) -i, --ipc[=<file>] enter System V IPC namespace -n, --net[=<file>] enter network namespace -p, --pid[=<file>] enter pid namespace -U, --user[=<file>] enter user namespace -S, --setuid <uid> set uid in entered namespace -G, --setgid <gid> set gid in entered namespace --preserve-credentials do not touch uids or gids -r, --root[=<dir>] set the root directory -w, --wd[=<dir>] set the working directory -F, --no-fork 执行 <程序> 前不 fork -Z, --follow-context set SELinux context according to --target PID -h, --help 显示此帮助并退出 -V, --version 输出版本信息并退出
eg: 进入容器的网路空间 pause 容器会共享网络等资源,进入 pause 一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@test-61 ~]# ps -ef |grep pause 65535 13324 13157 0 Aug24 ? 00:00:00 /pause [root@test-61 ~]# nsenter -t 13324 -n [root@test-61 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if66: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 32:89:55:bc:d8:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.69.0.58/24 brd 10.69.0.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::3089:55ff:febc:d8f6/64 scope link valid_lft forever preferred_lft forever
nsenter -t $PID -m -u -i -n -p /bin/sh 相当于 docker exec -it $container /bin/sh
临时容器 nsenter 的前提是能登上节点。如果只有 kubectl 权限,或者业务镜像是 distroless 这类连 shell 都没有的精简镜像,就该换成临时容器(ephemeral containers)。
临时容器:在原有的 pod 上,添加一个临时的 container,这个 container 可以包含很多需要使用到的排查工具,比如使用 busybox。
参考官方文档
1 https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/
⚠️ 注:早期笔记里写的“还是实验功能 1.16 +,需要 --feature-gates=EphemeralContainers=true”已经过时。临时容器在 Kubernetes 1.23 转为 beta 并默认开启,1.25 已正式 GA,不用再开 feature gate,直接用 kubectl debug 就行。
1 2 3 4 5 kubectl debug -it <POD_NAME> --image=busybox --target=<CONTAINER_NAME> -- sh kubectl get pod <POD_NAME> -o jsonpath='{.spec.ephemeralContainers[*].name}'
--target 指定要共享进程命名空间的目标容器,带上它才能在临时容器里看到目标容器的进程(需要容器运行时支持)。临时容器没有资源和调度保证,不能配置 ports、livenessProbe 之类的字段,也不能重启或移除,排查完重建 pod 即可。
两者适用场景对比
维度
nsenter
临时容器
前提条件
能登上节点并有 root 权限
只需 kubectl 权限,集群 1.23+(1.25 起 GA)
工具来源
节点上装的工具(yum install util-linux)
临时容器镜像自带,如 busybox、netshoot
对 pod 的影响
完全无侵入,不改 pod 对象
会给 pod 追加一个临时 container,不可移除
典型用途
抓包,看 ip addr、iptables、conntrack 等命名空间内的状态
业务镜像里没有 shell / curl / ping 时,进去看进程、文件、发请求