目录
Docker namespace
在linux中namespace相当于一个空间. 这个空间放任意的系统资源, 比如进程, 用户账号,文件系统网络等等. 一旦某个系统资源被放到 namespace 中那么其他的namespace就看不到了, 被隔离起来了, 再操作系统层面看各个namespace下面会有很多进程号相同的进程, 但是在用户的层面看, 就只能看到当前用户的namespace下面的进程, 所以每个namespace下面类似于一个子系统,
docker的LXC虚拟化技术就是通过 namespace 实现系统资源隔离, 把容器需要的账号, 网络资源,文件系统等等放入对应的容器
再加上 cgroup 限制资源做资源控制就成了一个容器.
Veth pair和 linux bridge
veth pair 是不同容器之间也就是不同namespace 之间进行网络通信的手段, veth pair 可以把一个 network namespace 里面的数据转发到另一个 network namespace 的 veth, 会把两个namespace 打通. 实现两个容器点对点的传输
要是想实现交换传输就要借助于网桥(linux bridge)了, 这里网桥充当了交换机的角色, 打通各个namespace, 但是 linux bridge 本身也是有ip地址的, 所以其实 linux bridge 承担路由转发的功能.
查找 veth 和容器的对应关系
docker通过 veth pair 来链接容器和docker 0 网桥, 那么 我怎么知道哪个veth 对应是哪个容器呢?
先启动两个容器
[docker@VM_121_116_centos ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79a22e5c7139 java_ssh "/bin/bash" 13 days ago Up 13 days 0.0.0.0:22588->8080/tcp dreamy_rubin
9ff2e033a096 java "/bin/bash" 13 days ago Up 13 days 0.0.0.0:22580->8080/tcp kind_brahmagupta
执行 bridge link 命令查一下看 docker0 的 veth, 有两个 veth
[docker@VM_121_116_centos ~]$ bridge link
33: veth484a82e state UP @(null): <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2
41: vethedc7768 state UP @(null): <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2
查看IP信息, 也发现有两个 veth
[docker@VM_121_116_centos ~]$ ip addr
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:02:81:43 brd ff:ff:ff:ff:ff:ff
inet 10.105.121.116/18 brd 10.105.127.255 scope global eth0
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:0d:f7:1b:95 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
33: veth484a82e@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether aa:86:9f:a9:e1:e5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
41: vethedc7768@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 16:f1:1c:6d:d2:42 brd ff:ff:ff:ff:ff:ff link-netnsid 1
到这里我们知道有两个容器, 也有两个veth, 但是不知道谁对应的是谁.
接下来我们找一下容器(79a22e5c7139)对应的是这两个veth的那一个?
首先看看容器(79a22e5c7139)的进程号是 8378, PID和namespace是一致的, 8378 就是容器运行对应的 namespace
[docker@VM_121_116_centos ~]$ docker inspect -f '{{.State.Pid}}' 79a22e5c7139
8378
docker把创建的网络命这是因为默认docker把创建的网络命名空间链接文件隐藏起来了,导致
ip netns
命令无法读取, 所以我们首先使用 ls 建立链接, 把它恢复出来之后在刚刚查询的PID所在的namespace执行 ip netns
[root@VM_121_116_centos netns]# mkdir -p /var/run/netns
[root@VM_121_116_centos netns]# ln -s /proc/8378/ns/net /var/run/netns/8378
[root@VM_121_116_centos netns]# ip netns exec 8378 ethtool -S eth0
NIC statistics:
peer_ifindex: 41
看到得到的结构是41和之前 查看的IP信息对比, 得到容器(79a22e5c7139)的 eth0 对应的 veth 是 vethedc7768@if40