使用overly网络
该overlay
网络驱动程序会创建多个docker进程主机之间的分布式网络。该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信。Docker透明地处理每个数据包与Docker守护程序主机和正确的目标容器之间正确的的路由。
初始化swarm或将Docker主机加入现有swarm时,会在该Docker主机上创建两个新网络:
- 称为覆盖网络
ingress
,处理与群集服务相关的控制和数据流量。创建群组服务并且不将其连接到用户定义的覆盖网络时,ingress
默认连接到网络。 - 一个名为的桥接网络
docker_gwbridge
,它将各个Docker守护程序连接到参与该群集的其他守护进程。
您可以使用与创建用户定义bridge
网络docker network create
相同的方式创建用户定义的overly
网络。服务或容器一次可以连接到多个网络。服务或容器只能通过它们各自连接的网络进行通信。
虽然您可以将swarm服务和独立容器连接到覆盖网络,但默认行为和配置问题是不同的。因此,本主题的其余部分分为适用于所有覆盖网络的操作,适用于群集服务网络的操作以及适用于独立容器使用的覆盖网络的操作。
所有覆盖网络的操作
创建覆盖网络
先决条件:
使用覆盖网络的Docker守护程序的防火墙规则
您需要以下端口打开来往于覆盖网络上的每个Docker主机的流量:
- 用于集群管理通信的TCP端口2377
- TCP和UDP端口7946用于节点之间的通信
- UDP端口4789用于覆盖网络流量
在创建覆盖网络之前,您需要将Docker守护程序初始化为swarm管理器,
docker swarm init
或者使用它将其连接到现有的swarmdocker swarm join
。这些中的任何一个都会创建默认ingress
覆盖网络,默认情况下 由群服务使用。即使您从未计划使用群组服务,也需要执行此操作。之后,您可以创建其他用户定义的覆盖网络。
要创建用于swarm服务的覆盖网络,请使用如下命令:
$ docker network create -d overlay my-overlay
要创建可由群集服务或 独立容器用于与在其他Docker守护程序上运行的其他独立容器通信的覆盖网络,请添加--attachable
标志:
$ docker network create -d overlay --attachable my-attachable-overlay
您可以指定IP地址范围,子网,网关和其他选项。详情 docker network create --help
请见。
加密覆盖网络上的流量
默认情况下,使用GCM模式下的AES算法加密所有群集服务管理流量 。群中的管理器节点每隔12小时轮换用于加密八卦数据的密钥。
要加密应用程序数据,请--opt encrypted
在创建覆盖网络时添加。这样可以在vxlan级别启用IPSEC加密。此加密会产生不可忽视的性能损失,因此您应该在生产中使用此选项之前对其进行测试。
启用覆盖加密后,Docker会在所有节点之间创建IPSEC隧道,在这些节点上为连接到覆盖网络的服务安排任务。这些隧道还在GCM模式下使用AES算法,管理器节点每12小时自动旋转密钥。
SWARM模式覆盖网络和独立容器
您可以将覆盖网络功能两个参数 一起使用--opt encrypted --attachable
,并将非托管到集群中的容器附加到该网络:
$ docker network create --opt encrypted --driver overlay --attachable my-attachable-multi-host-network
自定义默认入口网络
大多数用户从不需要配置ingress
网络,但Docker 17.05及更高版本允许您这样做。如果自动选择的子网与网络上已存在的子网冲突,或者您需要自定义其他低级网络设置(如MTU),则此功能非常有用。
自定义ingress
网络涉及删除和重新创建它。这通常在您在swarm中创建任何服务之前完成。如果您具有发布端口的现有服务,则在删除ingress
网络之前需要删除这些服务。
在没有ingress
网络存在的时间内,不发布端口的现有服务继续运行但不是负载平衡的。这会影响发布端口的服务,例如发布端口80的WordPress服务。
检查
ingress
网络使用docker network inspect ingress
,并删除其容器连接到它的任何服务。这些是发布端口的服务,例如发布端口80的WordPress服务。如果未停止所有此类服务,则下一步失败。删除现有
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/ \
--gateway=10.11.0.2 \
--opt com.docker.network.driver.mtu= \
my-ingress
注意:您可以将ingress
网络命名为其他内容 ingress
,但您只能拥有一个。尝试创建第二个失败。
4.重新启动您在第一步中停止的服务。
自定义docker_gwbridge接口
它docker_gwbridge
是一个虚拟网桥,将覆盖网络(包括ingress
网络)连接到单个Docker守护程序的物理网络。
Docker初始化swarm或将Docker主机加入swarm时会自动创建它,但它不是Docker设备。它存在于Docker主机的内核中。如果您需要自定义其设置,则必须在将Docker主机加入群组之前或从群集中临时删除主机之后执行此操作。
停止docker_gwbridge。
删除现有docker_gwbridge。
$ sudo ip link set docker_gwbridge down $ sudo ip link del dev docker_gwbridge
3.启动Docker。不要加入或初始化群。
4.docker_gwbridge使用docker network create
命令使用自定义设置手动创建或重新创建桥。此示例使用子网10.11.0.0/16
。有关可自定义选项的完整列表,请参阅Bridge驱动程序选项。
$ docker network create \
--subnet 10.11.0.0/ \
--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.初始化或加入群。由于桥已经存在,Docker不会使用自动设置创建它。
群组服务的操作
在覆盖网络上发布端口
连接到同一覆盖网络的群集服务有效地将所有端口相互暴露。对于可在服务外部访问的端口,必须使用或标记on 或发布该端口。支持过期的冒号分隔语法和较新的逗号分隔值语法。较长的语法是首选,因为它有利于自我记忆。
-p --publishdocker service createdocker service update
标志值 | 描述 |
---|---|
-p 8080:80或 -p published = 8080,target = 80 |
将服务上的TCP端口80映射到路由网格上的端口8080。 |
-p 8080:80 / udp或 -p published = 8080,target = 80,protocol = udp |
将服务上的UDP端口80映射到路由网格上的端口8080。 |
-p 8080:80 / tcp -p 8080:80 / udp或 -p published = 8080,target = 80,protocol = tcp -p published = 8080,target = 80,protocol = udp |
将服务上的TCP端口80映射到路由网格上的TCP端口8080,并将服务上的UDP端口80映射到路由网格上的UDP端口8080。 |
绕过群集服务的路由网格
默认情况下,发布端口的swarm服务使用路由网格来实现。当您连接到任何swarm节点上的已发布端口(无论它是否正在运行给定服务)时,您将被透明地重定向到正在运行该服务的worker。实际上,Docker充当您的群服务的负载均衡器。使用路由网格的服务以虚拟IP(VIP)模式运行。即使在每个节点上运行的服务(通过--global
标志)也使用路由网格。使用路由网格时,无法保证哪个Docker节点服务客户端请求。
要绕过路由网格,可以使用DNS循环(DNSRR)模式启动服务,方法是将--endpoint-mode
标志设置为dnsrr
。您必须在服务前运行自己的负载均衡器。Docker主机上的服务名称的DNS查询返回运行该服务的节点的IP地址列表。配置负载均衡器以使用此列表并平衡节点之间的流量。
单独的控制和数据流量
默认情况下,与群组管理相关的控制流量以及进出应用程序的流量都在同一网络上运行,尽管群集控制流量已加密。您可以将Docker配置为使用单独的网络接口来处理两种不同类型的流量。当你初始化或者加入群,分别指定--advertise-addr
和--datapath-addr
。您必须为加入群集的每个节点执行此操作。
覆盖网络上独立容器的操作
将独立容器连接到覆盖网络
该ingress
网络创建是没有 --attachable
标志,这意味着只有群服务可以使用它,而不是独立的容器。您可以将独立容器连接到使用
该--attachable
标志创建的用户定义的覆盖网络。这使得在不同Docker守护程序上运行的独立容器能够进行通信,而无需在各个Docker守护程序主机上设置路由
发布端口
标志值 | 描述 |
---|---|
-p 8080:80 |
将容器中的TCP端口80映射到覆盖网络上的端口8080。 |
-p 8080:80/udp |
将容器中的UDP端口80映射到覆盖网络上的端口8080。 |
-p 8080:80/sctp |
将容器中的SCTP端口80映射到覆盖网络上的端口8080。 |
-p 8080:80/tcp -p 8080:80/udp |
将容器中的TCP端口80映射到覆盖网络上的TCP端口8080,并将容器中的UDP端口80映射到覆盖网络上的UDP端口8080。 |
容器发现
在大多数情况下,您应该连接到服务名称,该名称是负载平衡的,并由支持该服务的所有容器(“任务”)处理。要获取支持该服务的所有任务的列表,请执行DNS查找tasks.<service-name>.
与覆盖网络联网
预计阅读时间: 21分钟
这一系列教程涉及群组服务的网络。有关使用独立容器进行联网的信息,请参阅 使用独立容器联网。如果您需要了解有关Docker网络的更多信息,请参阅概述。
本主题包括四个不同的教程。您可以在Linux,Windows或Mac上运行它们,但是对于最后两个,您需要在其他地方运行第二个Docker主机。
使用默认overly网络 演示了如何使用Docker在初始化或加入群集时自动为您设置的默认覆盖网络。该网络不是生产系统的最佳选择。
使用自定义的overly网络 显示如何创建和使用您自己的自定义覆盖网络,以连接服务。建议用于生产中运行的服务。
对独立容器使用overly网络 显示如何使用覆盖网络在不同Docker守护程序上的独立容器之间进行通信。
容器和集群服务之间的通信 使用可附加的覆盖网络在独立容器和群服务之间建立通信。Docker 17.06及更高版本支持此功能。
先决条件
这些要求您至少拥有一个单节点群,这意味着您已启动Docker并docker swarm init
在主机上运行。您也可以在多节点群上运行示例。
最后一个示例需要Docker 17.06或更高版本。
使用默认overly网络
在此示例中,您将从alpine
各个服务容器的角度启动服务并检查网络的特征。
本教程不涉及有关如何实现覆盖网络的操作系统特定细节,而是着重于从服务的角度来看覆盖的功能。
先决条件
本教程需要三个物理或虚拟Docker主机,它们都可以相互通信,所有主机都运行Docker 17.03或更高版本的新安装。本教程假定三台主机在同一网络上运行,不涉及防火墙。
这些主机将被称为manager
,worker-1
和worker-2
。该 manager
主机将作为既是manager和worker,这意味着它可以运行服务任务和管理集群。worker-1
合worker-2
仅作为worker,
资源使用情况
[root@docker11 ~]# uname -r
3.10.-.el7.x86_64
[root@docker11 ~]# cat /etc/redhat-release
CentOS Linux release 7.2. (Core)
[root@docker11 ~]# docker --version
Docker version 18.06.-ce, build 0ffa825
主机名 | 角色 | ip |
docker11 | manager | 10.0.0.11 |
docker12 | worker | 10.0.0.12 |
docker13 | worker | 10.0.0.13 |
演练
创建群
在此过程结束时,所有三个Docker主机将连接到群集,并将使用名为的覆盖网络连接在一起ingress
。
-
在
master
。初始化群。如果主机只有一个网络接口,则该--advertise-addr
标志是可选的$ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>
[root@docker11 ~]# docker swarm init --advertise-addr=10.0.0.11
Swarm initialized: current node (tqen693onueeokb4yhvctkzj2) is now a manager.To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3s09ku0ul8knjiav33o2ekl9l5o6m18dx5dq7gemcialz7o1zf-5ovnjoejjw3tbjiypv7lj3zpo 10.0.0.11:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
记下打印的文本,因为它包含您将用于加入worker-1
和使用worker-2
swarm 的标记。将令牌token存储在密码管理器中是个比较好的建议。
2.在worker-1
,加入群。如果主机只有一个网络接口,则该--advertise-addr
标志是可选的。
$ docker swarm --join --token <TOKEN> \
--advertise-addr <IP-ADDRESS-OF-WORKER-> \
<IP-ADDRESS-OF-MANAGER>:
在docker12 上执行
[root@docker12 ~]# docker swarm join --token SWMTKN--3s09ku0ul8knjiav33o2ekl9l5o6m18dx5dq7gemcialz7o1zf-5ovnjoejjw3tbjiypv7lj3zpo 10.0.0.11:
This node joined a swarm as a worker
3. 在worker-2
,加入群。如果主机只有一个网络接口,则该--advertise-addr
标志是可选的。
$ docker swarm --join --token <TOKEN> \
--advertise-addr <IP-ADDRESS-OF-WORKER-> \
<IP-ADDRESS-OF-MANAGER>:
在docker13上执行
[root@docker13 ~]# docker swarm join --token SWMTKN--3s09ku0ul8knjiav33o2ekl9l5o6m18dx5dq7gemcialz7o1zf-5ovnjoejjw3tbjiypv7lj3zpo 10.0.0.11:
This node joined a swarm as a worker.
4.manager节点上
,列出所有的节点。此命令只能从manager完成。
您还可以使用该--filter
标志按角色进行过滤:
[root@docker11 ~]# docker node ls --filter role=manager
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
tqen693onueeokb4yhvctkzj2 * docker11 Ready Active Leader 18.06.-ce
[root@docker11 ~]# docker node ls --filter role=worker
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
id33e1c29uijlwa498u6u0aco docker12 Ready Active 18.06.-ce
ojk0bn1tr0qmdc3t633yulm5j docker13 Ready Active 18.06.-ce
列出Docker网络
[root@docker11 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
eee9ca8be915 bridge bridge local
883db4142382 docker_gwbridge bridge local
0fb58f1bebd7 host host local
3g87ciii6vcm ingress overlay swarm
624aa8834d74 none null local
docker_gwbridge是
连接ingress
网络到docker主机的的网络接口,以便manager和worker之间的通信可以流入和流出。
如果您创建swarm服务但未指定网络,则它们将连接到ingress
网络。建议您为可以协同worker的每个应用程序或应用程序组使用单独的覆盖网络。
在下一个过程中,您将创建两个覆盖网络并将服务连接到每个网络。
创建服务
在
manager
,创建一个名为nginx-net的新覆盖网络:
[root@docker11 ~]# docker network create -d overlay nginx-net
0jio47q1lesr6wcc3vv9imr0i
2. 在manager
,创建nginx-net连接到5副本的Nginx服务。该服务将向外界发布端口80。所有服务任务容器都可以相互通信而无需打开任何端口。
注意:只能在经理上创建服务。
[root@docker11 ~]# docker service create \
> --name my-nginx \
> --publish target=,published= \
> --replicas= \
> --network nginx-net \
> nginx
id3jqur0qybc6rqtmppjzq9j1
overall progress: out of tasks
/: running [==================================================>]
/: running [==================================================>]
/: running [==================================================>]
/: running [==================================================>]
/: running [==================================================>]
verify: Service converged
默认的发布模式ingress
,当你不指定所使用mode
的--publish
标志,意味着如果在浏览到端口80上manager
,worker-1
或者worker-2
即使没有,你会被连接到端口80上的5项服务任务之一,
当前任务正在您浏览的节点上运行。如果要使用host
模式发布端口 ,可以添加mode=host
到--publish
输出。但是,您也应该使用--mode global
而不是--replicas=5
在这种情况下,因为只有一个服务任务可以绑定给定节点上的给定端口。
3.运行docker service ls
以监视服务启动的进度,这可能需要几秒钟。
4.检查nginx-net
网络master
,worker-1
和worker-2
。请记住,您不需要手动创建它worker-1
, worker-2
因为Docker会为您创建它。
输出将很长,但请注意Containers
和Peers
部分。Containers
列出从该主机连接到覆盖网络的所有服务任务(或独立容器)。
[root@docker11 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
eee9ca8be915 bridge bridge local
883db4142382 docker_gwbridge bridge local
0fb58f1bebd7 host host local
3g87ciii6vcm ingress overlay swarm
0jio47q1lesr nginx-net overlay swarm
624aa8834d74 none null local
[root@docker11 ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47002c65a1c8 nginx:latest "nginx -g 'daemon of…" minutes ago Up minutes /tcp my-nginx..aq7qnmt33c84mrw7dn8xzdmwb
1f4e3effd9bf nginx:latest "nginx -g 'daemon of…" minutes ago Up minutes /tcp my-nginx..i6nrst2f6x7l9uspiguprq779
[root@docker11 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47002c65a1c8 nginx:latest "nginx -g 'daemon of…" minutes ago Up minutes /tcp my-nginx..aq7qnmt33c84mrw7dn8xzdmwb
1f4e3effd9bf nginx:latest "nginx -g 'daemon of…" minutes ago Up minutes /tcp my-nginx..i6nrst2f6x7l9uspiguprq779
5.从manager
,检查服务使用docker service inspect my-nginx
并注意有关服务使用的端口和端点的信息。
[root@docker11 ~]# docker service inspect my-nginx
[
{
"ID": "id3jqur0qybc6rqtmppjzq9j1",
"Version": {
"Index":
},
"CreatedAt": "2018-08-20T09:13:25.208540232Z",
"UpdatedAt": "2018-08-20T09:13:25.209631123Z",
"Spec": {
"Name": "my-nginx",
"Labels": {},
"TaskTemplate": {
"ContainerSpec": {
"Image": "nginx:latest@sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424",
"Init": false,
"StopGracePeriod": ,
"DNSConfig": {},
"Isolation": "default"
},
"Resources": {
"Limits": {},
"Reservations": {}
},
"RestartPolicy": {
"Condition": "any",
"Delay": ,
"MaxAttempts":
},
"Placement": {
"Platforms": [
{
"Architecture": "amd64",
"OS": "linux"
},
{
"OS": "linux"
},
{
"Architecture": "arm64",
"OS": "linux"
},
{
"Architecture": "",
"OS": "linux"
},
{
"Architecture": "ppc64le",
"OS": "linux"
},
{
"Architecture": "s390x",
"OS": "linux"
}
]
},
"Networks": [
{
"Target": "0jio47q1lesr6wcc3vv9imr0i"
}
],
"ForceUpdate": ,
"Runtime": "container"
},
"Mode": {
"Replicated": {
"Replicas":
}
},
"UpdateConfig": {
"Parallelism": ,
"FailureAction": "pause",
"Monitor": ,
"MaxFailureRatio": ,
"Order": "stop-first"
},
"RollbackConfig": {
"Parallelism": ,
"FailureAction": "pause",
"Monitor": ,
"MaxFailureRatio": ,
"Order": "stop-first"
},
"EndpointSpec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": ,
"PublishedPort": ,
"PublishMode": "ingress"
}
]
}
},
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": ,
"PublishedPort": ,
"PublishMode": "ingress"
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": ,
"PublishedPort": ,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "3g87ciii6vcmnbbh5xhef9d6x",
"Addr": "10.255.0.5/16"
},
{
"NetworkID": "0jio47q1lesr6wcc3vv9imr0i",
"Addr": "10.0.0.5/24"
}
]
}
}
]
6.创建一个新网络nginx-net-2
,然后更新服务以使用此网络而不是nginx-net
:
[root@docker11 ~]# docker network create -d overlay nginx-net-
lf0ikr366da10357nkrwgruo5
7.运行docker service ls
以验证服务是否已更新并且已重新部署所有任务。运行docker network inspect nginx-net
以验证没有容器连接到它。运行相同的命令, nginx-net-2
并注意所有服务任务容器都连接到它。
[root@docker11 ~]# docker network inspect nginx-net
[
{
"Name": "nginx-net",
"Id": "0jio47q1lesr6wcc3vv9imr0i",
"Created": "2018-08-20T17:13:25.381549021+08:00",
"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,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"lb-nginx-net": {
"Name": "nginx-net-endpoint",
"EndpointID": "907f7ab7106d1ca7e01a8d2cc212ca9285f6c4a111057cc08bbf61a4e3a7a18c",
"MacAddress": "02:42:0a:00:00:04",
"IPv4Address": "10.0.0.4/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": ""
},
"Labels": {},
"Peers": [
{
"Name": "5396a0282436",
"IP": "10.0.0.11"
},
{
"Name": "6bcf7a0cc868",
"IP": "10.0.0.13"
},
{
"Name": "96eed05fba40",
"IP": "10.0.0.12"
}
]
}
]
[root@docker11 ~]# docker network inspect nginx-net-
[
{
"Name": "nginx-net-2",
"Id": "lf0ikr366da10357nkrwgruo5",
"Created": "2018-08-20T17:25:53.36574903+08:00",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.1.0/24",
"Gateway": "10.0.1.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"2d551a9e08c75ee47a39e65b356f3bc06c67b1422ce07dafacdbe509ed24cee6": {
"Name": "my-nginx.2.pjkfo8yk59zg4muoer0vq6zuz",
"EndpointID": "f6322607d6eb098cc823dfea7ca9bd7aaeb341d495b6f400a8b7524fb55e1686",
"MacAddress": "02:42:0a:00:01:09",
"IPv4Address": "10.0.1.9/24",
"IPv6Address": ""
},
"56572953de75e93f7f9bfdfc4e3ed9dc34f4242a188b0c9f86fd66cc5ebc18cf": {
"Name": "my-nginx.5.8bog4krru1bcnfzgvw9hy2uuq",
"EndpointID": "0c374ec88d475bb76e0a10123bd05fd7336b33966ea6f62a79d378ff169aeab4",
"MacAddress": "02:42:0a:00:01:0a",
"IPv4Address": "10.0.1.10/24",
"IPv6Address": ""
},
"lb-nginx-net-2": {
"Name": "nginx-net-2-endpoint",
"EndpointID": "8d9ba9f7a00a4f75df7e0cadff0609be02c80068b33e947a76d558ab8e5a2336",
"MacAddress": "02:42:0a:00:01:04",
"IPv4Address": "10.0.1.4/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": ""
},
"Labels": {},
"Peers": [
{
"Name": "96eed05fba40",
"IP": "10.0.0.12"
},
{
"Name": "6bcf7a0cc868",
"IP": "10.0.0.13"
},
{
"Name": "5396a0282436",
"IP": "10.0.0.11"
}
]
}
]
注意:即使根据需要在swarm worker节点上自动创建覆盖网络,也不会自动删除它们。
8.清理服务和网络。从manager
,运行以下命令。manager将指导worker自动删除网络。
[root@docker11 ~]# docker service rm my-nginx
my-nginx
[root@docker11 ~]# docker network rm nginx-net nginx-net-
nginx-net
nginx-net-
使用用户定义的覆盖网络
先决条件
本教程假设已经设置了swarm并且您在经理上。
演练
创建用户定义的覆盖网络。
[root@docker11 ~]# docker network create -d overlay my-overlay
6pihnll7a2q3amg05j2vo2uqc
2.使用覆盖网络启动服务,并将端口80发布到Docker主机上的端口8080。
[root@docker11 ~]# docker service create \
> --name my-nginx \
> --network my-overlay \
> --replicas \
> --publish published=,target= \
> nginx:latest
qewq4jy05n7sar8d6rfzaf3ny
overall progress: out of tasks
/: running [==================================================>]
verify: Service converged
3.通过查看该部分,运行docker network inspect my-overlay
并验证my-nginx
服务任务是否已连接到该服务任务Containers
。
[root@docker11 ~]# docker network inspect my-overlay
[
{
"Name": "my-overlay",
"Id": "6pihnll7a2q3amg05j2vo2uqc",
"Created": "2018-08-20T17:42:41.326901392+08:00",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.2.0/24",
"Gateway": "10.0.2.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"f0d353bca975761ad2c9665db20075af128886a1d171b15dc2dec365b7a0c384": {
"Name": "my-nginx.1.ohho088gz1el01pgwtmnyrbyk",
"EndpointID": "94ae0e87deb040b4285c4624cf64d520b5696d6738834ef4d3668e00840d0b42",
"MacAddress": "02:42:0a:00:02:06",
"IPv4Address": "10.0.2.6/24",
"IPv6Address": ""
},
"lb-my-overlay": {
"Name": "my-overlay-endpoint",
"EndpointID": "f3c160b564513b3fea1adbb985bb042008d0d3f3a40770e2e4fbc990109b707d",
"MacAddress": "02:42:0a:00:02:04",
"IPv4Address": "10.0.2.4/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": ""
},
"Labels": {},
"Peers": [
{
"Name": "5396a0282436",
"IP": "10.0.0.11"
}
]
}
]
4.删除服务和网络。
[root@docker11 ~]# docker service rm my-nginx
my-nginx
[root@docker11 ~]# docker network rm my-overlay
my-overlay
将覆盖网络用于独立容器
此示例演示了DNS容器发现 - 具体来说,是如何使用覆盖网络在不同Docker守护程序上的独立容器之间进行通信。步骤是:
- 在
host1
,将节点初始化为swarm(管理器)。 - 单击
host2
,将节点加入swarm(worker)。 - 在
host1
,创建一个可附加的覆盖网络(test-net
)。 - 在
host1
,打开一个交互式容器(alpine1
)test-net
。 - 在
host2
,打开一个交互式,分离的容器(alpine2
)test-net
。 - 在
host1
的会话中。pingalpine1
alpine2
先决条件
对于此测试,您需要两个可以相互通信的不同Docker主机。每个主机必须具有Docker 17.06或更高版本,并且在两个Docker主机之间打开以下端口:
- TCP端口2377
- TCP和UDP端口7946
- UDP端口4789
演练
-
设置群。
打开
host1
,初始化一个群(如果提示,则用于--advertise-addr
指定与群中其他主机通信的接口的IP地址,例如,AWS上的私有IP地址):
$ 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--5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252: To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
在host2
,按照上面的说明加入群体:
$ docker swarm join --token <your_token> <your_ip_address>:
This node joined a swarm as a worker.
如果节点无法加入群集,则docker swarm join
命令超时。要解决,运行docker swarm leave --force
上host2
,验证您的网络和防火墙设置,然后再试一次。
其实我还是复用刚刚上面的群集
2.在host1
,创建一个可附加的覆盖网络,称为test-net
:
[root@docker11 ~]# docker network create --driver=overlay --attachable test-net
pbfhuwobalq951patyl7au0gw
请注意返回的NETWORK ID - 当您连接到它时,您将在host2再次看到它
3.在host1
,启动一个连接到:的interactive(-it
)容器(alpine1
)test-net
:
[root@docker11 ~]# docker network create --driver=overlay --attachable test-net
pbfhuwobalq951patyl7au0gw
[root@docker11 ~]# dock
[root@docker11 ~]# docker run -it --name alpine1 --network test-net alpine
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
8e3ba11ec2a2: Pull complete
Digest: sha256:0873c923e00e0fd2ba78041bfb64a105e1ecb7678916d1f7776311e45bf5634b
Status: Downloaded newer image for alpine:latest
/ #
4.在host2
,列出可用的网络 - 通知test-net
尚不存在
[root@docker12 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6420cf5136cb bridge bridge local
10c56fdf193c docker_gwbridge bridge local
0fb58f1bebd7 host host local
3g87ciii6vcm ingress overlay swarm
624aa8834d74 none null local
5.在host2
,启动一个连接到:的detached(-d
)和interactive(-it
)容器(alpine2
)test-net
:
[root@docker12 ~]# docker run -dit --name alpine2 --network test-net alpine
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
8e3ba11ec2a2: Pull complete
Digest: sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430
Status: Downloaded newer image for alpine:latest
8e5aaf169b69e3c8329aaab4ec80a66133ef9ea47283b362892da5f300bbd1bf
自动DNS容器发现仅适用于名称唯一的容器。
6.上host2
,验证test-net
被创建(和具有相同的网络ID为test-net
上host1
):
[root@docker11 ~]# docker network ls|grep test-net
pbfhuwobalq9 test-net overlay swarm [root@docker12 ~]# docker network ls|grep test-net
pbfhuwobalq9 test-net overlay swarm
7.在host1
,alpine2
交互式终端内ping alpine1
:
/ # ping -c alpine2
PING alpine2 (10.0.3.6): data bytes
bytes from 10.0.3.6: seq= ttl= time=0.298 ms
bytes from 10.0.3.6: seq= ttl= time=0.358 ms --- alpine2 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.298/0.328/0.358 ms
两个容器与连接两个主机的覆盖网络通信。如果您运行的另一个容器 与host2
是不相关的,可以从host2
ping alpine1
(在这里,我们添加 删除选项自动清理容器):
/ # ping -c alpine1
PING alpine1 (10.0.3.7): data bytes
bytes from 10.0.3.7: seq= ttl= time=0.399 ms
bytes from 10.0.3.7: seq= ttl= time=0.320 ms --- alpine1 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.320/0.359/0.399 ms
/ # exit
[root@docker12 ~]#
8.打开host1
,关闭alpine1
会话(也会停止容器):
/ # exit
[root@docker11 ~]#
9.清理容器和网络:
您必须单独停止和删除每个主机上的容器,因为Docker守护程序独立运行,并且这些是独立容器。您只需要删除host1网络,因为当您停止 alpine2
时host2
,test-net
消失。
打开host2
,停止alpine2
,检查test-net
已删除,然后删除alpine2
:
[root@docker12 ~]# docker rm alpine2
alpine2
打开host1
,删除alpine1
和test-net
:
[root@docker11 ~]# docker rm alpine1
alpine1
[root@docker11 ~]# docker network rm test-net
test-net
在容器和群服务之间进行通信
先决条件
此示例需要Docker 17.06或更高版本。
演练
在此示例中,您需要安装并运行Docker,您在同一个Docker主机上启动两个不同的alpine容器,并进行一些测试以了解它们如何相互通信。。
打开终端窗口。在执行任何其他操作之前列出当前网络。如果您从未在此Docker守护程序上添加网络或初始化群组,那么您应该看到以下内容。您可能会看到不同的网络,但至少应该看到这些(网络ID会有所不同):
$ docker network ls NETWORK ID NAME DRIVER SCOPE
17e324f45964 bridge bridge local
6ed54d316334 host host local
7092879f2cc8 none null local
bridge
列出了默认网络以及host
和none
。后两者不是完全成熟的网络,但用于启动直接连接到Docker守护程序主机的网络堆栈的容器,或用于启动没有网络设备的容器。本教程将两个容器连接到bridge
网络。
2.bridge是
默认网络, 以及host
和none
。后两者不是完全成熟的网络,但用于启动直接连接到Docker守护程序主机的网络堆栈的容器,或用于启动没有网络设备的容器。本教程将两个容器连接到bridge
网络。
启动两个alpine
容器运行ash
,这是Alpine的默认shell是ash而不是bash
。该-dit
标志意味着要首先分离容器(背景),互动(与输入到它的能力),并与TTY(这样你就可以看到输入和输出)。
由于您正在启动它,因此您不会立即连接到容器。而是打印容器的ID。由于您尚未指定任何 --network
标志,因此容器将连接到默认bridge
网络。
[root@docker11 ~]# docker run -dit --name alpine1 alpine ash
5c996592ef2625823aca676ed2c74dcbca9bb70476532c3aeabc128dbad0788b
[root@docker11 ~]# docker run -dit --name alpine2 alpine ash
3156de9fdae1230baa3c19d038e347cb197f78d9b32bfb4e56bfdb948b724fbd
检查两个容器是否实际启动:
3.检查bridge
网络以查看连接到它的容器。
[root@docker11 ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "eee9ca8be915650919c6a86c66e9b8c26f862943abfc99f46c01efdfa405de2b",
"Created": "2018-08-20T16:47:37.448247591+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"3156de9fdae1230baa3c19d038e347cb197f78d9b32bfb4e56bfdb948b724fbd": {
"Name": "alpine2",
"EndpointID": "4d08f938c8e30dfccd1e90b9055a2bfbcf34443aed56cbbf6b459887294bc0f8",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"5c996592ef2625823aca676ed2c74dcbca9bb70476532c3aeabc128dbad0788b": {
"Name": "alpine1",
"EndpointID": "ce96f52236f5b7a5b8489a59d3f6ef76a63489aa2dfd37288e585b547cbcef38",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": ""
},
"Labels": {}
}
]
在顶部附近bridge
列出了有关网络的信息,包括Docker主机和bridge
网络之间的网关的IP地址(172.17.0.1
)。在Containers
密钥下面,列出了每个连接的容器,以及有关其IP地址(172.17.0.2
for alpine1
和172.17.0.3
for alpine2
)的信息。
4.容器在后台运行。使用docker attach
命令连接到alpine1
。
第一个接口是环回设备。暂时忽略它。请注意,第二个接口具有IP地址172.17.0.2
,该地址alpine1
与上一步中显示的地址相同。
5.从内部alpine1
,确保您可以通过ping连接到互联网baidu.com
。该-c 2
标志限制命令两次ping
尝试。
6.现在尝试ping第二个容器。首先,通过IP地址ping它 172.17.0.3
:
这成功了。接下来,尝试alpine2
按容器名称ping 容器。这将失败。
7.alpine2
使用分离序列分离而不停止它, CTRL
+ p
CTRL
+ q
(按住CTRL
并键入p
后跟q
)。如果你愿意,重视alpine2
并重复步骤4,5和6出现,取代alpine1
了alpine2
。
8.停止并移除两个容器。