Docker 17
引擎 | Engine

管理群体服务网络(引擎) | Manage swarm service networks (Engine)

管理群集服务网络

Docker群体会生成两种不同的流量:

  • 控制和管理平面流量:这包括群管理消息,例如加入或离开群体的请求。此流量始终加密。

本主题讨论如何管理群集服务的应用程序数据。有关通用群集网络的更多详细信息,请参阅Docker网络参考架构

以下三种网络概念对群集服务非常重要:

  • 覆盖网络管理参与群集的Docker守护进程之间的通信。您可以创建覆盖网络,与独立容器的用户定义网络相同。您也可以将服务附加到一个或多个现有覆盖网络,以启用服务到服务的通信。覆盖网络是使用overlay网络驱动程序的Docker网络。

防火墙考虑

参与swarm的Docker守护进程需要通过以下端口相互通信的能力:

  • 端口7946TCP / 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保存服务中所有工作节点的列表,并在客户端和其中一个节点之间路由请求。来自客户端的每个请求可能会路由到不同的节点。

自定义入口网络

大多数用户从不需要配置ingress网络,但Docker 17.05和更高版本允许您这样做。如果自动选择的子网与网络中已存在的子网冲突,或者需要自定义其他低级网络设置(如MTU),则此功能非常有用。

定制ingress网络涉及到删除和重新创建网络。这通常在群体中创建任何服务之前完成。如果您有现有的发布端口的服务,则需要先删除这些服务,然后才能删除ingress网络。

在没有ingress网络存在的时间内,不发布端口的现有服务将继续运行,但没有负载平衡。这会影响发布端口的服务,例如发布端口80的WordPress服务。

  • 使用检查ingress网络docker network inspect ingress,并删除任何容器连接到它的服务。这些是发布端口的服务,例如发布端口80的WordPress服务。如果所有这些服务都未停止,则下一步将失败。

自定义docker_gwbridge

docker_gwbridge是一个将覆盖网络(包括ingress网络)连接到单独的Docker守护进程物理网络的虚拟桥。当您初始化群集或将Docker主机加入群集时,Docker会自动创建它,但它不是Docker设备。它存在于Docker主机的内核中。如果您需要自定义其设置,则必须在将Docker主机加入群集之前或临时从群集中暂时删除主机之后执行此操作。

您需要brctl在您的操作系统上安装该应用程序才能删除现有的网桥。包名是bridge-utils

  • 停止Docker。

使用单独的界面进行控制和数据通信

默认情况下,所有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

扩展内容

  • 将服务部署到群集