一、跨主机网络解决方案
我们知道,Docker 的几种网络方案:none、host、bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题。
那么跨主机容器间通信的方案又有哪些呢?
跨主机网络方案包括:
1. docker 原生的 overlay 和 macvlan。
2. 第三方方案:常用的包括 flannel、weave 和 calico。
Docker 网络是一个非常活跃的技术领域,不断有新的方案开发出来,那么要问个非常重要的问题了: 如此众多的方案是如何与 docker 集成在一起的?答案是:libnetwork 以及 CNM。
libnetwork 是 docker 容器网络库,最核心的内容是其定义的 Container Network Model (CNM),这个模型对容器网络进行了抽象,由以下三类组件组成:
1.Sandbox:Sandbox 是容器的网络栈,包含容器的 interface、路由表和 DNS 设置。 Linux Network Namespace 是 Sandbox 的标准实现。Sandbox 可以包含来自不同 Network 的 Endpoint。
2.Endpoint:Endpoint 的作用是将 Sandbox 接入 Network。Endpoint 的典型实现是 veth pair,后面我们会举例。一个 Endpoint 只能属于一个网络,也只能属于一个 Sandbox。
3.Network:Network 包含一组 Endpoint,同一 Network 的 Endpoint 可以直接通信。Network 的实现可以是 Linux Bridge、VLAN 等。
如图所示两个容器,一个容器一个 Sandbox,每个 Sandbox 都有一个 Endpoint 连接到 Network 1,第二个 Sandbox 还有一个 Endpoint 将其接入 Network 2.
libnetwork CNM 定义了 docker 容器的网络模型,按照该模型开发出的 driver 就能与 docker daemon 协同工作,实现容器网络。
docker 原生的 driver 包括 none、bridge、overlay 和 macvlan,第三方 driver 包括 flannel、weave、calico 等。
Docker Swarm 内置的跨主机容器通信方案是overlay网络,这是一个基于vxlan协议的网络实现。
VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。
overlay 通过虚拟出一个子网,让处于不同主机的容器能透明地使用这个子网。所以跨主机的容器通信就变成了在同一个子网下的容器通信,看上去就像是同一主机下的bridge网络通信。
根据vxlan的作用知道,它是要在三层网络中虚拟出二层网络,即跨网段建立虚拟子网。
简单的理解就是把发送到虚拟子网地址10.0.0.3的报文封装为发送到真实IP192.168.1.3的报文。这必然会有更大的数据开销,但却简化了集群的网络连接,让分布在不同主机的容器好像都在同一个主机上一样 。
overlay网络会创建多个Docker主机之间的分布式网络。该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信。Docker透明地处理每个数据包与正确的Docker守护程序主机和正确的目标容器的路由。
初始化swarm或将Docker主机加入现有swarm时,会在该Docker主机上创建两个新网络:
1. ingress overlay 网络,处理与swarm集群服务相关的控制和数据流量。创建群组服务并且不将其连接到用户定义的覆盖网络时,服务将默认连接到ingress overlay网络。集群中只能有一个ingress overlay 网络。
2. docker_gwbridge 桥接网络,它将各个Docker守护程序连接到参与该群集的其他Docker守护进程。同时该docker_gwbridge 网络将为主机上的容器提供访问外网的能力。
# docker network ls
# docker network inspect docker_gwbridge
# docker network inspect ingress
服务或容器一次可以连接到多个网络。服务或容器只能通过它们各自连接的网络进行通信。
二、创建overlay网络
三、加密overlay网络
四、overlay 网络实现原理
docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux bridge br0,endpoint 还是由 veth pair 实现,一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上。
br0 除了连接所有的 endpoint,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的。
五、参考
从docker单机到swarm模式的网络变化
https://www.jianshu.com/p/26e13631d625
Docker Swarm管理节点高可用分析
https://zhoujinl.github.io/2018/10/19/docker-swarm-manager-ha
Docker Swarm服务调度分析
https://zhoujinl.github.io/2018/09/20/docker-swarm-scheduler