拓扑
本文示例的拓扑结构如下,两个容器之间有一个路由器,采用静态路由。
-----------------------
| (container C1) |
| eth0 192.168.10.2/24] |
-----------------------
^
|
v
----------------------
| eth0 192.168.10.1/24 |
| (container R1) |
| eth1 192.168.11.1/24 |
----------------------
^
|
v
-----------------------
| eth0 192.168.11.2/24] |
| (container C2) |
-----------------------
创建容器
docker run --privileged -d -t --net none --name c1 fcastello/ubuntu-network bash
docker run --privileged -d -t --net none --name r1 fcastello/ubuntu-network bash
docker run --privileged -d -t --net none --name c2 fcastello/ubuntu-network bash
查找容器的网络名称空间
# Get the container id for each container (will be needed later)
c1_id=$(docker ps --format '{{.ID}}' --filter name=c1)
r1_id=$(docker ps --format '{{.ID}}' --filter name=r1)
c2_id=$(docker ps --format '{{.ID}}' --filter name=c2)
# Get the containers pids which will be used to find their network namespace
c1_pid=$(docker inspect -f '{{.State.Pid}}' ${c1_id})
r1_pid=$(docker inspect -f '{{.State.Pid}}' ${r1_id})
c2_pid=$(docker inspect -f '{{.State.Pid}}' ${c2_id})
# create the /var/run/netns/ path if it doesn't already exist
mkdir -p /var/run/netns/
# Create a soft link to the containers network namespace to /var/run/netns/
ln -sfT /proc/$c1_pid/ns/net /var/run/netns/$c1_id
ln -sfT /proc/$r1_pid/ns/net /var/run/netns/$r1_id
ln -sfT /proc/$c2_pid/ns/net /var/run/netns/$c2_id
创建虚拟以太网接口并将其分配给容器
# Create the virtual ethernet devices for conecting C1 to R1
ip link add 'c1-eth0' type veth peer name 'r1-eth0'
# Create the virtual ethernet devices for conecting C2 to R1
ip link add 'c2-eth0' type veth peer name 'r1-eth1'
# We created the virtual ethernet pairs but they are still in the host network namespace
# we need to move each virtual interface now to the corresponding containers namespace
# move c1 interface to c1 container
ip link set 'c1-eth0' netns $c1_id
# move r1 interfaces to r1 container
# note that r1 is a router which will
# need at least 2 interfaces
ip link set 'r1-eth0' netns $r1_id
ip link set 'r1-eth1' netns $r1_id
# move c2 interface to c2 container
ip link set 'c2-eth0' netns $c2_id
# Next step is not needed but it is nice to have more standard interface names
# so we will rename interfaces inside the containers
# rename c1 container interface from c1-eth0 to eth0
ip netns exec $c1_id ip link set 'c1-eth0' name 'eth0'
# rename r1 container interfaces from r1-eth0 to eth0 and r1-eth1 to eth1
ip netns exec $r1_id ip link set 'r1-eth0' name 'eth0'
ip netns exec $r1_id ip link set 'r1-eth1' name 'eth1'
# rename c2 container interface form c2-eth0 to eth0
ip netns exec $c2_id ip link set 'c2-eth0' name 'eth0'
# bring up all interfaces in containers
ip netns exec $c1_id ip link set 'eth0' up
ip netns exec $c1_id ip link set 'lo' up
ip netns exec $r1_id ip link set 'eth0' up
ip netns exec $r1_id ip link set 'eth1' up
ip netns exec $r1_id ip link set 'lo' up
ip netns exec $c2_id ip link set 'eth0' up
ip netns exec $c2_id ip link set 'lo' up
给容器设置IP和路由
# lets set c1 container ip to 192.168.10.2
ip netns exec $c1_id ip addr add 192.168.10.2/24 dev eth0
# lets set r1 ips to 192.168.10.1 and 192.168.11.1
ip netns exec $r1_id ip addr add 192.168.10.1/24 dev eth0
ip netns exec $r1_id ip addr add 192.168.11.1/24 dev eth1
# lets set c2 container ip to 192.168.11.2
ip netns exec $c2_id ip addr add 192.168.11.2/24 dev eth0
# set default gw on c1 container
ip netns exec $c1_id ip route add default via 192.168.10.1 dev eth0
# set default gw on c2 container
ip netns exec $c2_id ip route add default via 192.168.11.1 dev eth0
清理环境
# Delete the containets
docker stop c1 c2 r1 && docker rm c1 c2 r1
# Clean up the Network namespaces links
rm /var/run/netns/$c1_id
rm /var/run/netns/$r1_id
rm /var/run/netns/$c2_id