容器化时代如何调试容器内线程

容器化时代服务都是运行在一个个权限较低的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 hotfix7b5f22758bf7        registry.cn-ha./xxxx/# docker inspect -f '{{.State.Pid}} {{.Id}}' $(docker ps -q)|grep 7b5f22758bf714734 7b5f22758bf7ecf002e8aa3a418aef0593a4048f07c4297fde08cd7004facaba

进入namespace应用调试工具

sudo nsenter -t 14734 -m -p gdb -p 1