Docker 容器的常用网络模式与容器之间互访

Docker 容器的常用网络模式与容器之间互访

开一篇文章记录一下 Docker 的网络相关,查资料费半天劲还没几个讲的易懂的,不如自己整理一篇作为备忘。

Docker 里创建的容器默认有三种联网方式,分别为 bridge,host 和 none 模式,使用 docker network ls 命令可以查看,如下图:

Docker 默认会自动生成一个名为 docker0 的网桥, 一般情况下如果不进行特别指定,所有创建的容器默认都会走此网桥,使用 bridge 模式联网。

在此模式下,容器可以单向连接外网,外网设备(宿主机这类)需要访问容器的话,则需要容器设定对应的端口映射。

用通俗易懂来说的话,默认 bridge 联网模式就类似一个名字为 docker0 ,网关地址为 172.17.0.1 的路由器,所有容器则都连接在这个路由器上,随机分配 IP 地址,IP 地址范围为 172.17.0.2—172.17.0.254。

容器之间的通信可以直接使用内网 IP 地址进行,但默认这个 “路由器” 的缺点也十分明显,无法给容器设定固定 IP。在有多个容器存在的情况下,由于启动有先后,因此会造成容器 IP 地址出现变化。


而 host 模式则等同于容器直接使用物理机网络,这种联网模式需要创建容器时手动指定参数,宿主机的 IP 就是容器的 IP,端口也可以直接调用。

此模式的缺点是容易造成宿主机和容器端口冲突,而且降低了安全性,在有多个容器的情况下使用也不方便,一般此模式很少使用。


最后则是 none 模式,也就是容器默认不联网的模式,此模式实际一般也不用,了解一下即可。

另外还有两种更高级的网络模式,overlay 和 macvlan,分别用于跨宿主机的容器通信和给每个容器分配一个 mac 地址,这两个模式初期基本用不到,本文也不作解释。


接着再来说一下多个容器之间如何互相访问,默认情况下容器之间本身可以通过 docker0 网桥分配的 IP 地址互访,但由于无法固定 IP,日常使用起来并不方便。

Docker 本身也有一个 link 指令,可以用于连接两个容器,但这命令的缺点是只能单向连接,也就是 A 和 B 两个容器,只能 A 访问 B 或者 B 访问 A,做不到 AB 之间直接同时互访。

因此一般情况下,更推荐使用创建新网络的方法来配置容器,创建新网络的指令格式为:

 docker network create 网络名称

后面可以跟随指令,例如:

 docker network create -d bridge newnet

上面这句命令里,-d 就不是后台运行的意思了,而是指定网络类型的,意思是创建的新网络类型为 bridge,命名为 newnet。

当然一般情况下创建网络时不需要刻意指定类型,默认创建的就是 bridge 类型,除非有特殊需求才需要用-d 指令,这里只是作为演示提一下。

运行后会看到一串网络 ID,这个 ID 的作用和容器以及镜像 ID 一样,都是用于标记识别。再使用 docker network ls 命令查看网络,可以看到一个新的名为 newnet 的网络。

如果创建时不指定 IP 段,那么新创建的网络 IP 段会顺着默认网络依次顺延,默认 IP 段为 172.17.0.0/16,那新创建的 newnet 网络的 IP 段也就是 172.18.0.0/16,如下图所示:

查看 docker 网络信息的命令格式为:docker network inspect 网络名称或 ID

假如再创建一个 newnet2 网络,那么可以看到 IP 段顺次下来为 172.19.0.0/16,如下图所示:

如果想删除网络的话,命令格式为 docker network rm 网络名称或 ID,比如想删除 newnet 网络,那么命令就是: docker network rm newnet,或者 docker network rm 6e3d70683005,都是一样的效果,和管理镜像与容器的指令其实一个路子。

注:IP 后面跟着一个斜杠+数字,比如/16 这种的,表示子网掩码位数,可以区分 IP 段类型,/16 就是子网有 16 个一(二进制),剩余全为零,而子网一共分为 4 段,每段 8 位,所以二进制写出来也就是: 11111111.11111111.00000000.00000000
而 8 个二进制的 1 也就等于十进制的 255,转换成十进制也就是:255.255.0.0
整个 172.17.0.0/16 的 IP 包含范围是 172.17.0.0~172.17.255.255,去掉首尾两个特殊地址,实际可分配 IP 范围为 172.17.0.1~172.17.255.254

除了默认按顺序分配,创建网络时同样可以指定 IP 段,命令格式为:

docker network create --subnet=192.168.1.0/24 testnet

上面这句话的意思为创建一个名为 testnet 的网络,类型为默认 bridge,IP 段为 192.168.1.0~192.168.1.255 ,实际可分配 IP 范围为 192.168.1.1~192.168.1.254

实际运行结果如下图所示:

创建完了网络之后,如果需要指定容器使用对应的网络,则只需创建时加上--network --ip 指令即可,作为例子,这里创建一个 centos 容器,名称为 centos7,指定 ip 为 192.168.1.10,连接到上面创建的 testnet 网络,整个命令如下:

docker run -dit --name=centos7 --network testnet --ip 192.168.1.10 centos:7

创建之后使用 docker inspect 指令查看容器信息,可以看到对应 IP 地址就是设定好的 192.168.1.10:

另外对于连接在同一个自定义网络上的容器,互访时可以直接使用容器名字+端口,比如在另一个容器里直接 ping 上面创建的 centos7 容器,是完全没问题的:


创建时还可以再额外设定别名,加上 --network-alias 参数即可,这样容器互访时还使用别名+端口的形式。

编辑于 2019-12-20 15:44