为什么需要跨容器主机通信?我们的应用可能和所依赖的基础设施不是部署在同一台机器上,我们会把mysql之类的基础设施部署在test-node-1上,测试应用部署在test-node-2上,因此会出现2台机器上的2个容器需要互相通信的需求。
由于笔者这里就用了2台服务器,就不搭建集群了(swarm、k8s),我们这里期望的是最简单的跨主机通信实现方案,像swam这种是自带跨主机通信的,但是今天我们不用。我们采用kv存储器来作为跨主机通信的实现方案,docker支持多种kv存储器,这里使用consul
。
玩过微服务的同学可能知道conusl,consul在微服务中作为注册中心,同时它也是个kv存储器。
1、安装consul
consul我们安装在test-node-1这台上,因此这一节的操作都是在test-node-1上进行的,方便起见,我们直接把consul安装在docker环境中,但是这样做有一个坏处,重启docker会比较慢,因为docker连不上consul会不断重试。如果介意的话,可以直接安装到宿主机上。
docker run -d -p 8500:8500 \
-v /data/consul:/consul/data \
-e CONSUL_BIND_INTERFACE='eth0' \
--name=consul1 \
consul agent -server -bootstrap -ui -client='0.0.0.0'
⚠️注意:consul一定要开启持久化!否则当consul重启后,数据会被清空,会影响已经启动的其他容器!究其原理,docker把网络参数存储到了consul中,共享给其他的docker实例。上述的容器创建命令已经开启持久化。
2、验证容器
执行下面的命令:
docker ps -a
执行结果如下图,并且STATUS
是Up
状态。
3、可视化界面
过浏览器访问172.16.113.9:8500
,正常情况可以打开consul的管理界面。
4、配置docker
⚠️2台机器都要操作
这一步是关键步骤,我们需要修改docker的配置,让docker接入到consul中,把网络参数共享出来。
# 编辑docker的配置文件
vim /etc/docker/daemon.json
配置内容中新增"cluster-store": "consul://172.16.113.9:8500",
结果如下:
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn"
],
"cluster-store": "consul://172.16.113.9:8500",
"graph": "/data/docker"
}
最后需要重启
systemctl restart docker
这样就完成了网络打通,可以发现在consul中已经被注册进来了。
5、创建overlay网络
overlay驱动的网络可以实现跨主机通信,现在我们可以创建一个试试。在任何一台机器上执行,笔者在test-node-2上执行:
docker network create \
--driver overlay \
--attachable \
--subnet 10.10.0.0/24 \
app_network
结果如下图:
6、验证overlay网络
可以在test-node-1上执行docker network ls
进行查看docker网络列表,如果列表中出现了app_network
,就说明跨主机通信网络搭建成功了。下图是命令执行结果:
7、小结
这里主要使用了consul的key/value存储来实现的容器跨主机通信,docker不止是支持consul,还可以使用其他的比如etcd等等来实现。