docker环境下面一般缺省配置有三个网络类型:
- bridge
- host
- none
缺省情况下,每一种网络类型都会创建一个同名网络。
这里我们介绍bridge网络。
在docker环境下bridge网络是最常用的网络模式,可以控制在一个bridge网络内的container互相连通,不同bridge的container互相隔离。
- 缺省bridge网络
docker安装完之后缺省创建一个bridge网络,对应的网络接口就是docker0
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
30ad283d2b88 bridge bridge local
0900a7fe3411 host host local
c60923002052 none null local
查看bridge网络的地址:
$ docker network inspect bridge
[
{
"IPAM": {
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
在主机上查看网络接口docker0的信息:
$ ifconfig
docker0: flags=4163 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 ...
ether ...
...
- 加入container到bridge网络
任意启动一个container,因为手头有zookeeper的image,就直接起了。
$ docker run --rm -dit zookeeper
5d93fafaba2ae819ef54b2a14e59ac78696b9f15a27bf00ff39076db14fb9078
注意bridge也是所有container的缺省网络,如果在创建container的时候没指定网络,那么系统就会自动加入到bridge网络中。(--network用来指定网络)
查看container的地址:
$ docker exec -it 5d93fafaba2ae819ef54b2a14e59ac78696b9f15a27bf00ff39076db14fb9078 bash
bash-4.4# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
...
bash-4.4# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
我们可以看到container使用的IP地址是172.17.0.2,网关地址是172.17.0.1。
那么172.17.0.1是谁呢,前面我们已经知道了,就是网卡docker0的地址,就是bridge的地址。所以在docker里面会把信息默认发送到网关172.17.0.1,即网关的地址,从而实现网络内的互通功能。
再查看docker中标准的container地址:
$ docker network inspect bridge
[
{
"Containers": {
"5d93fafaba2ae819ef54b2a14e59ac78696b9f15a27bf00ff39076db14fb9078": {
"Name": "unruffled_lovelace",
"EndpointID": "...",
"MacAddress": "...",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
这就说明container里面eth0的地址就是172.17.0.2了。
再来查看bridge信息:
请先安装bridge-utils:sudo apt-get install bridge-utils
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242919ae797 no vethed80010
这里面有一个重要信息,就是vethed80010的interface,我们查看他的信息:
$ ifconfig
vethed80010: flags=4163 mtu 1500
inet6 fe80::8072:3ff:fe53:60d1 prefixlen 64 scopeid 0x20
ether 82:72:03:53:60:d1 txqueuelen 0 (Ethernet)
...
我们再来看ip link的输出:
$ ip link
...
26: vethed80010@if25: mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT
link/ether 9a:0f:4d:07:72:db brd ff:ff:ff:ff:ff:ff link-netnsid 2
进入container里面再执行:
root@c60c61dcd4ac:/# ifconfig
eth0: flags=4163 mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 51 bytes 10580 (10.3 KiB)
RX errors 0 dropped 37 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@c60c61dcd4ac:/# ip link
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
25: eth0@if26: mtu 1500 qdisc noqueue state UP mode DEFAULT
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
这个地方我们清楚的看到主机上网卡和container内部的网卡的一对映射关系:
- 主机上:26: vethed80010@if25
- 容器里:25: eth0@if26
我们知道在bridge模式下,每启动一个container都会创建一个interface对,这一对interface,一端就是container里面的eth0,另一端就是这个vethXXXX的interface,而且各自都标识了对端。
所以这个vethXXXX就是container内部的eth0在主机上的映射。因为每创建一个container都会在主机的ifconfig和brctl show的输出中多出一条内容。
- 自创建bridge网络
docker network create my-network
每一个自创建的网络,在主机上都有一个"br-"开头的interface;这和缺省bridge网络一样,只不过bridge使用的interface名字也叫bridge,不以br-开头,而自定义的网络使用br-开头罢了:
NETWORK INTERFACE
bridge bridge
my-network br-945148bc5539
my-network2 br-e0ba2220542b
...
这个bridge充当了路由转发的功能,保证同一个bridge网络的container都能够互相通信。