目录
1 iptables简介
iptables很重要,但是我还没未进行详细学习,这里这是介绍个大概,后续进行补充完善。在本文2.3的第(5)部分中涉及到了iptables的相关内容,所以在这里对iptables做个介绍。
- iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的”安全框架”中,这个”安全框架”才是真正的防火墙,这个框架的名字叫netfilter
- netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。
- iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。
1.1 基本操作指令
- 查看filter表所有规则(-t不写的话,默认查询filter表)
iptables -L
- 查看nat表中的DOCKER链的信息(v:显示详细信息,n:以数字的方式显示ip、port)
iptables -t nat -vnL DOCKER
- 将当前的iptables配置导出为标准输出
iptables-save
1.2 iptables 工作流程
2 实现多主机间Docker容器通信
2.1 目标
- 创建虚拟机1(centos7),开启Docker容器a
- 创建虚拟机2(centos7),开启Docker容器b
- 保证a、b之间能相互ping通
2.2 操作步骤总结
- 在任意一台主机上安装ETCD,用来存储网络相关的环境变量信息
- 将子网信息(B级ip)写入ETCD
- 在2台要相互访问的主机上分别安装Flannel,对接ETCD
- 在2台要相互访问的主机上分别配置Docker要使用Flannel生成的子网信息(C级ip)
- 在2台要相互访问的主机上分别配置“允许数据包转发”
- 验证
整体过程如下图:
2.3 具体操作步骤
(1) etcd的安装、配置、启动(在虚拟机1中安装)
- 安装:yum install etcd -y
- 修改配置文件(localhost改为ip):vi /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://安装etcd的宿主机ip:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://安装etcd的宿主机ip:2379"
- 启动:systemctl start etcd
- 设置开机启动:systemctl enable etcd
(2) 将规划好的子网写入etcd
键是一个文件“config”,值是json字符串,描述一个子网
etcdctl --endpoints="http://安装etcd的宿主机ip:2379" set /atomic.io/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}} '
(3) Flannel 的安装、配置(2台虚拟机都需要安装)
- 简介:Flannel是CoreOS维护的一个网络组件,在每个主机上运行守护进程负责维护本地路由转发,Flannel使用ETCD来存储容器网络与主机之前的关系。
- 安装:yum install flannel -y
- 配置:vi /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://宿主机ip:2379"
- 基于“大子网(B类ip)”,Flannel启动后会进一步生成子网信息(C类ip),作为docker的环境变量
- 查看子网信息(Flannel启动后,现在还没启动):cat /var/run/flannel/docker
(4) 配置Docker使用Flannel生成的网络信息(把本机Docker和Flannel关联起来,2台都要)
- 打开如下文件:vi /usr/lib/systemd/system/docker.service
- 在 ExecStart 前新增一行
EnvironmentFile=/run/flannel/docker
- ExecStart这一行的内容更改为:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_NETWORK_OPTIONS
(5) 将两台虚拟机的FORWARD链设置为允许(2台虚拟机都需要配置)
- 默认情况下,输入指令 iptables -vnL 会发现FORWARD链默认是拒绝状态
- 即:来自外部的访问数据包进入到Linux系统之后,如果数据包的目的ip不在本机ip网段内的话(宿主机网段和docker网段隔离的),
- 该数据包会被判断是否满足FORWARD链的规则,如果满足则路由到目的ip(docker容器上)
- 输入指令,可以让来自外部的数据包访问到Docker容器(如果主机A设置该iptables规则,则其他主机中的Docker容器可以访问到该主机中的Docker容器,前提当然要保证两台主机之间本身是能ping通的):
- 哪台虚拟机的容器需要被访问,就输入指令:
iptables -P FORWARD ACCEPT
(6) 服务启动
在2台主机上分别进行如下操作:
- 重新加载配置文件:systemctl daemon-reload
- 启动Flannel:systemctl restart flanneld
- 设置Flannel开启自启动:systemctl enable flanneld
- 重启Docker:systemctl restart docker
如果后来又修改了相关配置,需要先重启Flannel,再重启Docker(不是必要操作,按需进行):
- systemctl restart flanneld
- systemctl restart docker
(7) 验证
在a容器中pingb容器,b容器中pinga容器,保证相互之间能ping通即可。
分析如下:
- 分别在两台宿主机上查看Docker分配ip的情况:ps -ef |grep docker
- 同一个ETCD(先规定一个大子网,让不同docker容器配置ip),对应多个不同的Flannel,具体分配各docker子网ip的工作由各自宿主机的Flannel来完成。于是,解决了不同主机docker容器ip冲突的问题
- 具体来说:当初我们在ETCD中规划的“大子网”在"172.17.0.0/16"范围内,是一个B类ip,然后不同宿主机下的Flannel为Docker分配的ip范围(C类ip)分别在:bip=172.17.99.1/24 、bip=172.17.75.1/24范围内。C类ip的范围是在B类ip的基础上随机分配的,即便往ETCD中加入新的Docker,那么Flannel给这个Docker分配的ip段也是基于"172.17.0.0/16"分配的,且和其他Docker的ip不会冲突
- 我们发现:两个dockerIP的范围都在最初规划的“大子网”"172.17.0.0/16"范围内。flannel启动后会生成如下文件信息,作为docker的环境变量:cat /var/run/flannel/docker
- 在Docker启动时,读取上述变量文件并引用:vi /usr/lib/systemd/system/docker.service