使用叠加网络联网
本系列教程涉及 Swarm 服务的联网。 有关使用独立容器联网的信息,请参阅使用独立容器联网。如果您需要 了解有关 Docker 网络的更多信息,请参阅概述。
此页面包括以下教程。您可以在 Linux、Windows 或 Mac,但对于最后一个,您需要第二个 Docker 主机在其他地方运行。
使用默认覆盖网络演示 如何使用 Docker 为您设置的默认覆盖网络 在您初始化或加入 Swarm 时自动进行。此网络不是 生产系统的最佳选择。
使用用户定义的叠加网络显示 如何创建和使用您自己的自定义叠加网络来连接服务。 建议对在生产环境中运行的服务执行此操作。
将覆盖网络用于独立容器 展示了如何在不同 Docker 上的独立容器之间进行通信 守护程序。
先决条件
这些要求至少有一个单节点 swarm,这意味着
您已启动 Docker 并在主机上运行。您可以运行
多节点 swarm 上的示例也是如此。docker swarm init
使用默认覆盖网络
在此示例中,您将启动一项服务并检查特征
从单个服务容器的角度来看。alpine
本教程不讨论特定于操作系统的细节,介绍如何操作 叠加层网络,但重点介绍叠加层的工作原理 服务的视点。
先决条件
本教程需要三个物理或虚拟 Docker 主机,它们都可以 相互沟通。本教程假定这三台主机是 在未涉及防火墙的同一网络上运行。
这些主机将称为 、 和 。主机将同时充当 Manager 和 worker,这意味着它可以
两者都运行服务任务并管理 Swarm。 并且将
仅作为 worker 工作,manager
worker-1
worker-2
manager
worker-1
worker-2
如果您手头没有 3 个主机,一个简单的解决方案是设置三个 云提供商(如 Amazon EC2)上的 Ubuntu 主机都位于同一网络上 允许与该网络上的所有主机进行所有通信(使用一种机制 例如 EC2 安全组),然后按照 Docker Engine - Ubuntu 上的社区的安装说明进行操作。
演练
创建 swarm
在此过程结束时,所有三个 Docker 主机都将加入 swarm
,并将使用名为 的覆盖网络连接在一起。ingress
上。初始化 Swarm。如果主机只有一个网络 interface 的 API 中,该标志是可选的。
manager
--advertise-addr
$ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>
记下打印的文本,因为其中包含 您将使用 to join 和 to the swarm。这是一个很好的 将令牌存储在密码管理器中的想法。
worker-1
worker-2
在 上,加入召集。如果主机只有一个网络接口, 该标志是可选的。
worker-1
--advertise-addr
$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-1> \ <IP-ADDRESS-OF-MANAGER>:2377
在 上,加入召集。如果主机只有一个网络接口, 该标志是可选的。
worker-2
--advertise-addr
$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-2> \ <IP-ADDRESS-OF-MANAGER>:2377
在 上,列出所有节点。此命令只能从 经理。
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
列出 、 、 和 和 注意 上的 Docker 网络 现在,他们每个人都有一个名为 和 Bridge 的覆盖网络 网络称为 .仅显示 的列表 这里:
manager
worker-1
worker-2
ingress
docker_gwbridge
manager
$ 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_gwbridge
ingress
ingress
创建服务
在 上,创建一个名为 的新覆盖网络 :
manager
nginx-net
$ docker network create -d overlay nginx-net
您无需在其他节点上创建覆盖网络,因为它 将在其中一个节点开始运行 service 任务。
在 上,创建一个连接到 的 5 副本 Nginx 服务 。这 service 将 80 端口发布到外部。所有服务 任务容器可以在不打开任何端口的情况下相互通信。
manager
nginx-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 而不是 因为只有一个服务任务可以绑定给定节点上的给定端口。
ingress
mode
--publish
manager
worker-1
worker-2
host
mode=host
--publish
--mode global
--replicas=5
Run 以监控服务启动的进度,该 可能需要几秒钟。
docker service ls
检查 、 和 上的网络。 请记住,您不需要手动创建它,因为 Docker 已为您创建它。输出会很长,但是 请注意 and 部分。 列出全部 连接到覆盖网络的服务任务(或独立容器) 从该主机。
nginx-net
manager
worker-1
worker-2
worker-1
worker-2
Containers
Peers
Containers
从 中,检查服务使用并注意 服务。
manager
docker service inspect my-nginx
创建新网络 ,然后更新服务以使用此网络 network 而不是 :
nginx-net-2
nginx-net
$ docker network create -d overlay nginx-net-2
$ docker service update \ --network-add nginx-net-2 \ --network-rm nginx-net \ my-nginx
运行以验证服务是否已更新,并且所有 任务已重新部署。运行以验证 没有容器连接到它。运行相同的命令,并注意所有服务任务容器都已连接 到它。
docker service ls
docker network inspect nginx-net
nginx-net-2
注意
即使覆盖网络是在 swarm 上自动创建的 worker 节点,则不会自动删除它们。
清理服务和网络。从 中,运行以下命令 命令。经理将指示 worker 删除网络 自然而然。
manager
$ docker service rm my-nginx $ docker network rm nginx-net nginx-net-2
使用用户定义的叠加网络
先决条件
本教程假设 swarm 已经设置完毕,并且您是 Manager。
演练
创建用户定义的叠加网络。
$ docker network create -d overlay my-overlay
使用覆盖网络启动服务并将端口 80 发布到端口 Docker 主机上的 8080 命令。
$ docker service create \ --name my-nginx \ --network my-overlay \ --replicas 1 \ --publish published=8080,target=80 \ nginx:latest
通过查看该部分,运行并验证服务任务是否已连接到它。
docker network inspect my-overlay
my-nginx
Containers
删除服务和网络。
$ docker service rm my-nginx $ docker network rm my-overlay
对独立容器使用覆盖网络
此示例演示了 DNS 容器发现 -- 具体而言,如何 使用 overlay 网络。步骤包括:
- 在 上,将节点初始化为 swarm (manager)。
host1
- 在 上,将节点加入 swarm (worker)。
host2
- 在 上,创建可附加的覆盖网络 ()。
host1
test-net
- 在 上,在 上运行交互式 alpine 容器 ()。
host1
alpine1
test-net
- 在 上,在 上运行一个交互式的、分离的 alpine 容器 ()。
host2
alpine2
test-net
- 在 上 ,从 , ping 的会话中。
host1
alpine1
alpine2
先决条件
对于此测试,您需要两个不同的 Docker 主机,它们可以与 彼此。每个主机必须在两个 Docker 之间打开以下端口 主机:
- TCP 端口 2377
- TCP 和 UDP 端口 7946
- UDP 端口 4789
一种简单的设置方法是拥有两个 VM(本地或云上) 提供商(如 AWS),每个提供商都安装并运行 Docker。如果您使用的是 AWS 或类似的云计算平台,最简单的配置是使用 打开两台主机和 SSH 之间的所有传入端口的安全组 port 的 IP 地址。
此示例将 swarm 中的两个节点称为 和 。这
example 也使用 Linux 主机,但相同的命令适用于 Windows。host1
host2
演练
设置 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 join
docker swarm leave --force
host2
在 上,创建一个名为 的可附加覆盖网络 :
host1
test-net
$ docker network create --driver=overlay --attachable test-net uqsof8phj3ak0rq9k86zta6ht
请注意返回的 NETWORK ID -- 当您从 连接到它时,您将再次看到它。
host2
在 上,启动一个连接到 的交互式 () 容器 () :
host1
-it
alpine1
test-net
$ docker run -it --name alpine1 --network test-net alpine / #
在 上,列出可用的网络 -- 请注意 尚不存在:
host2
test-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
在 上,启动一个连接到的分离 () 和交互式 () 容器 () :
host2
-d
-it
alpine2
test-net
$ docker run -dit --name alpine2 --network test-net alpine fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342
注意
自动 DNS 容器发现仅适用于唯一的容器名称。
在 上 ,验证是否已创建(并且与 上 具有相同的网络 ID):
host2
test-net
test-net
host1
$ docker network ls NETWORK ID NAME DRIVER SCOPE ... uqsof8phj3ak test-net overlay swarm
在 的交互式终端内 上 , ping :
host1
alpine2
alpine1
/ # 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 选项以自动清理容器):
host2
alpine1
host2
$ docker run -it --rm --name alpine3 --network test-net alpine / # ping -c 2 alpine1 / # exit
在 上,关闭会话(这也会停止容器):
host1
alpine1
/ # exit
清理容器和网络:
您必须单独停止并删除每个主机上的容器,因为 Docker 守护程序独立运行,这些是独立的容器。 您只需删除 on 网络,因为当您停止 on 时,它会消失。
host1
alpine2
host2
test-net
一个。在 、 stop 上 、 检查已删除的 ,然后删除 :
host2
alpine2
test-net
alpine2
$ docker container stop alpine2 $ docker network ls $ docker container rm alpine2
一个。在 、 remove 和 :
host1
alpine1
test-net
$ docker container rm alpine1 $ docker network rm test-net