Docker之间的通信方式
概述
我们可以将服务发布到Docker中,然后发布Docker到各个环境,比如开发、测试、生产环境,不再需要像以前那么麻烦,需要一个个的环境进行配置,经常会为了环境之间的差异,花费大量的时间去排查问题,所以使用 Docker提高了我们的研发交付的效率。但是在使用Docker的时候,我们可能会碰到一个场景,那就是服务A需要访问服务B,如果这两个服务都是部署在Docker中,问题就变为我们就需要能够让这两个docker容器进行通信,为了要让这两个Docker容器进行通信,我们就需要将这两个docker都加入到同一个网络中,这个网络可以是虚拟的网络,也可以是实际的物理网络,具体如何操作详情见下文。
利用物理网络进行通信的介绍
如果要通过实际的物理网络进行通信,那么我在启动docker的时候,会有如下的写法:
docker run -d --name serviceA -p 80:8080 serviceA
这就将serviceA在docker内服务的8080端口映射到宿主机器的80端口上,这样服务A和服务B之间就可以通过宿主机的网络进行通信,服务B以如下的方式启动:
docker run -d --name serviceB -p 81:8080 serviceB
那么我们在服务A中需要访问服务B,就可以利用服务B在物理机器的IP和端口进行通信。
利用虚拟网络的方式进行通信
除了物理网络通信的方式外,Docker还提供了一个种通过虚拟网络进行通信的方式,首先我们通过如下的命令,创建一个虚拟的docker网络,
docker create network demo
然后再通过如下的命令,检查一下demo这个网络的定义信息:
[sshuser@SY-SUZ-SRV73 ~]$ docker network inspect demo
{
"Name": "demo",
"Id": "017b50fa475dafa62ca0cfe4675cc38201be16d19da52f308226952f1c57b5bb",
"Created": "2019-05-22T11:57:02.010906134+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.21.0.0/16",
"Gateway": "172.21.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
},
"Options": {},
"Labels": {}
}
]
可以观察到containers节点都为空,下面我们将要把serviceA和serviceB都加入的上面创建的demo网络中 。
docker run -d --name serviceA --net=ci -p 80:8080 serviceA
docker run -d --nam serviceB --net=ci -p 8081:8081 serviceB
上面的命令中的–net用来指定前面创建的虚拟网络的唯一ID。这样我们就可以在serviceA或者serviceB中互相以服务名字来访问对方。
总结
以物理网络的方式访问,服务双方通信会经过物理网卡,而通过虚拟网络的方式通信,不会经过物理网卡,所有的通信数据都在在操作系统的内存中进行交互,所以虚拟网络的通信效率肯定会比物理网络的效率高很多。而且在服务依赖的时候,我们以服务名作为依赖,比用物理的IP地址和端口的依赖形式的可读性高。