一、容器间内部通信

bridge 模式

host 模式

自定义网络

Container 模式

None 模式

跨主机通信


Docker 默认的网络环境下 , 单台主机上的 Docker 容器可以通过 docker0 网桥直接通信 , 而不同主机上的 Docker 容器之间只能通过在主机上做端口映射进行通信。

这种端口映射方式对很多集群应用来说极不方便。

如果能让 Docker 容器之间直接使用自己的 IP 地址进行通信 , 会解决很多问题。

按实现原理可分别直接路由方式、桥接方式 ( 如 pipework) 、 Overlay 隧道方式 ( 如 flannel 、 ovs+gre) 等。

直接路由




跨集群上传与下载hdfs文件_容器


Flannel

Flannel 实质上是一种覆盖网络 (overlay network), 即表示运行在一个网上的网 ( 应用层网络 ), 并不依靠 ip 地址来传递消息 , 而是采用一种映射机制, 把 ip 地址和 identifiers 做映射来资源定位。


也就是将 TCP 数据包装在另一种网络包里面进行路由转发和通信 ,

目前已经支持 UDP 、 VxLAN 、 AWS VPC 和 GCE 路由等数据转发方式


Flannel 实现的容器的跨主机通信通过如下过程实现 :

每个主机上安装并运行 etcd 和 flannel ;

在 etcd 中规划配置所有主机的 docker0 子网范围;

每个主机上的 flannel 根据 etcd 中的配置 , 为本主机的 docker0 分配子网 , 保证所有主机上的 docker0 网段不重复 , 并将结果 ( 即本主机上的 docker0 子网信息和本主机 IP 的对应关系 ) 存入

etcd 库中 , 这样 etcd 库中就保存了所有主机上的 docker 子网信息和本主机 IP 的对应关系;

当需要与其他主机上的容器进行通信时 , 查找 etcd 数据库 , 找到目的容器的子网所对应的 outip( 目的宿主机的 IP) ;

将原始数据包封装在 VXLAN 或 UDP 数据包中 ,IP 层以 outip 为目的 IP 进行封装;

由于目的 IP 是宿主机 IP, 因此路由是可达的;

VXLAN 或 UDP 数据包到达目的宿主机解封装 , 解出原始数据包 , 最终到达目的容器。

跨集群上传与下载hdfs文件_容器_02

Flannel特点

1. 使集群中的不同 Node 主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。

2. 建立一个覆盖网络 (overlay network), 通过这个覆盖网络 , 将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将

一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后 , 将其解封装。

3. 创建一个新的虚拟网卡 flannel0 接收 docker 网桥的数据 , 通过维护路由表 , 对接收到的数据进行封包和转发 (vxlan) 。

4. etcd 保证了所有 node 上 flanned 所看到的配置是一致的。同时每个 node 上的 flanned 监听 etcd 上的数据变化 , 实时感知集群中 node 的变化。

三、环境搭建

1、检查docker与etcd安装与配置

主机                                               ip(根据自己机器变化)                         环境要求
Centos7                                           192.168.181.110                             etcd,docker,flannel    
CentOS7                                         192.168.181.120                             etcd,docker,flannel
 

docker安装与配置

etcd安装与集群搭建

查看两部主机是否拥有👆:systemctl status docker ——》systemctl status etcd

跨集群上传与下载hdfs文件_跨集群上传与下载hdfs文件_03

 

跨集群上传与下载hdfs文件_微服务_04

 

检测两台主机是否在集群内(两边都要测试):etcdctl member list

跨集群上传与下载hdfs文件_微服务_05

跨集群上传与下载hdfs文件_微服务_06

 2、ETCD版本问题

ETCD3.4版本中,ETCDCTL_API=3和etcd --enable-v2=false成为了默认配置
flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API。

为了兼容flannel,将默认开启v2版本,故配置文件中还要设置(两台主机都要操作):

vi /etc/profile        ——》编辑文件

 export ETCDCTL_API=2 # 指定etcdctl命令的版本为v2        ——》将此内容添加到文件中
 

跨集群上传与下载hdfs文件_docker_07

刷新文件:source /etc/profile

 etcdctl2和etcdctl3是不兼容的,两者的api参数也不一样,最关键的是“v2/v3的数据是不互通的”

api 2 使用方法


ETCDCTL_API = 2 etcdctl set key value

ETCDCTL_API = 2 etcdctl ls /

ETCDCTL_API = 2 etcdctl del / -- prefix


api 3 使用方法


ETCDCTL_API = 3 etcdctl put key value

ETCDCTL_API = 3 etcdctl get /

ETCDCTL_API = 3 etcdctl del / -- prefix




3、ETCD中保存网络信息 

使用 v2 版的 set( 而非 put) 命令向 ETCD 中保存 flannel 覆盖网络信息


ETCDCTL_API=2 etcdctl \
--endpoints "http://192.168.218.132:2379,http://192.168.218.133:2379" \
set /coreos.com/network/config \
'{"NetWork":"10.0.0.0/16","SubnetMin": "10.0.1.0","SubnetMax": "10.0.20.0","Backend": {"Type": "vxlan"}}'

