一种生产环境Docker Overlay Network的配置方案
原文地址介绍一种生产环境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 lsNETWORK ID NAME DRIVER SCOPEfbfde97ed12a bridge bridge local73ab6bbac970 docker_gwbridge bridge locala2adb3de5f7a host host localnm7pgzuh6ww4 ingress overlay swarm638e550dab67 none null localqqf78g8iio10 prod-overlay overlay swarm在worker节点上查看这个网络,这时你看不到这个网络,不过不要担心,当后面在worker节点上创建工作负载后就能看到了:$ docker network lsNETWORK ID NAME DRIVER SCOPEfbfde97ed12a bridge bridge local73ab6bbac970 docker_gwbridge bridge locala2adb3de5f7a host host localnm7pgzuh6ww4 ingress overlay swarm638e550dab67 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 lsNETWORK ID NAME DRIVER SCOPE01180b9d4833 bridge bridge localcd94df435afc docker_gwbridge bridge local74721e7670eb host host localnm7pgzuh6ww4 ingress overlay swarm32e6853ea78d none null localdw8kd2nb2yl3 prod-overlay overlay swarm确认容器可以互ping到manager节点上,让c1 ping c2$ docker exec c1 ping -c 2 c2PING c2 (10.0.2.2): 56 data bytes64 bytes from 10.0.2.2: seq=0 ttl=64 time=0.682 ms64 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.cPING tasks.c (10.0.2.8): 56 data bytes64 bytes from 10.0.2.8: seq=0 ttl=64 time=2.772 ms64 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.cServer: 127.0.0.11Address: 127.0.0.11:53Non-authoritative answer:Name: tasks.cAddress: 10.0.2.7Name: tasks.cAddress: 10.0.2.8到manager节点上,查看service c的task,看到有c.1、c.2两个task,分别部署在两个节点上:$ docker service ps cID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTSp5n70vhtnz2f c.1 busybox:latest docker-learn-1 Running Running 17 minutes agobyuoox1t7cve c.2 busybox:latest docker-learn-2 Running Running 17 minutes ago到c.1 task所在的节点上,查看task c.1的容器名:$ docker ps -f name=c.1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES795a3bd3c20a 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.p5n70vhtnz2f5q8p2pcvbyfmwPING c.1.p5n70vhtnz2f5q8p2pcvbyfmw (10.0.2.7): 56 data bytes64 bytes from 10.0.2.7: seq=0 ttl=64 time=0.198 ms64 bytes from 10.0.2.7: seq=1 ttl=64 time=0.128 ms你同样可以:在c2里:ping c1ping tasks.cping task c.1、c.2的容器在task c.1、c.2的容器里:ping c1、c2;ping tasks.cping task c.1、c.2的容器注意通过docker run / docker compose up创建的容器的名字,要保证在整个集群里是唯一的。docker 不会帮你检查名称冲突的情况,如果名称冲突了那么会得到错误的DNS结果。参考资料Use overlay networksUse an overlay network for standalone containers ...