docker网络管理基础
docker网络管理基础
docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下几种网络模式:
- bridge模式:使用–net =bridge指定,默认设置;
- host模式:使用–net =host指定;
- none模式:使用–net =none指定;
- overlay模式:使用–net=overlay
1 bridge模式
1.1 docker0默认网桥
在一台未经特殊网络配置的centos上,安装完成docker之后,使用ifconfig可以看到,多了一块docker0的网卡。
$ ifconfig
...
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:2fff:fe7a:e0db prefixlen 64 scopeid 0x20<link>
ether 02:42:2f:7a:e0:db txqueuelen 0 (Ethernet)
RX packets 3968669 bytes 644580844 (614.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3679538 bytes 3512842547 (3.2 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
宿主机也会在路由表上,增加一条到达该网络的静态路由。
$ route -n
...
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
此条路由表示,所有目的地址为 172.17.0.0/16 的数据包都会从网卡docker0发出。
在同一台主机创建容器时,默认所有的容器都会连接到docker0的网桥上,因此可以经过该网桥互相通信。
我们可以创建两个容器,测试其连通性:
# 创建con1容器,并前台运行bash
docker run -it --rm --name con1 centos bash
# 使用新终端创建con2容器,并前台运行bash
docker run -it --rm --name con2 centos bash
# 在两台容器中安装 net-tools 工具,就可以使用ifconfig查看ip地址了。
yum install net-tools -y
# 查看con1容器地址
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.4 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:4 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:04 txqueuelen 0 (Ethernet)
RX packets 5376 bytes 15075293 (14.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4207 bytes 259962 (253.8 KiB)
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 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 查看con2容器地址
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.5 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:5 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:05 txqueuelen 0 (Ethernet)
RX packets 5274 bytes 15068941 (14.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4011 bytes 247650 (241.8 KiB)
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 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 在con1上ping con2的IP地址
ping 172.17.0.5
PING 172.17.0.5 (172.17.0.5) 56(84) bytes of data.
64 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.094 ms
64 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.039 ms
# 在con2上ping con1的IP地址
ping 172.17.0.4
PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data.
64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.015 ms
通过上面的测试,我们可以看到:所有创建的容器都默认使用了docker0网桥的地址,他们之间可以互相通信。
1.2 自定义bridge网桥
除了docker0网桥,我们还可以使用管理网桥
新建docker1网桥并设置网络地址
docker network create --driver=bridge --subnet=172.28.0.0/16 docker1
我们可以查看刚刚创建的docker1网络
docker network ls
NETWORK ID NAME DRIVER SCOPE
6c778f1a00da bridge bridge local
47aa85cb2147 docker1 bridge local
e813918a0518 host host local
2f770562addf none null local
使用ifconfig可以看到,多了一块docker1的网卡。
$ ifconfig
...
br-47aa85cb2147: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.28.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:8f:66:27:d1 txqueuelen 0 (Ethernet)
RX packets 13301740 bytes 213883897891 (199.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13301740 bytes 213883897891 (199.1 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
宿主机也会在路由表上,增加一条到达该网络的静态路由。
$ route -n
...
172.28.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-47aa85cb2147
创建容器时,使用 –network 指定使用docker1网桥即可。
docker run -it --rm --network docker1 --name con1 centos bash
类似的,我们也可以查看容器IP地址
$ yum install net-tools -y
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.28.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe1c:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:1c:00:02 txqueuelen 0 (Ethernet)
RX packets 5535 bytes 15110921 (14.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4370 bytes 301924 (294.8 KiB)
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 0 (Local Loopback)
RX packets 72 bytes 6599 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 72 bytes 6599 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
使用默认bridge模式,可以满足简单的通信需求。其与外界通信时,需要进行端口映射,在复杂场景下,存在很多限制。
2 host模式
在host网络模式下,docker使用宿主机的网络、IP、端口等信息,但容器的其他信息,如文件系统、进程等还是和宿主机隔离的。
创建 host 模式的容器
docker run -it --rm --network host --name con1 centos bash
查看其IP地址
$ yum install net-tools -y
$ ifconfig
...
其结果应当与宿主机的网络完全一致。
host模式可以简单的解决容器与外界通信的地址转换问题,可以直接使用宿主机的IP,不存在使用虚拟化网络带来的额外性能问题。但host模式也降低了容器与容器之间、容器与宿主机之间的隔离性,存在一定的安全隐患。对于集群规模不大的内网环境下,可以考虑使用该方案。
3 none模式
在none模式下,docker容器没有进行任何网络配置。需要用户自己为docker容器增加网卡,配置IP等信息。在这种模式下,如果不配置相关网络是无法使用的,但同时也给了用户最大的自由度来配置网络环境。
创建 host 模式的容器
docker run -it --rm --network none --name con1 centos bash
此时,容器只有loopback网卡,因此无法进行 yum install等需要网络的操作,需要自行配置网络与路由。
4 overlay模式
overlay模式一般是用来处理容器跨主机通信的问题。在使用过程中,需要一个额外的配置存储服务,如Consul、etcd、ZooKeeper等。还需要修改docker的启动参数,来指定所使用的配置存储服务地址。
关于overlay网络在跨主机通信中的使用,我们将在以后详细讨论。
参考资料
- docker的网络模式,https://blog.csdn.net/qq_41961805/article/details/90647692
- Docker容器与容器云(第2版) 浙江大学SEL实验室著 P110