跨集群上传与下载hdfs文件_容器_08

Network: 用于指定 Flannel 地址池 , 整个 overlay( 覆盖 ) 网络为 10.0.0.0/16 网段 .

SubnetLen: 用于指定分配给单个宿主机的 docker0 的 ip 段的子网掩码的长度 , 默认值也是 24

SubnetMin: 用于指定最小能够分配的 ip 段

SudbnetMax: 用于指定最大能够分配的 ip 段 , 在上面的示例中 , 表示每个宿主机可以分配一个 24 位掩码长度的子网 , 可以分配的子网从 10.0.1.0/24 到 10.0.20.0/24, 也就意味着在这个网

段中 , 最多只能有 20 台宿主机

Backend: 用于指定数据包以什么方式转发 , 默认为 udp 模式 , 这里使用的是 vxlan 模式 . 因为为 vxlan 比起预设的 udp 性能相对好一些

flannel 访问 etcd 时使用的 key 默认为 :/coreos.com/network, 可修改 , 但必须重新配置 flanneld.conf 的参数 etcd-prefix, 例如 -etcd-prefix=/zking.com/network


4、flannel安装与配置

下载或上传flannel安装包(俩台都要)

跨集群上传与下载hdfs文件_微服务_09

创建flannel安装目录

mkdir -p /opt/flannel


解压到安装目录


tar xzf flannel-v0.11.0-linux-amd64.tar.gz -C /opt/flannel


查看解压后文件


cd /opt/flannel && ls

 

flanneld 为主要的执行文件

sh 脚本用于生成 Docker 启动参数


为flannel创建一个systemd服务,用于后台启动


vim /etc/systemd/system/flanneld.service

[Unit]
Description=Flanneld
After=network.target
After=network-online.target
Wants=network-online.target
##1.flannel服务需要先于Docker启动,后于etcd启动
After=etcd.service
Before=docker.service

[Service]
User=root
##2.ExecStart即flanneld启动程序位置
##3.--etcd-endpoints参数为ectd集群客户端地址
##4.--iface参数为要绑定的网卡的IP地址,或是网卡名(ifconfig查看获得)请根据实际情况修改
ExecStart=/opt/flannel/flanneld \
--etcd-endpoints=http://192.168.181.110:2379,http://192.168.181.120:2379 \
--etcd-prefix=/coreos.com/network \
--iface=ens33 \
--ip-masq
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target


完了之后运行这个 

systemctl daemon-reload && systemctl restart flanneld

验证flannel网络

ifconfig

如果看到 flannel.1 网卡的地址和 etcd 中存储的地址一样 , 这样 flannel 网络配置完成

5、docker配置

在各个节点安装好 Docker, 然后更改 Docker 的启动参数 , 使其能够使用 flannel 进行 IP 分配 , 以及网络通讯


查看flannel分配的网络参数(在Flannel运行之后,会生成一个环境变量文件,包含了当前主机要使用flannel通讯的相关参数)


cat /run/flannel/subnet.env


创建Docker运行参数(使用flannel提供的脚本将subnet.env转写成Docker启动参数)


/opt/flannel/mk-docker-opts.sh -d /run/flannel/docker_opts.env -c

创建好的启动参数位于 /run/flannel/docker_opts.env 文件中 , 可使用 cat 命令查看

cat /run/flannel/docker_opts.env


修改Docker启动参数


vim /lib/systemd/system/docker.service

[Service] 节点中

指定启动参数所在的文件位置 ( 这个配置是新增的 )

EnvironmentFile=/run/flannel/docker_opts.env

在原有 ExecStart 后面添加 $DOCKER_OPTS

修改前 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

修改后 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_OPTS

 

跨集群上传与下载hdfs文件_自动化_10

重新加载systemd配置,并重启Docker

systemctl daemon-reload && systemctl restart docker && systemctl status docker

跨集群上传与下载hdfs文件_docker_11


ifconfig

跨集群上传与下载hdfs文件_docker_12

6、测试flannel


下载centos镜像,因为此镜像中其它软件及命令均有安装


docker run -it --name=centos centos bash


依次查看集群内容器的flannel.1网络IP


cat /etc/hosts

docker inspect bridge


从不同宿主机容器到其他宿主机容器


ping -c3 192.168.181.120
ping -c3 10.0.15.2

跨集群上传与下载hdfs文件_微服务_13

  

跨集群上传与下载hdfs文件_docker_14


解决flannel下容器无法跨主机互通问题



经测试 , 发现是防火墙的问题 , 关闭防火墙后问题解决 , 但作为服务的防火墙是不能关闭的 , 如何解决呢。

这是由于 linux 还有底层的 iptables, 所以在 node 上分别执行 :



iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT 
iptables -F 
iptables -L -n

跨集群上传与下载hdfs文件_容器_15