docker进程的Namespace信息是在宿主机上以文件形式存在的
    查看当前正在运行的 Docker 容器的进程号(PID)

    1. docker inspect --format '{{ .State.Pid }}' CID

    查看宿主机的proc文件,可看到该进程对应的所有Namespace文件

    ls -l  /proc/PID/ns
    

    image.png
    通过对比各资源的namespace是否相同,可判断不同进程是否共享了同一个Namespace对应的文件,例如下面两个进程就共享了同一个网络空间
    image.png
    一个进程加入到某个进程的namespace中,就可以达到进入该进程所在容器的目的,就是docker exec的实现原理。加入namespace操作依赖setns()这个Linux系统调用,调用方法参考set_ns.c,argv1是当前进程要加入NS文件的路局,argv2是需要在加入NS中运行的进程,例如/bin/bash

    #define _GNU_SOURCE
    #include <fcntl.h>
    #include <sched.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0)
    
    int main(int argc, char *argv[]) {
        int fd;
    
        fd = open(argv[1], O_RDONLY);
        if (setns(fd, 0) == -1) {
            errExit("setns");
        }
        execvp(argv[2], &argv[2]); 
        errExit("execvp");
    }
    

    编译运行

    gcc -o set_ns set_ns.c 
    $ ./set_ns /proc/25686/ns/net /bin/bash 
    $ ifconfig  通过返回结果可以判断是容器中的网络设备
    eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
              inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
              inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:12 errors:0 dropped:0 overruns:0 frame:0
              TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0 
              RX bytes:976 (976.0 B)  TX bytes:796 (796.0 B)
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)