docker网络管理基础

docker网络管理基础

docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下几种网络模式:

  1. bridge模式:使用–net =bridge指定,默认设置;
  2. host模式:使用–net =host指定;
  3. none模式:使用–net =none指定;
  4. 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网络在跨主机通信中的使用,我们将在以后详细讨论。

参考资料

  1. docker的网络模式,https://blog.csdn.net/qq_41961805/article/details/90647692
  2. Docker容器与容器云(第2版) 浙江大学SEL实验室著 P110
Table of Contents