管理 Swarm 服务网络

本页介绍了 swarm 服务的联网。

集群和流量类型

Docker 群生成两种不同类型的流量:

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

  • 应用程序数据平面流量:这包括容器流量和 传入和传出外部客户端的流量。

关键网络概念

以下三个网络概念对于 Swarm 服务很重要:

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

  • 入口网络是一种特殊的覆盖网络,它有助于 服务节点之间的负载均衡。当任何 swarm 节点收到 请求,它将该请求传递给一个名为 . 跟踪参与该事件的所有 IP 地址 service 选择其中一个,然后通过网络将请求路由到该服务。IPVSIPVSingress

    当您初始化或加入 群。大多数用户不需要自定义其配置,但 Docker 允许 你这样做。ingress

  • docker_gwbridge 是连接叠加层的桥接网络 网络(包括网络)连接到单个 Docker 守护进程的 物理网络。默认情况下,服务运行的每个容器都已连接 添加到其本地 Docker 守护程序主机的网络。ingressdocker_gwbridge

    网络将在您初始化或 加入一个 Swarm。大多数用户不需要自定义其配置,但 Docker 允许您这样做。docker_gwbridge

提示

另请参阅 网络概述 有关 Swarm 网络的一般详细信息。

防火墙注意事项

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

  • 端口 TCP/UDP 用于容器网络发现。7946
  • 覆盖网络(包括入口)数据路径的端口 UDP(可配置)。4789

在 Swarm 中设置网络时,应特别小心。咨询 教程 以获取概述。

覆盖网络

初始化 swarm 或将 Docker 主机加入现有 swarm 时,两个 在该 Docker 主机上创建新网络:

  • 一个名为 的覆盖网络,用于处理控制和数据通信 与 Swarm 服务相关。当您创建 swarm 服务但不创建 Connect it to a user-defined overlay network(连接到用户定义的覆盖网络),默认情况下会连接到该网络。ingressingress
  • 一个名为 的桥接网络,它将个人 Docker 守护进程分配给参与召集的其他守护进程。docker_gwbridge

创建叠加网络

要创建覆盖网络,请在使用命令时指定驱动程序:overlaydocker network create

$ docker network create \
  --driver overlay \
  my-network

上面的命令没有指定任何自定义选项,因此 Docker 会分配一个 subnet 并使用默认选项。您可以使用 查看有关网络的信息。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
    }
]

在上面的输出中,请注意驱动程序是 ,并且范围是 ,而不是 ,或您可能在 其他类型的 Docker 网络。此范围表示只有 参与 Swarm 可以访问此网络。overlayswarmlocalhostglobal

网络的子网和网关是在服务 首次连接到网络。以下示例显示了 与上述网络相同,但具有三个服务容器 连接到它。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

配置子网和网关

默认情况下,网络的子网和网关在 第一个服务连接到网络。您可以在以下情况下配置这些 使用 AND 标志创建网络。以下内容 Example 通过配置 Subnet 和 Gateway 来扩展前一个。--subnet--gateway

$ docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  --gateway 10.0.9.99 \
  my-network
使用自定义默认地址池

要自定义 Swarm 网络的子网分配,您可以选择在 .swarm init

例如,初始化 Swarm 时使用以下命令:

$ docker swarm init --default-addr-pool 10.20.0.0/16 --default-addr-pool-mask-length 26

每当用户创建网络但不使用命令行选项时,将从池中的下一个可用子网按顺序分配此网络的子网。如果已分配指定的网络,则该网络将不会用于 Swarm。--subnet

如果需要不连续的地址空间,则可以配置多个池。但是,不支持从特定池进行分配。网络子网将从 IP 池空间按顺序分配,并且子网将在从已删除的网络中取消分配时被重用。

默认掩码长度可以配置,并且所有网络都相同。它设置为 by default。要更改默认子网掩码长度,请使用 命令行 选项。/24--default-addr-pool-mask-length

注意

默认地址池只能在集群创建后配置,并且不能更改。swarm init

叠加网络大小限制

