docker容器和宿主机、容器与容器之间网络是互通的, 下面我们通过以下的例子来验证.
创建两个容器, 分别是box1和box2
# 拉取busybox镜像
docker image pull busybox
# 根据busybox镜像创建box1容器和box2容器
docker container run -d --rm --name box1 busybox /bin/sh -c "while true; do sleep 3600; done"
docker container run -d --rm --name box2 busybox /bin/sh -c "while true; do sleep 3600; done"
进入其中一个容器box1
docker container exec -it box1 sh
# 使用 ip addr查看容器的ip地址
ip addr
18: eth0@if19: <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 容器的ip 地址是 172.17.0.3
我们可以尝试ping 一下宿主机的ip
ping 172.19.10.234
PING 172.19.10.234 (172.19.10.234): 56 data bytes
64 bytes from 172.19.10.234: seq=0 ttl=64 time=0.115 ms
64 bytes from 172.19.10.234: seq=1 ttl=64 time=0.103 ms
64 bytes from 172.19.10.234: seq=2 ttl=64 time=0.097 ms
64 bytes from 172.19.10.234: seq=3 ttl=64 time=0.092 m
我们发现box1 是可以ping 通宿主机的.
我们退出到宿主机, 尝试ping 一下 box1.
ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.059 ms
发现也是可以 ping 通的, 这说明宿主机和容器之间的网络是互通的.
我们尝试 ping 一下容器与容器的网络
进入box2 容器, 在box2 容器里ping 一下box1 的ip
docker container exec -it box2 sh
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.130 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.104 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.101 ms
可以看出box2 是可以ping 通 box1 的
通过上面的例子可以看出, 宿主机容器之间网络是可以互通的.
创建和使用自定义bridge
在Docker中,"bridge"是一种网络模式,用于在Docker容器和主机之间创建一个虚拟网络桥接
-
- 创建自定义的bridge
docker network create -d mybridge
docker network ls
NETWORK ID NAME DRIVER SCOPE
b3fd39a8bbdb bridge bridge local
818738fdaee6 host host local
29adfe15e23f mybridge bridge local
e377484c3bd1 none null local
创建后使用 network ls 可以到我们新增的mybridge 已经在列表里.
使用 inspect 查看 mybridge
docker network inspect mybridge
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
}
可以看出mydridge 的子网是 172.18.0.0/16 , 也就是一个容器说连接到 mybridg, 会给这个容器分配一个 172.18 网段的 ip 地址.
-
- 使用自定义的bridge
默认情况下, 容器会链接docker0. 可以使用 container inspect查看
docker container inspect box2
可以在创建容器的时候指定要连接到的bridge
docker container run -d --rm --name box3 --network mybridge busybox /bin/sh -c "while true; do sleep 3600; done"
也可以使用 network connect 命令来连接
docker network connect mybridge box3
一个容器如何同时连两个网络
使用命令 container inspect box1, 我们可以看出box1 容器连了两个网络
docker container inspect box1
"Networks": {
"bridge": {
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3"
},
"mybridge": {
"Gateway": "172.18.0.1",
"IPAddress": "172.18.0.2"
}
}
进入box1 容器也可以看出, box1使用了两个网络
docker container exec -it box1 sh
ip a
89: eth0@if90: <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
93: eth1@if94: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1
valid_lft forever preferred_lft forever
连接到自定义的bridge, 可以使用容器名 ping 通, 但是连接到bridge, 不能使用容器名 ping 通
现在box1 和 box3 已经连接到了mybridge, 我们可以尝试ping 一下
docker container exec -it box1 ping box3
PING box3 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.174 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.076 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.063 ms
64 bytes from 172.18.0.3: seq=3 ttl=64 time=0.073 ms
可以看出, 直接使用容器名是可以 ping 通的. 但是如果 ping 连接到默认bridge的容器名, 是ping 不通的.
docker container exec -it box1 ping box2
ping: bad address 'box2'