为什么同一台机器上的两个容器IP可以互相通信?
在聊这个问题之前,我们先看一个日常生活中的例子来辅助理解,Docker Bridge网络在局域网中,多台电脑要想互相通信,需要一个交换机通过动态IP协议给每个机器分配一个IP地址(IP在同一网段),并且每台电脑都有一个默认的网关IP(交换机IP),通信的话先把数据包发送到交换机上面,通过转发规则转发到目标电脑上面。
docker创建的容器默认是连接到一个接口为docker0的Bridge网络上的,我们通过以下容器去分析。
首先我们先查看一下宿主机上的网络接口,是有一个接口为docker0的Bridge(网桥)的网络。IP是172.17.0.1/16(IP为172.17.0.1的16位掩码)
# 列出宿主机的网络接口
vagrant@swarm2:~$ ip a
...........
10: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:1a:21:8e:9f 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
...........
查看当前docker提供的网络模式,可以看到有一个DRIVER为bridge(网桥)的
vagrant@swarm2:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f20354b70d12 bridge bridge local
d65e5e9c6cd0 host host local
da5483f547f5 none null local
创建两个容器(box1和box2),需要用到BusyBox这个镜像。
在创建之前,先介绍一下BusyBox,它是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Linux 系统的自带的shell。
创建box1和box2容器,并且查看他们的IP。
# 创建容器box1
vagrant@swarm2:~$ docker container run -d --rm --name box1 busybox /bin/sh -c "while true; do sleep 3600; done"
30d22a0aeffa8631d9d6592d26b95176061d753bdbc25bcdf58be3ff90c26918
# 创建容器box2
vagrant@swarm2:~$ docker container run -d --rm --name box2 busybox /bin/sh -c "while true; do sleep 3600; done"
2a4a937afe9ff6903162dd0508d1151846431fbed3bdbd0da9eb47832409dafe
# box1的IP为 172.17.0.2/16
vagrant@swarm2:~$ docker exec -it box1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
12629: eth0@if12630: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# box2的IP为 172.17.0.3/16
vagrant@swarm2:~$ docker exec -it box2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
12631: eth0@if12632: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> 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
# box1容器测试访问box2可通
vagrant@swarm2:~$ docker exec -it box1 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.122 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.098 ms
^C
--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.098/0.110/0.122 ms
# box2容器测试访问box1可通
vagrant@swarm2:~$ docker exec -it box2 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.086 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.059/0.072/0.086 ms
查看bridge的详情,IPAM->Config->Subnet、Gateway和宿主机接口docker0的IP一致
,并且Options-> com.docker.network.bridge.name值也是docker0
。
可以看到Containers里有两个容器box1(172.17.0.2/16)和box2(172.17.0.3/16)
。
vagrant@swarm2:~$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "f20354b70d12a90c76c94b84ea78bc66688b794f7d62b538f525ebaad3151f7a",
"Created": "2022-06-18T02:17:56.044977005Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"2a4a937afe9ff6903162dd0508d1151846431fbed3bdbd0da9eb47832409dafe": {
"Name": "box2",
"EndpointID": "0b2a221a7f9498ad60bbc1c7fc21821e1bb48d2953b9a1a36d369f7310c517bb",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"30d22a0aeffa8631d9d6592d26b95176061d753bdbc25bcdf58be3ff90c26918": {
"Name": "box1",
"EndpointID": "97381c28d2e8381745ed8680bf1d104149f917938e8aa66795bd8452a06fcb38",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/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": {}
}
]
Comment here is closed