Docker Bridge0

首先我们使用下面命令查看网络信息:

[vagrant@localhost ~]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
dce12ad15e67        bridge              bridge              local
be63d9693f78        host                host                local
d1c04eee03c8        none                null                local

今天要讨论的就是Linux的bridge网络。
之前我们使用ip a命令查看宿主机网络接口的时候,返回结果如下:

1: lo:  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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:5f:94:78 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
       valid_lft 76814sec preferred_lft 76814sec
    inet6 fe80::5054:ff:fe5f:9478/64 scope link
       valid_lft forever preferred_lft forever
3: docker0:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:08:96:2b:f9 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
    inet6 fe80::42:8ff:fe96:2bf9/64 scope link
       valid_lft forever preferred_lft forever
59: vetha65affd@if58:  mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 5a:31:ef:f0:fb:64 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::5831:efff:fef0:fb64/64 scope link
       valid_lft forever preferred_lft forever

其中的veth开头的网络接口就是上一节介绍的veth-pair接口中的其中一个,而另外一个就是容器中的veth网络接口。如当前宿主机中已经启动的容器busybox1的网络接口信息如下:

[vagrant@localhost ~]$ sudo docker exec aec1c356e72c ip a
1: lo:  mtu 65536 qdisc noqueue 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
58: eth0@if59:  mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

其中的eth0端口就是容器与宿主主机中的veth接口组成一对的网络接口,这也是容器可以连接上互联网的原因。而实际上容器也是通过这对veth接口最终连接上了宿主机的docker0端口,为了验证这句话,这里使用brctl工具,这个工具要先安装一下:

sudo yum install bridge-utils

安装以后,执行brctl show命令:

vagrant@localhost ~]$ brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.024208962bf9   no      vetha65affd

上面输出表明宿主机docker0接口和宿主机的vetha65affd接口的关系。
容器和互联网通信的网络如下:


Docker Bridge0_第1张图片
image.png

由上图可知一个linux主机通过eth0接口连接互联网,容器显示连接到docker0,然后通过NAT(network address transtation,网络地址转换),最后通过eth0接口连接互联网。实际上两个容器通过veth-pair连接的过程中也是通过docker0关联的。

深入

之前我们执行sudo docker network ls来查看宿主机网络信息:
[vagrant@localhost ~]$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
dce12ad15e67 bridge bridge local
be63d9693f78 host host local
d1c04eee03c8 none null local
当我们创建一个容器后,容器就会自动连接到bridge网络上。此外,我们可以使用命令,让容器不连接到bridge网络上,而是连接到我们自己创建的网络上,请看下面:

  1. 首先创建一个名为my-bridge网络
sudo docker network create -d bridge my-bridge

结果如下:

[vagrant@localhost ~]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
dce12ad15e67        bridge              bridge              local
be63d9693f78        host                host                local
ec80468730b6        my-bridge           bridge              local
d1c04eee03c8        none                null                local

我们使用brctl show命令来查看bridge信息,除了docker0这个bridge信息外,还有一个我们新创建的bridge:my-bridge:

[vagrant@localhost ~]$ brctl show
bridge name bridge id       STP enabled interfaces
br-ec80468730b6     8000.02420153f2be   no
docker0     8000.024208962bf9   no      vetha65affd

可以看出新创建的network此时还没有其他容器对其连接。

  1. 创建容器的时候连接到自己创建的bridge
    现在我们新创建一个容器,并将这个容器连接到my-bridge上,而不是默认的docker0上:
docker run -d --name my-busybox --network my-bridge hub.c.163.com/library/busybox:latest /bin/sh -c "while true;do sleep 3600;done"

此时:

[vagrant@localhost ~]$ brctl show
bridge name bridge id       STP enabled interfaces
br-ec80468730b6     8000.02420153f2be   no      veth2f2686c
docker0     8000.024208962bf9   no      vetha65affd

可以看到此时我们新增的network已经有容器的veth网络端口连接上了。
我们也可以使用:

docker network inspect ec80468730b6

命令来查看具体的网络信息,最后一个参数为network id,在返回的json串中有一段:

"Containers": {
            "9189e44ffc8026c63216343126e43dbfec455a212beff342df64c70242c98c9d": {
                "Name": "my-busybox",
                "EndpointID": "1254c2f18629884fdbdcfa2d0cc9f790c1d2de679e9b90417de7e4d4b18873e6",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },

表示连接到这个network的容器信息,可以看到就是我们新创建的容器my-busybox。

3.修改已运行的容器连接到其他的bridge:

docker network connect my-bridge test1

上述命令将正在运行的test1容器网络端口连接到my-bridge。修改连接后,再次执行:

docker network inspect ec80468730b6

结果中Containers部分多了个test1容器的信息。另外,原来test1容器连接的docker0这个bridge网络interface信息中还是保留了连接,即一个容器可以连接到多个bridge上。
还需要注意的是当两个容器连接到了同一个bridge上,则两个容器之间就可以相互ping通。

你可能感兴趣的:(Docker Bridge0)