Docker
容器基于 Linux namespace
技术构建,本文结合 unshare、nsenter介绍 Namespaces 如何在 Docker 中应用。
前提
关于 Linux namespace 介绍 参考这篇文章。
docker 使用 namespace 技术
$ docker run -it -d --name u1 ubuntu:20.04
ee6135372b2c6910d837f4a7549610f207a41ab437d1fea874d487cd6eb28c1f
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee6135372b2c ubuntu:20.04 "bash" 4 minutes ago Up 4 minutes u1
$ docker inspect ee6135372b2c | grep \"Pid\":
"Pid": 4191078,
$ lsns |grep 4191078
4026532776 mnt 1 4191078 root bash
4026532777 uts 1 4191078 root bash
4026532778 ipc 1 4191078 root bash
4026532779 pid 1 4191078 root bash
4026532781 net 1 4191078 root bash
$ ps -ef | grep 4191078 | grep -v grep
root 4191078 4191055 0 21:36 pts/0 00:00:00 bash
$ ps -ef | grep 4191055 | grep -v grep
root 4191055 1 0 21:36 ? 00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id ee6135372b2c6910d837f4a7549610f207a41ab437d1fea874d487cd6eb28c1f -address /run/containerd/containerd.sock
root 4191078 4191055 0 21:36 pts/0 00:00:00 bash
- 默认情况下, netns 是在
/proc/4191078/ns/net
,我们使用 ip netns ls
查找本机的 netnamespace 列表是从 /var/run/netns
目录下查找,因此,如果我们想使用 ip netns
命令查找 docker 容器的网络命名空间,可以进行如下操作:
mkdir -p /var/run/netns
ln -s /proc/4191078/ns/net /var/run/netns/4191078
此时,可以进入 network namespace 中进行相关操作:
$ ip netns ls
4191078 (id: 0)
$ ip netns exec 4191078 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
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
$ ip netns exec 4191078 ethtool -S eth0
NIC statistics:
peer_ifindex: 12 # 与默认命名空间下的 12 配对
rx_queue_0_xdp_packets: 0
rx_queue_0_xdp_bytes: 0
rx_queue_0_drops: 0
rx_queue_0_xdp_redirect: 0
rx_queue_0_xdp_drops: 0
rx_queue_0_xdp_tx: 0
rx_queue_0_xdp_tx_errors: 0
tx_queue_0_xdp_xmit: 0
tx_queue_0_xdp_xmit_errors: 0
$ ip a
...
12: veth9694ab2@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 7e:b4:2d:0d:29:8d brd ff:ff:ff:ff:ff:ff link-netns 4191078
inet6 fe80::7cb4:2dff:fe0d:298d/64 scope link
valid_lft forever preferred_lft forever
...
# 通过 brctl show,可以看到 veth9694ab2 在 docker0 bridge 上
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024238ead58d no veth9694ab2