使用叠加网络联网

本系列教程涉及 Swarm 服务的联网。 有关使用独立容器联网的信息,请参阅使用独立容器联网。如果您需要 了解有关 Docker 网络的更多信息,请参阅概述

此页面包括以下教程。您可以在 Linux、Windows 或 Mac,但对于最后一个,您需要第二个 Docker 主机在其他地方运行。

  • 使用默认覆盖网络演示 如何使用 Docker 为您设置的默认覆盖网络 在您初始化或加入 Swarm 时自动进行。此网络不是 生产系统的最佳选择。

  • 使用用户定义的叠加网络显示 如何创建和使用您自己的自定义叠加网络来连接服务。 建议对在生产环境中运行的服务执行此操作。

  • 将覆盖网络用于独立容器 展示了如何在不同 Docker 上的独立容器之间进行通信 守护程序。

先决条件

这些要求至少有一个单节点 swarm,这意味着 您已启动 Docker 并在主机上运行。您可以运行 多节点 swarm 上的示例也是如此。docker swarm init

使用默认覆盖网络

在此示例中,您将启动一项服务并检查特征 从单个服务容器的角度来看。alpine

本教程不讨论特定于操作系统的细节,介绍如何操作 叠加层网络,但重点介绍叠加层的工作原理 服务的视点。

先决条件

本教程需要三个物理或虚拟 Docker 主机,它们都可以 相互沟通。本教程假定这三台主机是 在未涉及防火墙的同一网络上运行。

这些主机将称为 、 和 。主机将同时充当 Manager 和 worker,这意味着它可以 两者都运行服务任务并管理 Swarm。 并且将 仅作为 worker 工作,managerworker-1worker-2managerworker-1worker-2

如果您手头没有 3 个主机,一个简单的解决方案是设置三个 云提供商(如 Amazon EC2)上的 Ubuntu 主机都位于同一网络上 允许与该网络上的所有主机进行所有通信(使用一种机制 例如 EC2 安全组),然后按照 Docker Engine - Ubuntu 上的社区的安装说明进行操作。

演练

创建 swarm

在此过程结束时,所有三个 Docker 主机都将加入 swarm ,并将使用名为 的覆盖网络连接在一起。ingress

  1. 上。初始化 Swarm。如果主机只有一个网络 interface 的 API 中,该标志是可选的。manager--advertise-addr

    $ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>
    

    记下打印的文本,因为其中包含 您将使用 to join 和 to the swarm。这是一个很好的 将令牌存储在密码管理器中的想法。worker-1worker-2

  2. 在 上,加入召集。如果主机只有一个网络接口, 该标志是可选的。worker-1--advertise-addr

    $ docker swarm join --token <TOKEN> \
      --advertise-addr <IP-ADDRESS-OF-WORKER-1> \
      <IP-ADDRESS-OF-MANAGER>:2377
    
  3. 在 上,加入召集。如果主机只有一个网络接口, 该标志是可选的。worker-2--advertise-addr

    $ docker swarm join --token <TOKEN> \
      --advertise-addr <IP-ADDRESS-OF-WORKER-2> \
      <IP-ADDRESS-OF-MANAGER>:2377
    
  4. 在 上,列出所有节点。此命令只能从 经理。manager

    $ docker node ls
    
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
    d68ace5iraw6whp7llvgjpu48 *   ip-172-31-34-146    Ready               Active              Leader
    nvp5rwavvb8lhdggo8fcf7plg     ip-172-31-35-151    Ready               Active
    ouvx2l7qfcxisoyms8mtkgahw     ip-172-31-36-89     Ready               Active
    

    您还可以使用 flag 按角色进行筛选:--filter

    $ docker node ls --filter role=manager
    
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
    d68ace5iraw6whp7llvgjpu48 *   ip-172-31-34-146    Ready               Active              Leader
    
    $ docker node ls --filter role=worker
    
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
    nvp5rwavvb8lhdggo8fcf7plg     ip-172-31-35-151    Ready               Active
    ouvx2l7qfcxisoyms8mtkgahw     ip-172-31-36-89     Ready               Active
    
  5. 列出 、 、 和 和 注意 上的 Docker 网络 现在,他们每个人都有一个名为 和 Bridge 的覆盖网络 网络称为 .仅显示 的列表 这里:managerworker-1worker-2ingressdocker_gwbridgemanager

    $ docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    495c570066be        bridge              bridge              local
    961c6cae9945        docker_gwbridge     bridge              local
    ff35ceda3643        host                host                local
    trtnl4tqnc3n        ingress             overlay             swarm
    c8357deec9cb        none                null                local
    

