对docker中的overlay式网络详解
作者:zlw01234
翻译自docker官方文档,原文:https://docs.docker.com/network/overlay/
overlay(覆盖)式网络会在多个docker守护进程所在的主机之间创建一个分布式的网络。这个网络会覆盖宿主机特有的网络,并允许容器连接它(包括集群服务中的容器)来安全通信。显然,docker会处理docker守护进程源容器和目标容器之间的数据报的路由。
当你初始化一个集群(swarm)或把一个docker宿主机加入一个已经存在的集群时,宿主机上会新建两个网络:
一个叫ingress的overlay式网络,用来处理和集群服务相关的控制和数据传输。当你创建一个集群服务而且没有把它连到用户定义的overlay式网络时,它默认会连到ingress网络。
一个叫docker_gwbridge的bridge式网络。用来连接本docker守护进程和集群中的其他守护进程。
你可以用docker network create命令创建用户定义的overlay式网络,就和你创建用户定义的bridge式网络一样。服务和容器可以同时连到多个网络。服务和容器只能和它所在的网络中的其他对象通信。
虽然集群服务和单独的容器都能连到overlay式网络,但默认的表现和配置两者都是不同的。因此,本主题后面的内容会分成三部分:应用于所有overlay式网络的;应用于集群服务中的网络的;应用于单独的容器使用的overlay式网络的。
适用于所有overlay网络的操作
创建一个overlay网络
✅先决条件
使用overlay网络的docker守护进程需要的防火墙规则
要让一个overlay网络中的docker主机能够相互通信,你需要打开下面的端口:
1.TCP端口2377,用来集群管理相关的通信
2.TCP和UDP端口7946,用来进行节点之间的通信
3.UDP端口4789,用来进行进行overlay网络上的数据传输
在你能创建一个overlay网络之前,你要么要通过docker swarm init把你的docker守护进程初始化成一个集群管理者(swarm manager),要么要通过docker swarm join把它加入到一个已存在的集群中。
不管哪种方式,默认创建并使用的都是叫做ingress的overlay式网络。即使你不打算使用集群服务,也要这么做。
以后你可以创建用户定义的overlay式网络。
要创建一个用在集群服务中的overlay式网络,用下面所示的命令:
$ docker network create -d overlay my-overlay
要创建一个既能用于集群服务,又能用于单独的容器来和其他docker守护进程中的单独的容器进行通信的网络,加上--attachable标记:
$ docker network create -d overlay --attachable my-attachable-overlay
你可以指定IP地址范围,子网,网关和其他选项。细节请查看docker network create --help。
overlay网络上的加密传输
所有的服务管理相关的传输都默认用GCM模式的AES算法加密。集群中的管理节点每12个小时轮换加密用的键(key)。
如果要加密应用数据,在创建网络时加上--opt encrypted。这个参数支持在vxlan级别的IPSEC加密。这个操作会导致不可忽略的性能下降,所以在应用到生产环境前要先测试。
当你开启overlay加密后,docker会在所有网络中服务被调度到的节点上创建IPSEC 隧道。这些隧道也会使用GCM模式的AES算法加密,并且每12个小时自动轮换加密用的键(key)。
❌不要把Windows节点加入到加密通信的overlay网络中。
overlay网络上的加密通信不支持Windows。如果Windows节点试图连接到加密通信的overlay网络,不会报错,但这个节点会不能和其他节点通信。
集群模式的overlay网络和单独的容器
你可以用--opt encrypted --attachable或把没有被管理的容器加入到网络的方式来使用overlay网络特性。
$ docker network create --opt encrypted --driver overlay --attachable my-attachable-multi-host-network
修改默认的ingress网络
大多数用户不需要配置ingress网络。但docker17.05以及更高版本允许你这么做。如果自动选择的子网段和你网络中已存在的网络冲突了,或你需要修改其他底层的网络设置比如MTU的时候,这个功能就很有用了。
修改ingress网络需要删除再创建它。这就要求你在集群中创建服务之前完成修改。如果有发布端口的服务,在你删除ingress网络之前要先删除这些服务。
在ingress网络不存在的时候,已存在的没有发布端口的服务能继续提供服务,但没有负载均衡功能。那些发布端口的服务比如发布80端口的WordPress服务会受影响。
用docker network inspect ingress检查ingress网络,然后删除所有所在容器连到ingress的服务。这些服务是发布端口的服务比如发布80端口的WordPress服务。如果所有这些服务没有停掉,下一步会失败。
删除ingress网络。
$ docker network rm ingress
WARNING! Before removing the routing-mesh network, make sure all the nodes in your swarm run the same docker engine version. Otherwise, removal may not be effective and functionality of newly created ingress networks will be impaired.
Are you sure you want to continue? [y/N]
3.用ingress标记创建新的overlay网络,加上你想要的配置。下面的例子把MTU配置成1200,把子网设置成10.11.0.0/16,并把网关设成10.11.0.2。
$ docker network create \ --driver overlay \ --ingress \ --subnet=10.11.0.0/16 \ --gateway=10.11.0.2 \ --opt com.docker.network.mtu=1200 \ my-ingress
注意:你也可以把ingerss网络命名成其他名字,但只能有一个。如果你试图创建第二个,会失败。
4.重启你在第一步停掉的服务。
修改docker_gwbridge接口
docker_gwbridge是一个虚拟网桥,用来连接overlay网络(包括ingress网络)和一个特定的docker守护进程的物理网络。当你初始化一个集群或把一个docker宿主机加入到一个集群时,docker会自动创建它,但它不是一个docker设备。它存在于docker宿主机的内核中。如果你要修改它的配置,你必须在把宿主机加入集群前完成,或暂时把宿主机从集群中脱离。
停掉docker
删除docker_gwbridge接口
$ sudo ip link set docker_gwbridge down
$ sudo ip link del name docker_gwbridge
3.启动docker,不要加入或初始化集群
4.用docker network create命令手动创建或重新创建docker_gwbridge网桥,加上你自定义的设置。下面的例子使用10.11.0.0/16子网。
$ docker network create \ --subnet 10.11.0.0/16 \ --opt com.docker.network.bridge.name=docker_gwbridge \ --opt com.docker.network.bridge.enable_icc=false \ --opt com.docker.network.bridge.enable_ip_masquerade=true \ docker_gwbridge
5.初始化或加入集群。由于网桥已经存在,docker不会再用默认配置创建它了。
集群服务中的操作
在overlay网络上发布端口
连到同一个overlay网络的集群服务会互相暴露所有端口。如果一个端口要从服务外部可访问到,必须在docker service create或docker service update中用-p或--publish来发布。
遗留的冒号分割的语法和新的逗号分割的语法都是支持的。
更长的语法更好,因为某种意义上它是自解释的。
参数 | 描述 |
---|---|
-p 8080:80 o或-p published=8080,target=80 | 把服务内的 TCP 端口 80映射到路由中的端口8080 |
-p 8080:80/udp 或-p published=8080,target=80,protocol=udp | 把服务内的 UDP 端口 80映射到路由中的端口8080 |
-p 8080:80/tcp -p 8080:80/udp 或 -p published=8080,target=80,protocol=tcp -p published=8080,target=80,protocol=udp | 把服务内的 TCP 端口 80映射到路由中的端口8080,并把服务内的 UDP 端口 80映射到路由中的端口8080 |
为集群服务绕开路由网
默认的,集群服务通过路由网来发布端口。当你连到任一集群节点(不管它有没有运行端口所代表的服务)上的被发布的端口时,你都能重定向到运行着指定服务的节点。docker很有效的充当着你的集群服务的负载均衡器。使用路由网的服务运行在虚拟IP模式(VIP)下。即使一个服务运行在一个节点上(通过--global标记),也会使用路由网。当使用路由网时,不能保证哪个节点处理客户端的请求。
要绕开路由网,你可以用DNS Round Robin (DNSRR)模式启动服务。通过给dnsrr设置--endpoint-mode标记。你必须在服务前端运行你自己的负载均衡器。docker宿主机上的服务名的DNS查询会返回运行着指定服务的节点的IP地址集合。配置你的负载均衡器来使用这份列表并在节点间平衡通信。
分离控制流和数据流
默认的,控制流和集群管理者联系并在运行在同一网络上的应用间传输,虽然控制流是加密的。你可以配置docker,让它用不同的网络接口来处理不同的流。当你初始化或加入集群时,分别指定--advertise-addr和--datapath-addr。你必须在每个要加入集群的节点上做这个操作。
overlay网络上独立容器能用的操作
把独立容器连到overlay网络
ingress网络创建时没有指定--attachable标记,这意味着只有集群服务能使用它,独立容器不能。你可以把独立容器连到用户定义的,创建时指定了--attachablebiaoji d overlay网络。这给了运行在不同docker上的独立容器一种能力,即不需在特定docker宿主机上设置路由就能通信的能力。
发布端口
参数 | 描述 |
---|---|
-p 8080:80 | 把服务内的 TCP 端口 80映射到路由中的端口8080 |
-p 8080:80/udp | 把服务内的 UDP 端口 80映射到路由中的端口8080 |
-p 8080:80/tcp -p 8080:80/udp | 把服务内的 TCP 端口 80映射到路由中的端口8080,并把服务内的 UDP 端口 80映射到路由中的端口8080 |
以上这篇对docker中的overlay式网络详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。