Docker中使用GDB调试

背景

容器是一个很老的技术,但这几年却很火热。好多应用都已经容器化了,只要是在用户空间运行的,几乎都可以被容器化。就是放到docker里运行。

面对着容器里运行的应用程序它与外界隔离了,这种隔离有优点,也有缺点。今天我们不讲优点,说一说它的一个缺点。。。

如果你是在linux上写C/C++的朋友,你肯定会用到gdb这个神一样的调试工具。在当下这么火爆的容器面前,你的APP可能早就被扔到容器里了。

有一天,除了一个问题,需要你用gdb去调试一下,我靠,ns完全是隔离的,根本无法调试,火大了吧,别急!我来帮你~v~

调试方法

方法一

其实gdb调试容器内app也不难,只要做到两点就可以成功调试了。

  1. 你所使用的镜像里必须得有gdb工具,没有怎么调试啊。要么做镜像的时候将gdb安装进去,要么使你的gdb与被调试app的容器处于同一命名空间。
  2. 使用一些工具(nsenter)侵入到容器命名空间后再运行gdb调试。eg: sudo nsenter -t {容器的PID} -m -p gdb -p {容器内被调试app的PID}

方法二

方法二也需要在被调试的容器上先装有gdb,然后在启动容器的时候通过增加一些特权参数。待需要调试的时候直接登录到容器内就可以调试了。

  1. 在启动docker容器的时候需要增加--privileged参数
  2. 由于gdb调试需要的SYS_PTRACE属性被禁止掉了,所以在启动容器时候需要增加这个属性--cap-add sys_ptrace
  3. gdb调试时,需要关闭linux虚拟地址随机化(虚拟地址随机化是为了安全考虑而出现的,gdb调试只是暂时关闭)。关闭有两种方法,一是通过gdb的命令set disable-randomization off关闭。二是通过设置docker的参数--security-opt seccomp=unconfined

有此三步,可保gdb无告警,并正常使用。

参考&鸣谢