将网络连接到 Docker 主机的 网络接口,以便流量可以流入和流出 Swarm Manager 和 工人。如果您创建 swarm 服务但未指定网络,则它们是 已连接到网络。建议您使用单独的 每个应用程序或一组应用程序的覆盖网络 一起。在下一个过程中,您将创建两个叠加网络和 将服务连接到它们中的每一个。docker_gwbridgeingressingress

创建服务

  1. 在 上,创建一个名为 的新覆盖网络 :managernginx-net

    $ docker network create -d overlay nginx-net
    

    您无需在其他节点上创建覆盖网络,因为它 将在其中一个节点开始运行 service 任务。

  2. 在 上,创建一个连接到 的 5 副本 Nginx 服务 。这 service 将 80 端口发布到外部。所有服务 任务容器可以在不打开任何端口的情况下相互通信。managernginx-net

    注意

    只能在 Manager 上创建服务。

    $ docker service create \
      --name my-nginx \
      --publish target=80,published=80 \
      --replicas=5 \
      --network nginx-net \
      nginx
    

    的默认发布模式 ,当您不这样做时,将使用该模式 指定 a 作为标志,则表示如果您浏览到 、 或 上的 端口 80 ,您将连接到 端口 80 在 5 个服务任务之一上,即使当前没有任务 在您浏览到的节点上运行。如果要使用 mode 发布端口,可以添加到输出中。然而 在这种情况下,您还应该使用 instead 而不是 因为只有一个服务任务可以绑定给定节点上的给定端口。ingressmode--publishmanagerworker-1worker-2hostmode=host--publish--mode global--replicas=5

  3. Run 以监控服务启动的进度,该 可能需要几秒钟。docker service ls

  4. 检查 、 和 上的网络。 请记住,您不需要手动创建它,因为 Docker 已为您创建它。输出会很长,但是 请注意 and 部分。 列出全部 连接到覆盖网络的服务任务(或独立容器) 从该主机。nginx-netmanagerworker-1worker-2worker-1worker-2ContainersPeersContainers

  5. 从 中,检查服务使用并注意 服务。managerdocker service inspect my-nginx

  6. 创建新网络 ,然后更新服务以使用此网络 network 而不是 :nginx-net-2nginx-net

    $ docker network create -d overlay nginx-net-2
    
    $ docker service update \
      --network-add nginx-net-2 \
      --network-rm nginx-net \
      my-nginx
    
  7. 运行以验证服务是否已更新,并且所有 任务已重新部署。运行以验证 没有容器连接到它。运行相同的命令,并注意所有服务任务容器都已连接 到它。docker service lsdocker network inspect nginx-netnginx-net-2

    注意

    即使覆盖网络是在 swarm 上自动创建的 worker 节点,则不会自动删除它们。

  8. 清理服务和网络。从 中,运行以下命令 命令。经理将指示 worker 删除网络 自然而然。manager

    $ docker service rm my-nginx
    $ docker network rm nginx-net nginx-net-2
    

使用用户定义的叠加网络

先决条件

本教程假设 swarm 已经设置完毕,并且您是 Manager。

演练

  1. 创建用户定义的叠加网络。

    $ docker network create -d overlay my-overlay
    
  2. 使用覆盖网络启动服务并将端口 80 发布到端口 Docker 主机上的 8080 命令。

    $ docker service create \
      --name my-nginx \
      --network my-overlay \
      --replicas 1 \
      --publish published=8080,target=80 \
      nginx:latest
    
  3. 通过查看该部分,运行并验证服务任务是否已连接到它。docker network inspect my-overlaymy-nginxContainers

  4. 删除服务和网络。

    $ docker service rm my-nginx
    
    $ docker network rm my-overlay
    

对独立容器使用覆盖网络

