【Docker 那些事儿】容器网络(下篇)
🌟 前言
上一篇文章讲了 Docker 的 none 网络和 host 网络,本篇文章将继续承接上一篇,继续深入容器的网络
1. container 网络
container 是容器网络中一种较为特殊的网络模式。
这个模式指定新创建的容器和已经存在的容器共享一个网络命名空间,而不是和宿主机共享。
新创建的容器没有自己的网卡、IP 地址等,而是和一个指定的容器共享 IP 地址、端口号等。
这两个容器之间不存在网络隔离,而这两个容器与宿主机以及其他容器之间存在网络隔离。如图所示👇
下面搭建一个 container 网络模型并查看效果,首先创建一个普通容器,示例代码如下:
以上示例创建了一个被命名为 test1 的 BusyBox 容器,此时该容器的网络模式默认为 bridge。
创建完成后,在容器终端中查看容器 IP 信息,示例代码如下:
以上示例中,通过查看容器 IP 信息得知该容器 IP 地址为 172.17.0.2。
下面创建一个网络模式为 container 的容器,示例代码如下:
以上示例创建了一个被命名为 test-container 的 BusyBox 容器,它与先前的 test1 容器共享网络空间。
其中,在配置 container 网络时,需要添加与新容器共享网络命名空间的容器名称。
下面在 test-container 容器终端中查看其 IP 信息,示例代码如下:
从以上示例中可以看到,容器 test-container 与容器 test1 的 IP 地址是一样的,但不排除容器 test1 在创建之后自动崩溃,新的容器 test-container 沿用了它的 IP 地址的可能。
下面在宿主机终端中查看容器信息,示例代码如下:
以上示例说明这两个容器已经进行了网络空间共享。此时,两个容器之间已经可以进行通信。
2. 多节点容器网络
Docker 多节点网络模式可以分为两种:一种是 Docker1.19 版本开始引入的基于 VxLAN(Virtual extensible Local Area Network,虚拟可扩展局域网)的对跨界点网络的原生支持;
另一种是通过插件方式引入的第三方实现方案,如 Flannel、Calico 等。
🍑 Overlay 网络
Overlay 网络是一种实现设备间联通的虚拟网络,Docker1.19 版本中,增加了对 Overlay 网络的原生支持。
Docker 还支持 Consul、etcd 和 ZooKeeper3 种分布式存储。
其中,etcd 是一个支持高可用的分布式存储系统,通常 etcd 处理的数据都是控制数据,应用数据是在数据量很小但更新访问频繁的情况下使用 etcd;而 Consul 作为一个分布式数据库用于保存网络状态信息。
在 Docker 中,Overlay 网络用于连接不同计算机上的 Docker 容器,允许不同计算机上的容器相互通信,同时支持对消息进行加密;
当用户初始化一个集群或是将容器加入到一个集群中时,在 Docker 主机上会出现两种网络:一种是名为 ingress 的 Overlay 网络,用于传递集群服务的控制或数据消息,若在创建容器集群服务时没有指定连接用户自定义的 Overlay 网络,集群将会加入到默认的 ingress 网络。
另一种名为 docker_gwbridge 的桥接网络会连接容器集群中所有独立的 Docker 系统进程。
Overlay 网络架构如图所示👇
🍑 部署 Overlay 网络
Overlay 网络环境部署需要准备三台机器,其中一台(192.168.56.135)安装分布式数据库,这里以 Consul 为例,另外两台(192.168.56.144 / 192.168.56.145)创建网络,架构如图所示👇
在 Docker 环境下部署 Overlay 网络之前需要先创建 Consul 数据库,具体步骤如下:
1、三台机器部署 Docker 环境,主机名与 IP 地址如表所示:
2、选择一台作为 Consul 服务器用以安装 Consul,此处以 IP 地址为 192.168.56.135 的服务器为例。
这里直接使用镜像的方式启动 Cousul 容器部署 Consul 服务,示例代码如下:
上述示例在第一台宿主机中运行了一个 Cousul 容器。
下面使用浏览器访问 192.168.56.135:8500,查看 Consul,如图所示👇
3、修改两台机器的 Docker daemon 配置文件,示例代码如下:
以上示例中,--cluster-store 指定 Consul 的地址,--cluster-advertise 告知 Consul 该节点的连接地址,192.168.56.135 为 Consul 主机。
将配置文件配置成功之后,使用重启 Docker 的命令会报错。
需要先将配置文件重新加载,再重启 Docker,示例代码如下:
4、查看 Consul 端信息
用浏览器访问 Consul 主页,在 "KEY/VALUE" 下查看两个节点,这就是自动注册到 Consul 数据库中的节点,如图所示👇
在 Consul 页面中看到图所示结果,即表示 Consul 分布式数据库搭建完成。
下面开始构建 Overlay 网络。
5、在一台节点主机中创建 Overlay 网络,示例代码如下:
注意,此处的 -d 参数用以指定创建 Overlay 网络。
下面查看网络是否创建成功,示例代码如下:
从以上示例中可以看到,已经成功创建了一个名为 ov-test 的 Overlay 网络。
下面切换到另一台节点主机查看网络信息,示例代码如下:
以上示例中,在另一台节点主机中也能够看到 Overlay 网络。
这是因为网络类型为 global,即同时可以在多台节点主机查看到该网络,创建网络时,主机将信息存入 Consul 中,另一台主机会读取到新网络信息,同时,在主机上对网络的操作会同步到 Consul 中。
6、在网络中运行容器。
在 Docker-1 中运行一个容器,查看并测试其网络,示例代码如下:
以上示例中,新建容器可以连通外网,并且容器有两个网卡,一个 eth0,连接 Overlay 网络,另一个 eth1,连接主机的 docker_gwbridge,为访问外网的容器提供出口。
在另一台 Docker-2 中运行容器,查看并测试其网络,示例代码如下:
以上示例中,Docker-2 与 Docker-1 中的容器可以 ping 通。
这是因为在同一个 Overlay 网络下的容器使用 eth0 网卡通信,使用 eth1 网卡访问外网。
7、在 Docker-2 主机中创建一个 Overlay 网络,示例代码如下:
以上示例新创建了一个名为 ov-test2 的 Overlay 网络。
在新的网络中创建一个容器,并测试其能否与 ov-test 网络中的容器互通,示例代码如下:
以上示例中,10.0.0.2 为 ov-test 网络中容器的 IP 地址,却无法 ping 通。这是因为不同 Overlay 网络中的容器在正常情况下是无法互相通信的,并且不同 Overlay 网络之间是隔离的。
要让两个 Overlay 网络中的容器通信,可以将其中一个容器连到另一个容器所在的 Overlay 网络中,示例代码如下:
以上示例将 ov-test2 网络中的 test3 容器连接到 ov-test 网络。
下面回到 test3 容器终端,再次尝试连接 ov-test 网络中的容器,示例代码如下:
以上示例中,test3 容器连接到 ov-test 网络中之后,即可 ping 通 ov-test 网络中的所有容器。
8、IP 地址管理
Overlay 网络默认分配的子网为 10.0.X.0/24,用户也可以通过 --subnet 指定 IP 地址范围,示例代码如下:
以上示例创建了一个被命名为 ov-test3 的 Overlay 网络,并将其网段指定为 10.8.8.0/24。
下面在 ov-test3 网络中创建一个容器,并查看其 IP 地址,示例代码如下:
以上示例中,由于在创建 Overlay 网络时指定了 10.8.8.0/24 的网段,在网络中新建的容器分配到了指定网段的 IP 地址。
3. Macvlan 网络
Macvlan 网络可以实现 Docker 容器的跨主机通信。
通过为物理网卡额外添加 MAC(Media Access Control,媒体存取控制)地址的形式来复用物理网卡,也就是说 Macvlan 网络直接使用服务器上的网卡让不同主机上的容器进行通信。
创建 Macvlan 网络的原理是,在宿主机物理网卡上虚拟出多个子网卡,通过不同的 MAC 地址在数据链路层(Date Link Layer)进行网络数据转发,如图所示👇
下面通过 docker network create 命令创建网络模式为 Macvlan 的容器网络。
在创建时,用户无须手动为网卡添加 MAC 地址,但是必须明确指定使用的子网掩码(subnet)、网关(gateway)以及所使用的父网卡。
首先,在两台服务器上分别创建 Macvlan 网络,示例代码如下:
以上示例分别在 Docker-1 与 Docker-2 两台服务器上创建了 Macvlan 网络,并指定了 Macvlan 网络的子网掩码与网关。
其中,parent 指定了流量在 Docker 主机上实际通过的接口。
然后分别在主机 Docker-1 与 Docker-2 中的 Macvlan 网络中创建容器,并查看其 IP 地址,示例代码如下:
注意,在 Macvlan 网络模式下创建容器一定要指定 IP 地址,否则容易造成 IP 地址冲突。
最后使用以上两个容器中任意一个容器终端 ping 另外一个容器,测试其连通性,示例代码如下:
从以上示例可以看出,两个容器已经可以互相通信。
4. 小结
本章详细系统地介绍了 Docker 容器的网络结构,包括 none 网络、host 网络、bridge 网络、container 网络以及跨主机容器的网络。 相信通过本章的学习能够熟练掌握 Docker 容器网络技术。
版权声明: 本文为 InfoQ 作者【飞向星的客机】的原创文章。
原文链接:【http://xie.infoq.cn/article/c4ea53ba283174cf2e59f5672】。文章转载请联系作者。
评论