共计 3083 个字符,预计需要花费 8 分钟才能阅读完成。
原文地址
介绍一种生产环境 Docker overlay network 的配置方案。
概要
先讲一下生产环境中的问题:
有多个 Docker host,希望能够通过 Docker swarm 连接起来。
Docker swarm 只适合于无状态应用,不适合有状态应用。
因此生产环境中会同时存在
无状态应用:利用 docker service create/docker stack deploy 创建的。
有状态应用:利用 docker run/docker compose up 创建的。
希望两种应用能够连接到同一个 overlay 网络,在网络内部能够通过
tasks.<service-name> DNS name 连接到无状态应用(见 Container discovery)
<container-name> DNS name 连接到有状态应用
解决办法:
创建 attachable 的 overlay network
有状态应用挂到这个 overlay network 上
无状态应用也挂到这个 overlay network 上
步骤
到 manager 节点上创建 attachable 的 overlay network,名字叫做 prod-overlay:
docker network create -d overlay –attachable prod-overlay
在 manager 节点上查看这个网络是否创建成功:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
fbfde97ed12a bridge bridge local
73ab6bbac970 docker_gwbridge bridge local
a2adb3de5f7a host host local
nm7pgzuh6ww4 ingress overlay swarm
638e550dab67 none null local
qqf78g8iio10 prod-overlay overlay swarm
在 worker 节点上查看这个网络,这时你看不到这个网络,不过不要担心,当后面在 worker 节点上创建工作负载后就能看到了:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
fbfde97ed12a bridge bridge local
73ab6bbac970 docker_gwbridge bridge local
a2adb3de5f7a host host local
nm7pgzuh6ww4 ingress overlay swarm
638e550dab67 none null local
在 manager 上创建容器 c1,挂到 prod-overlay network 上:
docker run –name c1 –network prod-overlay -itd busybox
在 worker 上创建容器 c2,挂到 prod-overlay network 上:
docker run –name c2 –network prod-overlay -itd busybox
在 manager 上创建 service c,挂到 prod-overlay network 上:
docker service create -td –name c –replicas 2 –network prod-overlay busybox
验证
查看 worker 节点的 network
之前在 worker 节点上没有看到 prod-overlay network,现在你应该可以看见了:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
01180b9d4833 bridge bridge local
cd94df435afc docker_gwbridge bridge local
74721e7670eb host host local
nm7pgzuh6ww4 ingress overlay swarm
32e6853ea78d none null local
dw8kd2nb2yl3 prod-overlay overlay swarm
确认容器可以互 ping
到 manager 节点上,让 c1 ping c2
$ docker exec c1 ping -c 2 c2
PING c2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=64 time=0.682 ms
64 bytes from 10.0.2.2: seq=1 ttl=64 time=0.652 ms
到 manager 节点上,让 c1 ping tasks.c,tasks.c 是之前创建的 service c 的 DNS name:
$ docker exec c1 ping -c 2 tasks.c
PING tasks.c (10.0.2.8): 56 data bytes
64 bytes from 10.0.2.8: seq=0 ttl=64 time=2.772 ms
64 bytes from 10.0.2.8: seq=1 ttl=64 time=0.694 ms
到 manager 节点上,让 c1 查询 tasks.c 的 DNS name,可以看到 tasks.c 有两条记录:
$ docker exec c1 nslookup -type=a tasks.c
Server: 127.0.0.11
Address: 127.0.0.11:53
Non-authoritative answer:
Name: tasks.c
Address: 10.0.2.7
Name: tasks.c
Address: 10.0.2.8
到 manager 节点上,查看 service c 的 task,看到有 c.1、c.2 两个 task,分别部署在两个节点上:
$ docker service ps c
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
p5n70vhtnz2f c.1 busybox:latest docker-learn-1 Running Running 17 minutes ago
byuoox1t7cve c.2 busybox:latest docker-learn-2 Running Running 17 minutes ago
到 c.1 task 所在的节点上,查看 task c.1 的容器名:
$ docker ps -f name=c.1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
795a3bd3c20a busybox:latest “sh” 21 minutes ago Up 21 minutes c.1.p5n70vhtnz2f5q8p2pcvbyfmw
然后在 c1 里 ping task c.1 的容器名:
$ docker exec c1 ping -c 2 c.1.p5n70vhtnz2f5q8p2pcvbyfmw
PING c.1.p5n70vhtnz2f5q8p2pcvbyfmw (10.0.2.7): 56 data bytes
64 bytes from 10.0.2.7: seq=0 ttl=64 time=0.198 ms
64 bytes from 10.0.2.7: seq=1 ttl=64 time=0.128 ms
你同样可以:
在 c2 里:
ping c1
ping tasks.c
ping task c.1、c.2 的容器
在 task c.1、c.2 的容器里:
ping c1、c2;
ping tasks.c
ping task c.1、c.2 的容器
注意
通过 docker run / docker compose up 创建的容器的名字,要保证在整个集群里是唯一的。docker 不会帮你检查名称冲突的情况,如果名称冲突了那么会得到错误的 DNS 结果。
参考资料
Use overlay networks
Use an overlay network for standalone containers