此示例演示了 DNS 容器发现 -- 具体而言,如何 使用 overlay 网络。步骤包括:

  • 在 上,将节点初始化为 swarm (manager)。host1
  • 在 上,将节点加入 swarm (worker)。host2
  • 在 上,创建可附加的覆盖网络 ()。host1test-net
  • 在 上,在 上运行交互式 alpine 容器 ()。host1alpine1test-net
  • 在 上,在 上运行一个交互式的、分离的 alpine 容器 ()。host2alpine2test-net
  • 在 上 ,从 , ping 的会话中。host1alpine1alpine2

先决条件

对于此测试,您需要两个不同的 Docker 主机,它们可以与 彼此。每个主机必须在两个 Docker 之间打开以下端口 主机:

  • TCP 端口 2377
  • TCP 和 UDP 端口 7946
  • UDP 端口 4789

一种简单的设置方法是拥有两个 VM(本地或云上) 提供商(如 AWS),每个提供商都安装并运行 Docker。如果您使用的是 AWS 或类似的云计算平台,最简单的配置是使用 打开两台主机和 SSH 之间的所有传入端口的安全组 port 的 IP 地址。

此示例将 swarm 中的两个节点称为 和 。这 example 也使用 Linux 主机,但相同的命令适用于 Windows。host1host2

演练

  1. 设置 swarm。

    一个。在 上,初始化一个群(如果出现提示,则用于指定与其他 集群中的主机,例如,AWS 上的私有 IP 地址):host1--advertise-addr

    $ docker swarm init
    Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    

    b.在 上,按照上述说明加入 swarm:host2

    $ docker swarm join --token <your_token> <your_ip_address>:2377
    This node joined a swarm as a worker.
    

    如果节点加入集群失败,则命令将 外。要解决此问题,请运行 ,验证您的 Network 和 Firewall 设置,然后重试。docker swarm joindocker swarm leave --forcehost2

  2. 在 上,创建一个名为 的可附加覆盖网络 :host1test-net

    $ docker network create --driver=overlay --attachable test-net
    uqsof8phj3ak0rq9k86zta6ht
    

    请注意返回的 NETWORK ID -- 当您从 连接到它时,您将再次看到它。host2

  3. 在 上,启动一个连接到 的交互式 () 容器 () :host1-italpine1test-net

    $ docker run -it --name alpine1 --network test-net alpine
    / #
    
  4. 在 上,列出可用的网络 -- 请注意 尚不存在:host2test-net

    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    ec299350b504        bridge              bridge              local
    66e77d0d0e9a        docker_gwbridge     bridge              local
    9f6ae26ccb82        host                host                local
    omvdxqrda80z        ingress             overlay             swarm
    b65c952a4b2b        none                null                local
    
  5. 在 上,启动一个连接到的分离 () 和交互式 () 容器 () :host2-d-italpine2test-net

    $ docker run -dit --name alpine2 --network test-net alpine
    fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342
    

    注意

    自动 DNS 容器发现仅适用于唯一的容器名称。

  6. 在 上 ,验证是否已创建(并且与 上 具有相同的网络 ID):host2test-nettest-nethost1

    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    ...
    uqsof8phj3ak        test-net            overlay             swarm
    
  7. 在 的交互式终端内 上 , ping :host1alpine2alpine1

    / # ping -c 2 alpine2
    PING alpine2 (10.0.0.5): 56 data bytes
    64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.600 ms
    64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.555 ms
    
    --- alpine2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.555/0.577/0.600 ms
    

    这两个容器与连接两个容器的覆盖网络通信 主机。如果您在未分离的 alpine 容器上运行另一个 alpine 容器, 你可以从 ping (这里我们添加了 Remove 选项以自动清理容器):host2alpine1host2

    $ docker run -it --rm --name alpine3 --network test-net alpine
    / # ping -c 2 alpine1
    / # exit
  8. 在 上,关闭会话(这也会停止容器):host1alpine1

    / # exit
    
  9. 清理容器和网络:

    您必须单独停止并删除每个主机上的容器,因为 Docker 守护程序独立运行,这些是独立的容器。 您只需删除 on 网络,因为当您停止 on 时,它会消失。host1alpine2host2test-net

    一个。在 、 stop 上 、 检查已删除的 ,然后删除 :host2alpine2test-netalpine2

    $ docker container stop alpine2
    $ docker network ls
    $ docker container rm alpine2
    

    一个。在 、 remove 和 :host1alpine1test-net

    $ docker container rm alpine1
    $ docker network rm test-net
    

其他联网教程