©
本文档使用
php.cn手册 发布
Docker群体会生成两种不同的流量:
控制和管理平面流量:这包括群管理消息,例如加入或离开群体的请求。此流量始终加密。
应用程序数据平面流量:这包括集装箱流量和往返于外部客户端的流量。
本主题讨论如何管理群集服务的应用程序数据。有关通用群集网络的更多详细信息,请参阅Docker网络参考架构。
以下三种网络概念对群集服务非常重要:
覆盖网络管理参与群集的Docker守护进程之间的通信。您可以创建覆盖网络,与独立容器的用户定义网络相同。您也可以将服务附加到一个或多个现有覆盖网络,以启用服务到服务的通信。覆盖网络是使用overlay
网络驱动程序的Docker网络。
该入口网络是一个特殊的覆盖网络,便于服务的节点之间的负载均衡。当任何swarm节点在已发布的端口上收到请求时,它将该请求交给一个名为的模块IPVS
。IPVS
跟踪参与该服务的所有IP地址,选择其中的一个,并通过ingress
网络将请求路由到它。该ingress
网络时自动创建初始化或加入一个群。大多数用户不需要定制其配置,但Docker 17.05和更高版本允许您这样做。
该docker_gwbridge是一个桥接网络连接覆盖网(包括ingress
网络)到单个码头工人守护进程的物理网络。默认情况下,服务运行的每个容器都连接到其本地Docker守护程序主机的docker_gwbridge
网络。该docker_gwbridge
网络时自动创建初始化或加入一个群。大多数用户不需要定制其配置,但是Docker允许您这样做。
参与swarm的Docker守护进程需要通过以下端口相互通信的能力:
端口7946
TCP / UDP用于容器网络发现。
4789
容器覆盖网络的端口UDP。
要创建覆盖网络,请overlay
在使用该docker network create
命令时指定驱动程序:
$ docker network create \ --driver overlay \ my-network
上述命令没有指定任何自定义选项,所以Docker分配一个子网并使用默认选项。您可以看到有关使用网络的信息docker network inspect
。
当没有容器连接到覆盖网络时,其配置并不令人兴奋:
$ docker network inspect my-network[ { "Name": "my-network", "Id": "fsf1dmx3i9q75an49z36jycxd", "Created": "0001-01-01T00:00:00Z", "Scope": "swarm", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [] }, "Internal": false, "Attachable": false, "Ingress": false, "Containers": null, "Options": { "com.docker.network.driver.overlay.vxlanid_list": "4097" }, "Labels": null }]
在上面的输出中,请注意,驱动程序是覆盖的,并且范围是swarm,而不是您可能在其他类型的Docker网络中看到的本地,主机或全局范围。 该范围表示只有参与群体的主机才能访问此网络。
网络的子网和网关是在服务首次连接到网络时动态配置的。以下示例显示了与上述相同的网络,但有三个容器的redis
服务连接到它。
$ docker network inspect my-network[ { "Name": "my-network", "Id": "fsf1dmx3i9q75an49z36jycxd", "Created": "2017-05-31T18:35:58.877628262Z", "Scope": "swarm", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "10.0.0.0/24", "Gateway": "10.0.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "Containers": { "0e08442918814c2275c31321f877a47569ba3447498db10e25d234e47773756d": { "Name": "my-redis.1.ka6oo5cfmxbe6mq8qat2djgyj", "EndpointID": "950ce63a3ace13fe7ef40724afbdb297a50642b6d47f83a5ca8636d44039e1dd", "MacAddress": "02:42:0a:00:00:03", "IPv4Address": "10.0.0.3/24", "IPv6Address": "" }, "88d55505c2a02632c1e0e42930bcde7e2fa6e3cce074507908dc4b827016b833": { "Name": "my-redis.2.s7vlybipal9xlmjfqnt6qwz5e", "EndpointID": "dd822cb68bcd4ae172e29c321ced70b731b9994eee5a4ad1d807d9ae80ecc365", "MacAddress": "02:42:0a:00:00:05", "IPv4Address": "10.0.0.5/24", "IPv6Address": "" }, "9ed165407384f1276e5cfb0e065e7914adbf2658794fd861cfb9b991eddca754": { "Name": "my-redis.3.hbz3uk3hi5gb61xhxol27hl7d", "EndpointID": "f62c686a34c9f4d70a47b869576c37dffe5200732e1dd6609b488581634cf5d2", "MacAddress": "02:42:0a:00:00:04", "IPv4Address": "10.0.0.4/24", "IPv6Address": "" } }, "Options": { "com.docker.network.driver.overlay.vxlanid_list": "4097" }, "Labels": {}, "Peers": [ { "Name": "moby-e57c567e25e2", "IP": "192.168.65.2" } ] }]
有些情况下,您不想使用覆盖网络的默认配置。有关可配置选项的完整列表,请运行该命令docker network create --help
。以下是一些最常见的更改选项。
默认情况下,网络的子网和网关在第一个服务连接到网络时自动配置。使用--subnet
和--gateway
标志创建网络时,您可以配置这些设置。以下示例通过配置子网和网关扩展了前一个示例。
$ docker network create \ --driver overlay \ --subnet 10.0.9.0/24 \ --gateway 10.0.9.99 \ my-network
与群体有关的管理和控制平面数据始终是加密的。有关加密机制的更多详细信息,请参阅Docker群集模式覆盖网络安全模型。
swarm节点之间的应用程序数据默认不加密。要在给定的覆盖网络上加密此流量,请使用此--opt encrypted
标志docker network create
。这使得vxlan级别的IPSEC加密成为可能。这种加密会带来不可忽视的性能损失,所以您应该在生产中使用它之前对其进行测试。
要将服务附加到现有的重叠网络,请将--network
标志传递给docker service create
或将--network-add
标志传递给docker service update
。
$ docker service create \ --replicas 3 \ --name my-web \ --network my-network \ nginx
连接到覆盖网络的服务容器可以通过它相互通信。
要查看服务连接到哪个网络,请使用docker服务ls查找服务的名称,然后使用docker service ps <service-name>列出网络。 或者,要查看哪些服务的容器连接到网络,请使用docker网络检查<network-name>。 您可以从任何加入到swarm并处于运行状态的swarm节点运行这些命令。
服务发现是Docker用来将来自服务的外部客户端的请求路由到单个群集节点的机制,无需客户端需要知道有多少节点参与服务或其IP地址或端口。您不需要发布在同一网络上的服务之间使用的端口。例如,如果您有一个将其数据存储在MySQL服务中的WordPress服务,并且它们连接到相同的覆盖网络,则不需要将MySQL端口发布到客户端,只需发布WordPress HTTP端口。
使用虚拟IP(VIP)或DNS循环(DNSRR),服务发现可以以两种不同的方式工作。您可以配置此服务。
默认情况下,当您将服务附加到网络并且该服务发布一个或多个端口时,Docker会为该服务分配一个虚拟IP(VIP),这是客户端到达该服务的“前端”。Docker保存服务中所有工作节点的列表,并在客户端和其中一个节点之间路由请求。来自客户端的每个请求可能会路由到不同的节点。
如果您将服务配置为使用DNS轮询(DNSRR)服务发现,则不会有单个虚拟IP。相反,Docker会为服务设置DNS条目,以便服务名称的DNS查询返回一个IP地址列表,并且客户端直接连接到其中的一个。在您想使用自己的负载均衡器的情况下,DNS循环法很有用。要配置服务以使用DNSRR,请--endpoint-mode dnsrr
在创建新服务或更新现有服务时使用该标志。
大多数用户从不需要配置ingress
网络,但Docker 17.05和更高版本允许您这样做。如果自动选择的子网与网络中已存在的子网冲突,或者需要自定义其他低级网络设置(如MTU),则此功能非常有用。
定制ingress
网络涉及到删除和重新创建网络。这通常在群体中创建任何服务之前完成。如果您有现有的发布端口的服务,则需要先删除这些服务,然后才能删除ingress
网络。
在没有ingress
网络存在的时间内,不发布端口的现有服务将继续运行,但没有负载平衡。这会影响发布端口的服务,例如发布端口80的WordPress服务。
使用检查ingress
网络docker network inspect ingress
,并删除任何容器连接到它的服务。这些是发布端口的服务,例如发布端口80的WordPress服务。如果所有这些服务都未停止,则下一步将失败。
删除现有的ingress
网络:$ docker network rm ingress警告!在删除路由网格网络之前,请确保群集中的所有节点运行相同的码头引擎版本。否则,删除可能无效,新建入口网络的功能将受到影响。你确定你要继续吗?Y / N
使用该--ingress
标志创建一个新的覆盖网络,以及要设置的自定义选项。本示例将MTU设置为1200,将子网设置为10.11.0.0/16
,并将网关设置为10.11.0.2
。$ docker network create \ -d overlay \ --ingress \ --subnet = 10.11.0.0 / 16 \ --gateway = 10.11.0.2 \ --opt com.docker.network.mtu = 1200 \ my-ingress 注意:您可以为你的ingress
网络命名除了ingress
,但你只能有一个。尝试创建第二个将失败。
重新启动您在第一步中停止的服务。
这docker_gwbridge
是一个将覆盖网络(包括ingress
网络)连接到单独的Docker守护进程物理网络的虚拟桥。当您初始化群集或将Docker主机加入群集时,Docker会自动创建它,但它不是Docker设备。它存在于Docker主机的内核中。如果您需要自定义其设置,则必须在将Docker主机加入群集之前或临时从群集中暂时删除主机之后执行此操作。
您需要brctl
在您的操作系统上安装该应用程序才能删除现有的网桥。包名是bridge-utils
。
停止Docker。
使用该brctl show docker_gwbridge
命令检查是否存在调用的桥接设备docker_gwbridge
。如果是这样,请使用它brctl delbr docker_gwbridge
。
启动Docker。不要加入或初始化群体。
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 \ docker_gwbridge
初始化或加入群。
默认情况下,所有swarm流量都通过相同的接口发送,包括控制和管理流量,以维护swarm本身以及数据流量进出服务容器。
在Docker 17.06及更高版本中,可以--datapath-addr
在初始化或加入群集时通过传递该标志来分隔此流量。如果有多个接口,则--advertise-addr
必须明确指定,如果未指定--datapath-addr
,--advertise-addr
则默认为。关于加入,离开和管理群的--advertise-addr
流量将通过接口发送,并且服务容器之间的流量将通过--datapath-addr
接口发送。这些标志可以采用IP地址或网络设备名称,例如eth0
。
这个例子初始化一个独立的swarm --datapath-addr
。它假定您的Docker主机有两个不同的网络接口:10.0.0.1应该用于控制和管理流量,192.168.0.1应该用于与服务相关的流量。
$ docker swarm init --advertise-addr 10.0.0.1 --datapath-addr 192.168.0.1
这个例子加入了由主机管理的swarm 192.168.99.100:2377
,并将--advertise-addr
标志设置为eth0
,并将--datapath-addr
标志设置为eth1
。
$ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2d7c \ --advertise-addr eth0 \ --datapath-addr eth1 \ 192.168.99.100:2377
将服务部署到群集
群体管理指南
Docker CLI参考
Swarm模式教程
Docker网络参考架构