管理 Swarm 服务网络

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

集群和流量类型

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

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

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

关键网络概念

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

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

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

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

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

    docker_gwbridgenetwork 在您初始化时自动创建,或者 加入一个 Swarm。大多数用户不需要自定义其配置,但 Docker 允许您这样做。

提示

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

防火墙注意事项

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

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

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

覆盖网络

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

  • 一个名为ingress,它处理控制和数据流量 与 Swarm 服务相关。当您创建 swarm 服务但不创建 将其连接到用户定义的覆盖网络,则连接到ingressnetwork 的 NETWORK 中。
  • 一个名为docker_gwbridge,它将个人 Docker 守护进程分配给参与召集的其他守护进程。

创建叠加网络

要创建叠加网络,请指定overlay驱动程序docker 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
    }
]

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

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

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

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

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

注意

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

叠加网络大小限制

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

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

配置应用程序数据的加密

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

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

注意

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

将服务附加到覆盖网络

要将服务连接到现有的覆盖网络,请将--networkflag 设置为docker service create--network-addflag 设置为docker service update.

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

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

要查看服务连接到哪些网络,请使用docker service ls找到 服务的名称,然后docker service ps <service-name>列出 网络。或者,要查看哪些服务的容器连接到 网络, 使用docker network inspect <network-name>.您可以运行以下命令 从加入 Swarm 并位于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创建新服务或更新现有 一。

自定义入口网络

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

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

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

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

  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. 使用--ingress标志以及 自定义选项。此示例将 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.driver.mtu=1200 \
      my-ingress
    

    注意

    您可以将ingressnetwork 以外的其他内容ingress,但您只能有一个。尝试创建第二个 失败。

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

自定义 docker_gwbridge

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

您需要具有brctl作系统上安装的应用程序 命令删除现有网桥。包名称为bridge-utils.

  1. 停止 Docker。

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

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

  4. 创建或重新创建docker_gwbridgebridge 替换为您的自定义设置。 此示例使用子网10.11.0.0/16.有关可定制的完整列表 选项中,请参阅 Bridge 驱动程序选项

    $ 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 本身以及 从服务容器。

您可以通过传递 这--data-path-addr标志。如果有 多个接口 /--advertise-addr必须显式指定,并且--data-path-addr默认为--advertise-addr如果未指定。流量 加入、离开和管理 Swarm 将通过--advertise-addrinterface 的 API 和服务容器之间的流量 在--data-path-addr接口。这些标志可以采用 IP 地址或 网络设备名称,例如eth0.

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

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

此示例加入由 host 管理的 swarm192.168.99.100:2377并设置--advertise-addrflag 设置为eth0--data-path-addrflag 设置为eth1.

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

在覆盖网络上发布端口

连接到同一叠加网络的 Swarm 服务有效地暴露了所有 端口。对于可在服务外部访问的端口,该 port 必须使用-p--publish标记docker 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。

了解更多信息