容器化时代如何调试容器内线程
容器化时代服务都是运行在一个个权限较低的 docker 外部,当服务异样是很难在 docker 内执行 gdb、perf 等调试工具去进行运行时剖析,此时咱们须要登录到 pod 所在的 node 节点的宿主机上以 root 权限来进行调试。
装置 nsenter
yum install util-linux
什么是 nsenter
一个最典型的用处就是进入容器的网络命令空间。相当多的容器为了轻量级,是不蕴含较为根底的命令的,比如说 ip address,ping,telnet,ss,tcpdump “ 等等命令,这就给调试容器网络带来相当大的困扰:只能通过 docker inspect ContainerID 命令获取到容器 IP,以及无奈测试和其余网络的连通性。这时就能够应用 nsenter 命令仅进入该容器的网络命名空间,应用宿主机的命令调试容器网络。此外,nsenter 也能够进入 mnt, uts, ipc, pid, user 命令空间,以及指定根目录和工作目录。
原理
namespace 是 Linux 中一些过程的属性的作用域,应用命名空间,能够隔离不同的过程。
Linux 在一直的增加命名空间,目前有:
- mount:挂载命名空间,使过程有一个独立的挂载文件系统,始于 Linux 2.4.19
- ipc:ipc 命名空间,使过程有一个独立的 ipc,包含音讯队列,共享内存和信号量,始于 Linux 2.6.19
- uts:uts 命名空间,使过程有一个独立的 hostname 和 domainname,始于 Linux 2.6.19
- net:network 命令空间,使过程有一个独立的网络栈,始于 Linux 2.6.24
- pid:pid 命名空间,使过程有一个独立的 pid 空间,始于 Linux 2.6.24
- user:user 命名空间,是过程有一个独立的 user 空间,始于 Linux 2.6.23,完结于 Linux 3.8
- cgroup:cgroup 命名空间,使过程有一个独立的 cgroup 控制组,始于 Linux 4.6
Linux 的每个过程都具备命名空间,能够在 /proc/PID/ns 目录中看到命名空间的文件描述符。
应用
nsenter [options] [program [arguments]]
options:
-t, --target pid:指定被进入命名空间的指标过程的 pid
-m, --mount[=file]:进入 mount 命令空间。如果指定了 file,则进入 file 的命令空间
-u, --uts[=file]:进入 uts 命令空间。如果指定了 file,则进入 file 的命令空间
-i, --ipc[=file]:进入 ipc 命令空间。如果指定了 file,则进入 file 的命令空间
-n, --net[=file]:进入 net 命令空间。如果指定了 file,则进入 file 的命令空间
-p, --pid[=file]:进入 pid 命令空间。如果指定了 file,则进入 file 的命令空间
-U, --user[=file]:进入 user 命令空间。如果指定了 file,则进入 file 的命令空间
-G, --setgid gid:设置运行程序的 gid
-S, --setuid uid:设置运行程序的 uid
-r, --root[=directory]:设置根目录
-w, --wd[=directory]:设置工作目录
如果没有给出 program,则默认执行 $SHELL。
查找容器的 PID
# docker ps|grep hotfix
7b5f22758bf7 registry.cn-ha./xxxx/
# docker inspect -f '{{.State.Pid}} {{.Id}}' $(docker ps -q)|grep 7b5f22758bf7
14734 7b5f22758bf7ecf002e8aa3a418aef0593a4048f07c4297fde08cd7004facaba
进入 namespace 应用调试工具
sudo nsenter -t 14734 -m -p gdb -p 1