前言
docker 1.10以上版本的内置overlay网络挺好用的,奈何公司的线上环境必须是centos6.6,内核版本不够,只能基于ovs另搭建一套网络环境,使容器能够跨主机互通。
本文基于的操作环境,centos6.6
因为要操作network namespace,所以要升级下iproute,参见http://www.xiaomastack.com/2015/04/05/centos6-ip-netns/
本文从docker容器使用ovs网桥开始,最终搭建一个跨主机容器通信网络。
Docker 使用 OpenvSwitch 网桥
主要步骤可以参见 Docker 使用 OpenvSwitch 网桥
这里边有两个改进的地方(其实是一个)
- 无需到Container内部设置容器ip设置容器的ip时,可以使用ovs-docker。
https://github.com/openvswitch/ovs/raw/master/utilities/ovs-docker
。比如ovs-docker add-port vxbr eth1 fe8d1b02dc90 --ipaddress=10.1.2.3/24
或者ovs-docker add-port vxbr eth1 fe8d1b02dc90 // 获取容器进程id docker inspect --format "" fe8d1b02dc90 1915 ln -s /proc/1915/ns/net /var/run/netns/1915 ip netns exec 1935 ifconfig eth1 10.1.2.3/24
- 容器的ip从dhcp服务器获取,而非静态设置
从dhcp服务器获取容器ip
首先,需要搭建一个dhcp服务器,
在docker使用的过程中如果要自定义容器的网络设备(主要是指定IP地址),就要用到网络namespace(可以理解为进程级别的网络设备),关于namespace介绍可以查阅其它相关质料。centos默认安装的iproute包是不支持网络namespace操作的,使用ip netns会出现类似这样的报错:
Object "netns" is unknown, try "ip help" . |
谷歌度娘了一番,解决的方法都是升级内核和升级指定的iproute包。其实内核是不用的升级的,centos6.6版本的内核支持网络namespace操作的。只需要升级iproute包即可:
#安装yum源 [root@xx-xxxx ~] # yum install -y http://rdo.fedorapeople.org/rdo-release.rpm #修改yum的地址,网上提供的地址目前是无效的,貌似地址目前已经变成下面这个了 [root@xx-xxxx ~] # cat /etc/yum.repos.d/rdo-release.repo [openstack-juno] name=OpenStack Juno Repository baseurl=http: //repos .fedorapeople.org /repos/openstack/openstack-icehouse/epel-6/ enabled=1 skip_if_unavailable=0 gpgcheck=0 gpgkey= file : ///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-Juno [root@xx-xxxx ~] # #安装指定yum源的iproute包 [root@xx-xxxx ~] #yum --enablerepo=openstack-juno install iproute |
centos6.6只要升级指定的iproute包即可,不用升级内核。centos6其它版本的没有测试,未知。
后来源的地址改变,目录改变了,具体baseurl变成了
修改配置文件
cp /usr/share/doc/dhcp-3.0.5/dhcpd.conf.sample /etc/dhcp/dhcpd.conf
,添加如下内容:
subnet 10.1.2.0 netmask 255.255.255.0 {
range 10.1.2.100 10.1.2.200;
option subnet-mask 255.255.255.0;
# option routers 10.1.2.1;
}
在这里,我们只需要根据dhcp获取动态ip,至于routers等信息则没有必要。配置routers会更改容器的路由表,跟我们的下列设计不符。
安装后,打开防火墙,允许其它主机访问67端口。
iptables -A INPUT -m state --state NEW -p udp --dport 67 -j ACCEPT
创建容器并设置动态ip
// 创建容器,此处只是用ovs网桥,所有使用none网络模式
docker run -d -P --net=none 192.168.3.56:5000/tomcat7 bash /start.sh
fe8d1b02dc90
// 为容器添加网卡
ovs-docker add-port vxbr eth0 fe8d1b02dc90
// 获取容器进程id
docker inspect --format "" fe8d1b02dc90
3599
// ip套件默认操作的是/var/run/netns下的数据
ln -s /proc/3599/ns/net /var/run/netns/3599
// 设定网卡ip
ip netns exec 3599 dhclient eth0 -pf /var/run/dhclient-fe8d1b02dc90-eth0.pid \
-lf /var/lib/dhclient/dhclient-fe8d1b02dc90-eth0.lease
使用dhclient(一种dhcp客户端)时,常见用法是dhcpclient iface
,如果想要设置多个iface。
dhcpclient iface1 iface2
- 指定pid file和lease file
笔者在实践时,有一个疑问,pipework可以分开做以下两件事
pipework vxbr -i eth0 $CONTAINERID 10.1.2.3/24
,为容器增加eth0网卡并设置ipovs-docker add-port vxbr eth0 $CONTAINERID &&
pipework eth0 $CONTAINERID dhclient
合起来干,笔者没走通,最后只好直接用pipework dhcp特定的底层实现。
跨主机容器互通
上文解决了容器使用ovs网桥并动态设置ip的问题,再将不同主机的ovs网桥“连起来”,就可以解决容器互通问题。参见Docker+OpenvSwitch搭建VxLAN实验环境
假设已在192.168.56.105
和192.168.56.106
上完成上述操作,则
在192.168.56.105
上
ovs-vsctl add-port vxbr vxlan -- set interface vxlan type=vxlan options:remote_ip=192.168.56.106
在192.168.56.106
上
ovs-vsctl add-port vxbr vxlan -- set interface vxlan type=vxlan options:remote_ip=192.168.56.105
即可实现192.168.56.105
和192.168.56.106
上容器的跨主机通信。
一个容器两个网桥
每个主机安装一个ovs,通过上文的操作可以为容器提供一个overlay网络,保证容器间互通。那么容器与外界的交互呢?办法之一是,一个容器两个网卡(假设叫eth0和eth1),eth0连接docker0(即保持容器原有的docker0网络),负责与外界网络通信。eth1连接ovs网桥,负责容器的跨主机访问。
另一个办法是,容器只有一个网卡,连接ovs网桥,自己设置iptables规则(还未实验)
其它要做的
- 移除docker的时候,记得用ovs-docker删除一下port
- 部分操作脚本化
- 系统重启后,docker容器重启需要做什么样的工作
- 这套办法想办法直接做成docker的network plugin
- 清除
/var/run/netns/
下的软链接
评论前必须登录!
注册