深入浅析docker中的overlay式网络
创始人
2024-11-20 09:04:00
0次

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

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...