详解Docker 跨服务器通讯 Ambassador原理
先看拓扑图:ambassador 主要用来解决跨服务器通讯,因为同服务器通讯相对简单,直接用--link参数,或者用bridge网络即可。
服务器b的docker2:centos想要访问服务器a的docker1:nginx,但是不知道对方的端口和ip,这时就需要通过ambassador来解决。(ambassador后续版本应该会被抛弃,overlay网络应该是趋势)
1、先建立docker1:nginx
docker run -d --name nginx1 nginx
2、建立ambassador 1
docker run -d --name a1 --link nginx1:nginx1 -p 8000:80 svendowideit/ambassador
3、建立ambassador 2
docker run -d --name a2 --expose 8001 -e a2__port_8001_tcp=tcp://172.16.16.201:8000 svendowideit/ambassador
(暴露8001端口给centos,然后将8001端口的流量转到服务器1的8000端口,即间接访问了ambassador1)
4、建立docker2:centos
docker run -it --name centos1 --link a2:a2 centos /bin/bash
至此所有的步骤完成。
那么此时centos如何访问nginx呢?
curl a2:8001 访问ambassador2的8001端口即可,不需要知道服务器a的任何信息。(截图中用a200,由于之前已经弄好环境,不想改了)
具体的流量途径如下:
1、centos访问ambassador2的时候将直接访问它的8001端口。
2、ambassador2 中参数 -e a200__port_8001_tcp=tcp://172.16.16.201:8000 将访问8001端口的流量重新转到服务器a的8000端口。
a2__port_8001_tcp=tcp://172.16.16.201:8000 其中a2你可以随便命名,为什么呢。我们进入到ambassador2中看看原因:
输入env查看环境变量,和创建时的参数一致。
输入top,如图,系统只会对8001端口的流量转发到172.16.16.201:8000上,也就是服务器a的8000端口,压根不在乎会上边说的a2,原因如下:
ambassador dockrfile中有如下参数:
cmd env | grep _tcp= | sed 's/.*_port_\([0-9]*\)_tcp=tcp:\/\/\(.*\):\(.*\)/socat tcp4-listen:\1,fork,reuseaddr tcp4:\2:\3 \&/' | sh && top
我们按照此参数用a2__port_8001_tcp=tcp://172.16.16.201:8000执行sed 如下:
该shell语句只是单独提取其中的8001端口和后边的ip地址部分,其他的字段全部忽略,所以,其他字段只需要按照docker 中环境变量的格式即可。
3、ambassador1中,-p 8000:80 参数中的80要和nginx的端口80一致,因为--link nginx1:ngxin1后,ambassador1中的环境变量如下
此时会将80端口的流量转到nginx服务器上的80端口。假设我们使用 -p 8000:81参数,那么ambassador1中并没有对应的81端口的转发规则,当然其他服务器器也服务访问到nginx了。
网上很多教程全程采用同一个端口,初学者很难理解其中的原理,在实践中会遇到很大的麻烦,我这边整体梳理一下,希望帮到大家。