【06】循序渐进学 docker:跨主机通信

写在前面的话

 

目前解决容器跨主机通信的方案有很多种,这里给出的只是其中的一种,而且还不是最好的方案,不过归根结底,大同小异。在学习 docker swarm 之前,大家可以先看看这种。

 

 

啥是 overlay 和 etcd

 

从这里开始正式引入 overlay 网络这个概念,那啥是 overlay 呢?

可以这样理解,在原本主机通信之上开通的通信隧道,覆盖于原本的主机网络之上,所以叫 overlay。

那 etcd 又是啥?它源于 zookeeper,一个用于分享配置和服务发现的分布式一致性 KV 存储系统。

为啥将这两个东西放在一起?我们的目的就是为了搭建一个能够静态发现,并且能够实现配置共享的容器网络~

etcd 下载地址:

https://github.com/etcd-io/etcd/tags

 

 

多主机多容器实践

 

这里以实例的形式来实现这个功能,需要准备两台安装了 docker 的虚拟机,我这里分别是:

docker-node1:192.168.100.100(之后统称 node1)运行 redis 容器

docker-node2:192.168.100.101(之后统称 node2)运行 flask 容器

具体的拓扑图如下所示,项目就是之前的 flask + redis 项目:

 

在开始之前,有几点要特别说明:

1. 由于中间会涉及几个端口,建议关闭防火墙,可以省掉很多麻烦。

2. 一定要让两台机器的主机名有意义且不一样,否则莫名其妙的 BUG 调哭你。 

3. 为了直接安装 etcd 建议安装 epel 源。

# 修改主机名
hostnamectl set-hostname docker-node1
hostnamectl set-hostname docker-node2

# 关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service

# 安装 epel 源
yum -y install epel-release

截至我写文之前,GITHUB 上面 etcd 最新 TAG 为 3.3.12,而 epel 里面的版本为:3.3.11,所以推荐 epel 源直接 yum 安装。

 

【1】在 node1 上安装配置 etcd: 

yum -y install etcd
cd /etc/etcd/
mv etcd.conf etcd.conf_bak
vim etcd.conf

内容如下:

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="docker-node1"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.100.100:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.100.100:2379,http://192.168.100.100:4001"
ETCD_INITIAL_CLUSTER="docker-node1=http://192.168.100.100:2380,docker-node2=http://192.168.100.101:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

说明:有几个值得注意的地方需要说明:

ETCD_NAME:必须唯一,而且在之后的 ETCD_INITIAL_CLUSTER 参数也会用到。

Clustering 下面的配置除了 ETCD_INITIAL_CLUSTER 里面指定其他节点需要用到其他的 IP,否则都使用本机的 IP。

ETCD_INITIAL_CLUSTER_TOKEN:所有的节点都必须配置一样的值,相当于密钥

 

【2】在 node2 上面也安装 etcd 和配置 etcd:

yum -y install etcd
cd /etc/etcd/
mv etcd.conf etcd.conf_bak
vim etcd.conf

内容如下:

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="docker-node2"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.100.101:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.100.101:2379,http://192.168.100.101:4001"
ETCD_INITIAL_CLUSTER="docker-node1=http://192.168.100.100:2380,docker-node2=http://192.168.100.101:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

同 node1 的配置,只是需要注意有些标识性的配置改为自己的就行。 

简单的做个参数说明:

关键字说明
ETCD_DATA_DIR数据存储目录
ETCD_LISTEN_PEER_URLS与其他节点通信时的监听地址列表,通信协议可以是http、https
ETCD_LISTEN_CLIENT_URLS与客户端通信时的监听地址列表
ETCD_NAME节点名称,在也就是后面配置的那个 名字=地址
ETCD_INITIAL_ADVERTISE_PEER_URLS节点在整个集群中的通信地址列表,可以理解为能与外部通信的ip端口
ETCD_ADVERTISE_CLIENT_URLS告知集群中其他成员自己名下的客户端的地址列表
ETCD_INITIAL_CLUSTER集群内所有成员的地址,这就是为什么称之为静态发现,因为所有成员的地址都必须配置
ETCD_INITIAL_CLUSTER_TOKEN初始化集群口令,用于标识不同集群
ETCD_INITIAL_CLUSTER_STATE初始化集群状态,new表示新建

 

【3】在两个节点都启动 etcd 并查看:

systemctl start etcd
systemctl enable etcd

# 查看节点
etcdctl member list

# 监控检查
etcdctl cluster-health

结果如图:

如果发现不通报错,一般都是防火墙问题。

 

【4】修改两个 docker 的启动配置:

node1:

systemctl stop docker
vim /etc/systemd/system/multi-user.target.wants/docker.service

 ExecStart= 项改成如下内容:如果文件不存在,记得:systemctl enable docker.service

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.100.100:2379 --cluster-advertise=192.168.100.100:2375

启动 docker:

systemctl daemon-reload
systemctl start docker

 

node2:

systemctl stop docker
vim /etc/systemd/system/multi-user.target.wants/docker.service

 ExecStart= 项改成如下内容:

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.100.101:2379 --cluster-advertise=192.168.100.101:2375

启动 docker:

systemctl daemon-reload
systemctl start docker

 

【5】 在 node1 上面我们创建一个 overlay 网络:

# 创建网络
docker network create -d overlay demo

# 查看
docker network ls

结果如图:

此时在 node2 上面查看网络应该也是存在的~

如果你发现 node2 没有同步或者在 node1 上面直接创建就报 docker swarm 错误,建议重启两个机器的 etcd 服务和 docker 服务,一般就能解决。

 

【6】我们此时可以创建两个测试容器测试网络的连通性:

node1:

docker run -d --name b1 --net demo busybox sh -c "while true; do sleep 3600; done"

 

node2:

docker run -d --name b2 --net demo busybox sh -c "while true; do sleep 3600; done"

 

node1 上测试连通性:

docker container exec b1 ping b2

可以发现已经可以正常通信了。

 

【7】导出和导入镜像:

这里专门提供了一种导出和导入镜像的方法,因为在 node2 上面没有 Flask 项目的镜像,可以在 node1 上的镜像导出,再到 node2 上面导入,可以节省我们下载的时间。

node1:

docker save python:2.7 dylan/flask-demo:v1.0 -o image.tar

 将镜像传到 node2 上面,然后在 node2 执行:

docker load -i image.tar

完成以后在 node2 上面就有了这些镜像。

 

【8】运行项目:

node1:运行 redis 容器

docker run -d --name redis --network demo redis

 

node2:运行 flask 容器

docker run -d --name flask-demo --network demo -it -e REDIS_HOST="redis" -p 8080:5000 dylan/flask-demo:v1.0

 

【9】访问测试:

值得我们注意得是,在这里也没有指定 --link 参数。

 

 

小结

 

总的来说,这种方法还是很复杂的,而且由于是静态发现,每一次增加减少节点都会去修改配置重启 etcd,非常不方便。

转载于:https://www.cnblogs.com/Dy1an/p/10609031.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值