Docker 建议使用块创建覆盖网络。覆盖网络块将网络限制为 256 个 IP 地址。/24/24

此建议解决了 swarm 模式的限制。 如果您需要的 IP 地址超过 256 个,请不要增加 IP 块大小。您可以将终端节点模式与外部负载均衡器一起使用,也可以使用多个较小的覆盖网络。有关不同终端节点模式的更多信息,请参阅配置服务发现dnsrr

配置应用程序数据的加密

与 swarm 相关的 Management Plane 和 Control Plane 数据始终是加密的。 有关加密机制的更多详细信息,请参阅 Docker swarm 模式叠加网络安全模型

默认情况下,Swarm 节点之间的应用程序数据不加密。要对此进行加密 流量,请使用 上的标志。这将在 vxlan 级别启用 IPSEC 加密。这 加密会带来不可忽略的性能损失,因此您应该对此进行测试 选项,然后再在生产中使用它。--opt encrypteddocker network create

注意

您必须自定义自动创建的 Ingress 才能启用加密。默认情况下,所有入口流量都是未加密的,因为加密 是网络级选项。

将服务附加到覆盖网络

要将服务附加到现有覆盖网络,请将标志传递给 ,或将标志传递给 。--networkdocker service create--network-adddocker service update

$ docker service create \
  --replicas 3 \
  --name my-web \
  --network my-network \
  nginx

连接到覆盖网络的服务容器可以与 彼此跨越它。

要查看服务连接到哪些网络,请使用 查找 服务的名称,然后列出 网络。或者,要查看哪些服务的容器连接到 网络,请使用 。您可以运行以下命令 从已加入 Swarm 并处于某种状态的任何 Swarm 节点。docker service lsdocker service ps <service-name>docker network inspect <network-name>running

配置服务发现

服务发现是 Docker 用来路由来自 服务的外部客户端连接到单个 Swarm 节点,而无需客户端 需要知道有多少节点参与服务或其 IP 地址或端口。您不需要发布在 服务。例如,如果您有一个 WordPress 服务,将其数据存储在 MySQL 服务, 并且它们连接到同一个叠加网络,则无需发布 客户端的 MySQL 端口,只有 WordPress HTTP 端口。

服务发现可以通过两种不同的方式工作:基于内部连接的 使用嵌入式 DNS 和虚拟 IP (VIP) 在第 3 层和第 4 层进行负载均衡, 或使用 DNS 在第 7 层进行外部和自定义的基于请求的负载均衡 轮询 (DNSRR)。您可以按服务配置此项。

  • 默认情况下,当您将服务连接到网络并且该服务发布 一个或多个端口,Docker 会为服务分配一个虚拟 IP (VIP),即 “前端”,以便客户端访问服务。Docker 保留所有 worker 节点,并在客户端和其中一个 节点。来自客户端的每个请求都可能路由到不同的节点。

  • 如果将服务配置为使用 DNS 循环 (DNSRR) 服务发现, 没有一个虚拟 IP。相反,Docker 会为 service,以便对服务名称的 DNS 查询返回 IP 列表 地址,并且客户端直接连接到其中一个地址。

    DNS 循环在您想要使用自己的负载的情况下非常有用 balancer 中,例如 HAProxy。要将服务配置为使用 DNSRR,请在创建新服务或更新现有 一。--endpoint-mode dnsrr

自定义入口网络

大多数用户永远不需要配置网络,但 Docker 允许您 执行此操作。如果自动选择的子网 与您的网络上已存在的冲突,或者您需要自定义 其他低级网络设置(如 MTU),或者如果要启用加密ingress

自定义网络包括删除和重新创建网络。这是 通常在 Swarm 中创建任何服务之前完成。如果您已有 services 发布端口,则需要先删除这些服务 删除网络。ingressingress

