..

docker 的 namespace

docker 容器最终还是运行在内核上的一个进程, 我们在容器中无法访问外部资源是因为 namespace 的隔离作用, 主要隔离的有:

  • pid # 进程
  • networkd # 网络
  • mount # 文件系统

pid

默认情况下在容器内部是无法访问外部的, 可以可以在运行容器的时候加上 --pid=host 参数让容器中的进程和宿主机器上的进程相互可见

vagrant@archlinux ~ $ docker run -it --pid=host rust:latest bash
root@bb8d7e679d1d:/# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1  29196 11860 ?        Ss   Nov19   0:04 /sbin/init
root           2  0.0  0.0      0     0 ?        S    Nov19   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   Nov19   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   Nov19   0:00 [rcu_par_gp]
root           6  0.0  0.0      0     0 ?        I<   Nov19   0:00 [kworker/0:0H-kblockd]
root           8  0.0  0.0      0     0 ?        I<   Nov19   0:00 [mm_percpu_wq]
root           9  0.0  0.0      0     0 ?        S    Nov19   0:00 [ksoftirqd/0]
root          10  0.0  0.0      0     0 ?        S    Nov19   0:00 [rcuc/0]
root          11  0.0  0.0      0     0 ?        I    Nov19   0:03 [rcu_preempt]
root          12  0.0  0.0      0     0 ?        S    Nov19   0:00 [rcub/0]
root          13  0.0  0.0      0     0 ?        S    Nov19   0:00 [migration/0]
root          14  0.0  0.0      0     0 ?        S    Nov19   0:00 [idle_inject/0]
root          16  0.0  0.0      0     0 ?        S    Nov19   0:00 [cpuhp/0]
root          17  0.0  0.0      0     0 ?        S    Nov19   0:00 [cpuhp/1]

可以看到非常多的进程,而默认情况是看不到宿主机的进程的

vagrant@archlinux ~ $ docker run -it  rust:latest bash
root@2800b475d7c6:/# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1 26.0  0.0   3872  3260 pts/0    Ss   09:13   0:00 bash
root           6  0.0  0.0   7644  2784 pts/0    R+   09:13   0:00 ps aux
root@2800b475d7c6:/#

network

默认情况下容器内部使用的是一层虚拟的网卡和网络,通过 docker0 这个虚拟机网卡桥接在宿主机的网卡上,是看到外部的网络流量情况的

root@ccb540ada1f1:/# ss
Netid           State           Recv-Q            Send-Q                       Local Address:Port                       Peer Address:Port
root@ccb540ada1f1:/# exit

可以通过在运行容器的时候加上 --network=host 的方式来让容器也宿主机器使用同一个网卡和网络空间

root@archlinux:/# ip a
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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:8f:83:2c brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 58933sec preferred_lft 58933sec
    inet6 fe80::a00:27ff:fe8f:832c/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:6d:bc:a4:1f brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:6dff:febc:a41f/64 scope link
       valid_lft forever preferred_lft forever
root@archlinux:/# ss
Netid State      Recv-Q Send-Q                                                                            Local Address:Port      Peer Address:Port
u_str ESTAB      0      0                                                                                             * 27099                * 27100
u_str ESTAB      0      0                                                                   /run/dbus/system_bus_socket 16263                * 16262
u_str ESTAB      0      0                                                                                             * 16262                * 16263
u_str ESTAB      0      0                                                                                             * 27100                * 27099
u_str ESTAB      0      0                                                                                             * 68566                * 68565
u_str ESTAB      0      0                                                                                             * 68565                * 68566
u_str ESTAB      0      0                                                                                             * 68539                * 0

这样就能看到宿主机器上的网卡信息了.