docker 的 namespace

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

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

pid

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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]

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

1
2
3
4
5
6
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 这个虚拟机网卡桥接在宿主机的网卡上,是看到外部的网络流量情况的

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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

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