在不存在网络期间,不存在 发布端口继续运行,但未进行负载均衡。这会影响 发布端口的服务,例如发布端口的 WordPress 服务 80.ingress

  1. 使用 和 检查 删除其容器连接到它的所有服务。这些是服务 发布端口,例如发布端口 80 的 WordPress 服务。如果 所有此类服务都不会停止,下一步将失败。ingressdocker network inspect ingress

  2. 删除现有网络: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. 使用该标志以及 自定义选项。此示例将 MTU 设置为 1200,设置 将子网设置为 ,并将网关设置为 。--ingress10.11.0.0/1610.11.0.2

    $ docker network create \
      --driver overlay \
      --ingress \
      --subnet=10.11.0.0/16 \
      --gateway=10.11.0.2 \
      --opt com.docker.network.driver.mtu=1200 \
      my-ingress
    

    注意

    您可以将网络命名为 以外的名称,但只能有一个名称。尝试创建第二个 失败。ingressingress

  4. 重新启动您在第一步中停止的服务。

自定义 docker_gwbridge

这是连接叠加网络的虚拟网桥 (包括网络)到单个 Docker 守护程序的物理 网络。Docker 会在您初始化 swarm 或加入 Docker 主机部署到一个群中,但它不是 Docker 设备。它存在于内核中 Docker 主机的 Docker 主机。如果需要自定义其设置,则必须在之前进行自定义 将 Docker 主机加入 swarm,或在临时删除主机后 从蜂群中。docker_gwbridgeingress

您需要在操作系统上安装该应用程序 命令删除现有网桥。包名称为 。brctlbridge-utils

  1. 停止 Docker。

  2. 使用命令检查网桥是否 存在名为 的设备。如果是这样,请使用 将其删除。brctl show docker_gwbridgedocker_gwbridgebrctl delbr docker_gwbridge

  3. 启动 Docker。不要加入或初始化 swarm。

  4. 使用您的自定义设置创建或重新创建网桥。 此示例使用子网 .有关可定制的完整列表 选项中,请参阅 Bridge 驱动程序选项docker_gwbridge10.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. 初始化或加入 swarm。

对控制和数据流量使用单独的接口

默认情况下,所有 Swarm 流量都通过同一接口发送,包括 control 以及管理流量,用于维护 Swarm 本身以及 从服务容器。

您可以通过传递 初始化或加入 Swarm 时的标志。如果有 多个接口,必须显式指定,如果未指定,则默认为 。流量 加入、离开和管理群通过接口发送,服务容器之间的流量发送 通过界面。这些标志可以采用 IP 地址或 网络设备名称,例如 .--data-path-addr--advertise-addr--data-path-addr--advertise-addr--advertise-addr--data-path-addreth0

此示例使用单独的 .它假设 您的 Docker 主机有两个不同的网络接口:10.0.0.1 应该是 用于控制和管理流量,192.168.0.1 应用于 与服务相关的流量。--data-path-addr

$ docker swarm init --advertise-addr 10.0.0.1 --data-path-addr 192.168.0.1

此示例加入由 host 管理的 swarm,并将 flag 设置为 ,将 flag 设置为 。192.168.99.100:2377--advertise-addreth0--data-path-addreth1

$ docker swarm join \
  --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2d7c \
  --advertise-addr eth0 \
  --data-path-addr eth1 \
  192.168.99.100:2377

在覆盖网络上发布端口

连接到同一叠加网络的 Swarm 服务有效地暴露了所有 端口。对于可在服务外部访问的端口,该 port 必须使用 或 上的 or 标志发布。传统的冒号分隔语法和 支持较新的逗号分隔值语法。较长的语法是 首选,因为它在某种程度上是自记录的。-p--publishdocker service createdocker service update

标志值描述
-p 8080:80
-p 已发布=8080,目标=80
将服务上的 TCP 端口 80 映射到路由网格上的端口 8080。
-p 8080:80/udp or-p published=8080,target=80,protocol=udp
将服务上的 UDP 端口 80 映射到路由网格上的端口 8080。
-p 8080:80/tcp -p 8080:80/udp or-p
published=8080,target=80,protocol=tcp -p published=8080,target=80,protocol=udp
将服务上的 TCP 端口 80 映射到路由网格上的 TCP 端口 8080,并将服务上的 UDP 端口 80 映射到路由网格上的 UDP 端口 8080。

了解更多信息