当前位置: 首页 > 工具软件 > Pipework > 使用案例 >

Docker 网络(七)——使用pipework理解容器间网络

孙辰阳
2023-12-01

7 使用pipework理解容器间网络

使用Pipework来手工创建Docker网络
首先启动一个不带网络的容器

ubuntu@ubuntu:~$ docker run -it --rm --net none --name testbri ubuntu:14.04 bash
root@9149d27f1306:/# ip -d link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 

在另一个终端中使用pipework创建一个网桥 br0,为容器分配一个IP地址,从容器到主机设置正确的路由。

ubuntu@ubuntu:~$ sudo pipework br0 testbri 192.168.1.10/24@192.168.1.254
[sudo] password for ubuntu: 
Warning: arping not found; interface may not be immediately reachable

在容器中可以看到eth1已经开启,路由信息也配好

root@9149d27f1306:/# ip -d link show eth1
129: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 4a:81:42:00:ca:b5 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    veth 
root@9149d27f1306:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.254   0.0.0.0         UG    0      0        0 eth1
192.168.1.0     *               255.255.255.0   U     0      0        0 eth1

在主机上可以看到br0的网络

ubuntu@ubuntu:~$ ip -d link show br0
128: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 86:20:dd:61:af:e5 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    bridge 
ubuntu@ubuntu:~$ brctl  show
bridge name bridge id    STP enabled    interfaces
br0  8000.8620dd61afe5  no   veth1pl606
docker0  8000.000000000000  no

现在容器内到br0的网络是通的,但到外部还不通,因为NAT还没配置

$ sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE
现在容器内部就可以跟外网通信了。

我们看一下pipework命令都做了哪些工作
* 在主机上创建网桥 br0
* 分配IP地址 192.168.1.254
* 在容器内创建接口,并分配IP192.168.1.10
* 在容器内添加路由,设置网桥 为默认网关。

接下来我们不使用pipework,使用命令一步步实现pipework的功能
* 删除已经存在的br0

ubuntu@ubuntu:~$ sudo ip link set br0 down
ubuntu@ubuntu:~$ sudo brctl delbr br0
  • 创建br0,分配IP
ubuntu@ubuntu:~$ sudo brctl addbr br0
ubuntu@ubuntu:~$ sudo ip addr add 192.168.1.254/24 dev br0
ubuntu@ubuntu:~$ sudo ip link set dev br0 up
  • 创建 veth 对foo, bar,foo连接在br0 上
ubuntu@ubuntu:~$ sudo ip link add foo type veth peer name bar
ubuntu@ubuntu:~$ sudo brctl addif br0 foo
ubuntu@ubuntu:~$ sudo ip link set foo up

查看一下我们创建的网桥和端口

ubuntu@ubuntu:~$ ip -d link show

131: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether e2:2d:a9:0f:e1:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    bridge 
132: bar: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 56:5b:ae:2d:5d:83 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    veth 
133: foo: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether e2:2d:a9:0f:e1:00 brd ff:ff:ff:ff:ff:ff promiscuity 1 
    veth 
ubuntu@ubuntu:~$ brctl  show
bridge name bridge id    STP enabled    interfaces
br0  8000.e22da90fe100  no   foo
docker0  8000.000000000000  no

我们已经完成了一部分,在我们使用 --net none启动容器时,会创建一个网络命名空间,除了loopback外没有别的设备,现在我们
想去添加接口、设置路由,我们需要找到这个命名空间的ID。Docker保存的位置是 /var/run/docker/netns,这是一个非默认的位置,
为了让ip 工具正确运行,我们需要创建一个软链接 /var/run/docker/netns/var/run/netns,这是ip 工具查找网络命名空间的默认
位置,完成之后我们就可以列出已存在的网络命名空间,容器的命名空间ID就是容器的ID。

ubuntu@ubuntu:~$ cd /var/run
ubuntu@ubuntu:/var/run$ sudo ln -s /var/run/docker/netns netns
ubuntu@ubuntu:/var/run$ sudo ip netns
a2065be4c72e
default
ubuntu@ubuntu:/var/run$ NID=a2065be4c72e

现在我们把 bar veth放到容器的命名空间中,并配置ip和MAC地址。

ubuntu@ubuntu:~$ sudo ip link set bar netns $NID
ubuntu@ubuntu:~$ sudo ip netns exec $NID ip link set dev bar name eth1
ubuntu@ubuntu:~$ sudo ip netns exec $NID ip link set eth1 address 12:34:56:78:9a:cd
ubuntu@ubuntu:~$ sudo ip netns exec $NID ip link set eth1 up
ubuntu@ubuntu:~$ sudo ip netns exec $NID ip addr add 192.168.1.1/24 dev eth1
ubuntu@ubuntu:~$ sudo ip netns exec $NID ip route add default via 192.168.1.254

至此就完成了pipework命令所完成的工作了,现在到容器里看一下已经可以跟外部通信了。

 类似资料: