定制docker0

默认地,docker服务会在linux内核新建一个网络桥接docker0,使得物理主机和其他虚拟网络接口之间可以传递发送数据包,因此,这表现如一个独立的网络。

docker0有一个IP地址和子网掩码,使得物理主机可以从容器的桥接网络接收和发送数据包。并且给这个桥接网络一个MTU(最大传输单元)或者说网络接口允许的最大包长度-例如1,500 bytes 或者从docker的宿主主机上的网络接口拷贝的数值。在服务启动的时候两者都是可配置的:

  • —bip=CIDR— 为docker0桥接网络提供一个特殊的IP地址和一个子网掩码, 使用标准的 CIDR 记法例如192.168.1.5/24.
  • —mtu=BYTES— 从写docker0的最大数据包长度。

在ubuntu系统上,你可以增加以上的配置到 /etc/default/docker 文件中的DOCKER_OPTS参数中,然后重启docker服务。

当你有一个或多个正常运行的容器时,你可以通过在主机上运行brct1命令,观察interfaces列的输出,来确定Docker已经将这些容器正确地连接到docker0网桥。下面是一个连接了两个不同容器的主机:

  1. $ sudo brctl show
  2. bridge name bridge id STP enabled interfaces
  3. docker0 8000.3a1d7362b4ee no veth65f9
  4. vethdda6

最后,每次新建一个容器的时候都会用到docker0 桥接网络。每次在执行docker run命令新建一个容器的时候,docker从可利用的桥接网络中随机选择一个未被使用的IP地址,以及使用桥接网络的子网掩码,用来配置容器 eth0网络接口。docker宿主主机的IP地址被docker容器作为默认的网关。

  1. $ docker run -i -t --rm base /bin/bash
  2. [root@e623fd7cf734 /] ip addr show eth0
  3. 24: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  4. link/ether 32:6f:e0:35:57:91 brd ff:ff:ff:ff:ff:ff
  5. inet 172.17.0.3/16 scope global eth0
  6. valid_lft forever preferred_lft forever
  7. inet6 fe80::306f:e0ff:fe35:5791/64 scope link
  8. valid_lft forever preferred_lft forever
  9. [root@e623fd7cf734 /] ip route
  10. default via 172.17.42.1 dev eth0
  11. 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3
  12. [root@e623fd7cf734 /] exit

建立你自己的桥接网络

如果你希望建立完整的自己的桥接网络,你可以在启动docker之前用 -b BRIDGE 或者 —bridge=BRIDGE选项参数高数docker使用你自己的桥接网络。

如果你已经用docker0启动docker了,你需要停止docker服务然后移除docker0.

  1. $ sudo service docker stop
  2. $ sudo ip link set dev docker0 down
  3. $ sudo brctl delbr docker0
  4. $ sudo iptables -t nat -F POSTROUTING

然后,在启动docker服务之前,新建你自己的桥接网络,写上你想要的配置。接下来我们新建一个简单的桥接网络,刚好用这些选项来定做docker0 ,这刚好足够说明这个技术。

  1. $ sudo brctl addbr bridge0
  2. $ sudo ip addr add 192.168.4.1/24 dev bridge0
  3. $ sudo ip link set dev bridge0 up
  4. Chain POSTROUTING (policy ACCEPT)
  5. target prot opt source destination
  6. MASQUERADE all -- 192.168.4.0/24 0.0.0.0/0

创建好网桥之后在docker配置文件中写入启动参数,或者手动指定:

  1. $ sudo docker -d --bridge=bridge0

这样我们自己定义的网桥就做好了,当利用docker run启动容器时,会自动绑定网络到bridge0上:

  1. $ sudo docker run -it --rm centos
  2. [root@e623fd7cf734 /]# ip addr
  3. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. inet 127.0.0.1/8 scope host lo
  6. valid_lft forever preferred_lft forever
  7. inet6 ::1/128 scope host
  8. valid_lft forever preferred_lft forever
  9. 40: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
  10. link/ether 02:42:c0:a8:04:02 brd ff:ff:ff:ff:ff:ff
  11. inet 192.168.4.2/24 scope global eth0
  12. valid_lft forever preferred_lft forever
  13. inet6 fe80::42:c0ff:fea8:402/64 scope link
  14. valid_lft forever preferred_lft forever

我们可以看到新的网桥已经生效。