overlay网络简介
前面介绍过的host网络模式和bridge网络模式都是在单体的docker服务器上的容器间的网络通信。对于多个docker服务器上的多个容器间网络通信就需要使用到overlay网络模式了。
overlay网络常常用于docker swarm集群上的服务编排。当初始化docker swarm集群或者docker主机加入已存在的swarm集群时,会默认创建一个叫ingress的overlay网络和一个叫docker_gwbridge的bridge网络。其中docker_gwbridge的作用是将ingress跟宿主机的网络接口连接,这样才能将流量发送到swarm集群的每个节点上实现网络通信。
如果创建一个swarm集群的服务而没有自定义网络,那么会默认将服务连接到ingress的overlay网络上。建议每个swarm集群的服务都自定义overlay网络,这样可以实现不同的swarm集群服务间的网络隔离。
接下来说明overlay网络的使用,需要准备两台台已安装docker的服务器,一台初始化为manager节点,另一台加入swarm集群作为worker节点,可参考Docker系列之Docker Swarm容器管理与调度。
注:swarm集群需要用2377、7946、4798端口,配置防火墙的端口白名单或关闭防火墙。
使用overlay网络编排部署服务
使用swarm集群部署编排服务,其网络可以先创建好,而后在docker-compose.yml中配置引用。也可以直接在docker-compose.yml中定义,部署服务时会自动创建网络。
注:swarm集群管理的相关命令只能在manager节点运行。
自定义overlay网络:
$ docker network create -d overlay --subnet=10.11.0.0/16 my-overlay
定义一个overlay网络,名为my-overlay,网段为10.11.0.0/16。
查看网络列表:
NETWORK IDNAMEDRIVER SCOPE 20706abe43b3 bridge bridge local 87e7be65d0ce docker_gwbridgebridge local d2ad0895e4f3 hosthostlocal 3rrki5qjsbr4 ingress overlay swarm qse9xsv76lbp my-overlayoverlay swarm 8e5de9308b80 nonenulllocal$ docker network ls
在manager节点可以看到新创建的my-overlay在列表中,如果此时直接在worker节点上执行docker network ls是看不到my-overlay网络的,当部署swarm集群服务并且引用my-overlay网络,将服务部署在worker节点上时,就可以看到my-overlay网络已创建。
下面以一个tomcat与redis的服务编排来验证一下跨宿主机的网络通信。
在docker-compose.yml中引用网络,如下:
services: tomcat: image: tomcat:8.5 networks: - tc-net ports: - 8080:8080 deploy: replicas: 2 restart_policy: condition: any redis: image: redis:5.0 networks: - tc-net deploy: replicas: 1 restart_policy: condition: any networks: tc-net: driver: overlay external: name: my-overlayversion: '3'
作为参考,在docker-compose.yml中定义网络:
networks: tc-net: driver: overlay ipam: config: - subnet: 10.15.0.0/26...
在docker-compose.yml中定义tomcat和redis两个服务,使用external属性来引用已经创建好的网络my-overlay。
部署服务:
docker stack deploy -c docker-compose.yml tc# manager节点
查看服务:
$ docker stack ps tc ID NAMEIMAGENODEDESIRED STATE CURRENT STATE ERRORPORTS 1l0pkds2izjh tc_tomcat.1 tomcat:8.5docker-managerRunning Running 5 minutes ago 6icmjpn4wugt tc_redis.1redis:5.0 docker-managerRunning Running 5 minutes ago z2j2nahaxe3j tc_tomcat.2 tomcat:8.5docker-worker Running Running 5 minutes ago# manager节点
可以看到tomcat服务在manager和worker节点各有一个,redis服务在manager节点。
接下来分别在manager节点和worker节点上进入到tomcat容器中ping一下redis服务,来验证一下跨docker主机的网络通信。
manager节点
CONTAINER ID IMAGECOMMAND CREATED STATUS PORTSNAMES 739058b19824 tomcat:8.5"catalina.sh run" About a minute ago Up 58 seconds 8080/tcp tc_tomcat.1.1l0pkds2izjhju9phcil1mv02 a59d511157f4 redis:5.0 "docker-entrypoint.sh..." About a minute ago Up About a minute 6379/tcp tc_redis.1.6icmjpn4wugtx22xqie0bofq2$ docker ps
root@739058b19824:/usr/local/tomcat# ping -c 2 redis PING redis (10.11.40.60) 56(84) bytes of data. 64 bytes from 10.11.40.60 (10.11.40.60): icmp_seq=1 ttl=64 time=0.052 ms 64 bytes from 10.11.40.60 (10.11.40.60): icmp_seq=2 ttl=64 time=0.040 ms --- redis ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 134ms rtt min/avg/max/mdev = 0.040/0.046/0.052/0.006 ms$ docker exec -it 739058b19824 bash
在manager节点上是可以ping通redis服务的。
worker节点
CONTAINER ID IMAGECOMMAND CREATED STATUS PORTSNAMES dd3e3301de7d tomcat:8.5"catalina.sh run" About a minute ago Up About a minute 8080/tcp tc_tomcat.2.z2j2nahaxe3j403j21at7j9a6$ docker ps
root@dd3e3301de7d:/usr/local/tomcat# ping -c 2 redis PING redis (10.11.40.60) 56(84) bytes of data. 64 bytes from 10.11.40.60 (10.11.40.60): icmp_seq=1 ttl=64 time=0.053 ms 64 bytes from 10.11.40.60 (10.11.40.60): icmp_seq=2 ttl=64 time=0.067 ms --- redis ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 2ms rtt min/avg/max/mdev = 0.053/0.060/0.067/0.007 ms$ docker exec -it dd3e3301de7d bash
可以看到在worker节点上同样可以ping通redis服务。
以上也能说明通过自定义overlay网络实现了跨宿主机的网络通信,这也是常用swarm集群部署服务的原因所在。
使用overlay实现单个容器服务与swarm集群服务的通信
在compose file的3.2版本后增加了对网络设置的attachable属性,将其设置为true,可以实现单个容器连接swarm集群服务的overlay网络,从而实现单个容器与swarm集群的服务间的网络通信。
注:单个容器与swarm集群服务进行网络通信的前提是,单个容器所在的宿主机需要加入到swarm集群作为一节点。
下面以tomcat的swarm集群为例,在外部启动redis服务,将redis连接到tomcat所在的overlay网络,而后验证他们之间的网络通信。
manager节点
tomcat服务的compose file如下:
services: tomcat: image: tomcat:8.5 networks: - tc-net ports: - 8080:8080 deploy: replicas: 2 restart_policy: condition: any networks: tc-net: driver: overlay attachable: true ipam: config: - subnet: 10.15.0.0/26version: '3.2'
部署服务:
$ docker stack deploy -c docker-compose.yml tc
查看网络:
NETWORK IDNAMEDRIVER SCOPE 927ca7d69973 bridge bridge local 87e7be65d0ce docker_gwbridgebridge local d2ad0895e4f3 hosthostlocal 3rrki5qjsbr4 ingress overlay swarm pknwl0oj3iu2 my-overlayoverlay swarm 8e5de9308b80 nonenulllocal 650m9x2wl04j tc_tc-net overlay swarm$ docker network ls
在网络列表中新增了一个tc_tc-net,这也是我们在compose file中定义的overlay网络。
在manager节点上运行一个redis的单容器服务,指定其连接到tomcat所在的overlay网络:
$ docker run --name my_redis -it -d -p 6379:6379 --network tc_tc-net redis:5.0
CONTAINER ID IMAGECOMMAND CREATED STATUS PORTSNAMES 481fbb0e5b78 redis:5.0 "docker-entrypoint.sh..." 4 seconds ago Up 2 seconds 0.0.0.0:6379->6379/tcp my_redis 254e161ae63c tomcat:8.5"catalina.sh run" 34 seconds agoUp 33 seconds 8080/tcp tc_tomcat.2.ttonphlbithf2g2ocgsqltnna$ docker ps
接下来验证网络通信,进入tomcat服务,ping一下redis的服务,如下:
root@254e161ae63c:/usr/local/tomcat# ping -c 2 my_redis PING my_redis (10.15.0.7) 56(84) bytes of data. 64 bytes from my_redis.tc_tc-net (10.15.0.7): icmp_seq=1 ttl=64 time=0.066 ms 64 bytes from my_redis.tc_tc-net (10.15.0.7): icmp_seq=2 ttl=64 time=0.066 ms --- my_redis ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 2ms rtt min/avg/max/mdev = 0.066/0.066/0.066/0.000 ms$ docker exec -it 254e161ae63c bash
worker节点
CONTAINER ID IMAGECOMMAND CREATED STATUS PORTSNAMES 58083e1ac1c7 tomcat:8.5"catalina.sh run" 2 minutes ago Up 2 minutes 8080/tcp tc_tomcat.1.ecdd4yhm2wrnqjeobi2j6c7f5$ docker ps
root@58083e1ac1c7:/usr/local/tomcat# ping -c 2 my_redis PING my_redis (10.15.0.7) 56(84) bytes of data. 64 bytes from my_redis.tc_tc-net (10.15.0.7): icmp_seq=1 ttl=64 time=0.569 ms 64 bytes from my_redis.tc_tc-net (10.15.0.7): icmp_seq=2 ttl=64 time=0.424 ms --- my_redis ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 3ms rtt min/avg/max/mdev = 0.424/0.496/0.569/0.075 ms$ docker exec -it 58083e1ac1c7 bash
以上,实现和验证了单个容器与swarm服务集群间的网络通信。
如果有收获欢迎分享给你的朋友一起学习和讨论,也欢迎扫码关注公众号进击的极客。
相关链接:
Docker系列之Docker Swarm容器管理与调度
Docker网络篇之bridge网络