015docker默认bridage模式详解

一、

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

bridge模式如下图所示:

#我本地启动了2个容器
docker pull ubuntu
docker pull nginx

root@arun:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e81696ccf7db ubuntu "bash" 16 minutes ago Up 16 minutes ubuntu-default
64e678f0dc2e nginx "/docker-entrypoint.…" 49 minutes ago Up 49 minutes 80/tcp nginx-default

#(2)从宿主机上看
#其中的docker0为网桥,ens33是vm的网卡,最后的两个veth即为两个容器对应的在docker0上的虚拟网卡,如上图所示;
root@arun:~# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:79ff:fe9e:56d1  prefixlen 64  scopeid 0x20<link>
        ether 02:42:79:9e:56:d1  txqueuelen 0  (Ethernet)
        RX packets 17271  bytes 730406 (730.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17954  bytes 47369915 (47.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.31.95  netmask 255.255.255.0  broadcast 192.168.31.255
        inet6 fe80::20c:29ff:fed0:2fa9  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:d0:2f:a9  txqueuelen 1000  (Ethernet)
        RX packets 113793  bytes 141872357 (141.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42423  bytes 3327679 (3.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 292  bytes 27086 (27.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 292  bytes 27086 (27.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth9151ca7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::98f7:91ff:fe22:cf0e  prefixlen 64  scopeid 0x20<link>
        ether 9a:f7:91:22:cf:0e  txqueuelen 0  (Ethernet)
        RX packets 12356  bytes 677385 (677.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12517  bytes 36370839 (36.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vetha32505c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c8c2:b6ff:fee4:38cd  prefixlen 64  scopeid 0x20<link>
        ether ca:c2:b6:e4:38:cd  txqueuelen 0  (Ethernet)
        RX packets 4915  bytes 294815 (294.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5468  bytes 11001466 (11.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
root@arun:~# apt install bridge-utils
root@arun:~# brctl show
bridge name bridge id STP enabled    interfaces
docker0 8000.0242799e56d1 no        veth9151ca7
                                    vetha32505c

二、可以从docker网络设备管理看出,都哪些容器插到了bridge docker0上:

root@arun:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
405a37e19268   bridge    bridge    local
3a788fcf07b7   host      host      local
ab45462b6b41   none      null      local
#从以下可以看到有哪两个容器连接到了bridage0上:
root@arun:~# docker network inspect 405a37e19268
        "Containers": {
            "64e678f0dc2e27041c5d0f329a485c4b1d0585e9a9f4db6e6b51de10f08d66d7": {
                "Name": "nginx-default",
                "EndpointID": "ac7df1259dc70e52f45946d6905510909b27c2681cacb5ea43b7d33194b95dd6",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "e81696ccf7db9a1fbd3ea199afa7b646fdcd82b1431a387264cdbafd0ad5be7a": {
                "Name": "ubuntu-default",
                "EndpointID": "a8befcf9167c7433a985dee31eef23cf2024c04de8da100ffefbfb27439ac9ec",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

三、查看目前的iptables的nat规则

root@arun:~# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 465 packets, 52845 bytes)
 pkts bytes target     prot opt in     out     source               destination
  374 45844 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 392 packets, 48259 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 191 packets, 14474 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 191 packets, 14474 bytes)
 pkts bytes target     prot opt in     out     source               destination
   63  3876 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0

四、Ubuntu容器网络探索

docker exec -it ubuntu-default /bin/bash

root@e81696ccf7db:/# cat /etc/resolv.conf
nameserver 192.168.31.1
nameserver 114.114.114.114

root@e81696ccf7db:/# ping www.baidu.com -c 1
PING www.a.shifen.com (182.61.200.6) 56(84) bytes of data.
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=1 ttl=52 time=99.5 ms

#可以看到是通过docker0网桥和如上的iptables来实现的网络的转发
root@e81696ccf7db:/# traceroute 192.168.31.1
traceroute to 192.168.31.1 (192.168.31.1), 30 hops max, 60 byte packets
 1  172.17.0.1 (172.17.0.1)  0.093 ms  0.022 ms  0.016 ms
 2  XiaoQiang (192.168.31.1)  0.762 ms  0.983 ms  0.721 ms

 五、二层通信

root@64e678f0dc2e:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255

root@64e678f0dc2e:/# arp -a
? (172.17.0.3) at 02:42:ac:11:00:03 [ether] on eth0
? (172.17.0.1) at 02:42:79:9e:56:d1 [ether] on eth0
root@64e678f0dc2e:/# arp -e
Address                  HWtype  HWaddress           Flags Mask            Iface
172.17.0.3               ether   02:42:ac:11:00:03   C                     eth0
172.17.0.1               ether   02:42:79:9e:56:d1   C                     eth0

 

#Reference: 

https://time.geekbang.org/column/article/64948

https://segmentfault.com/a/1190000040335988 

 

posted @ 2022-01-09 19:16  arun_yh  阅读(376)  评论(0编辑  收藏  举报