您的位置:首页 > 运维架构 > Docker

为Docker容器设置固定IP实现网络联通(3)——如何节省IP资源防止主机网络广播风暴

2016-05-04 08:54 1221 查看
题记

前面我们提到使用两种方式实现Docker容器实例与主机网络的固定IP设置,也实现了外部网络与Docker容器的相互访问,而且这种方式支持跨主机容器实例的网络连通,但是不知道大家考虑过没有,使用这种方式其实也存在大量的问题:

1、Docker容器占用大量的主机网络的IP地址资源

2、大量Docker容器可能引起广播风暴,导致主机所在网络性能下降

3、Docker容器连在主机的网络中可能引起安全问题

--------------------------------------------------------------------------------------

Blog:    http://blog.csdn.net/chinagissoft

QQ群:16403743

宗旨:专注于"GIS+"前沿技术的研究与交流,将云计算技术、大数据技术、容器技术、物联网与GIS进行深度融合,探讨"GIS+"技术和行业解决方案

转载说明:文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

--------------------------------------------------------------------------------------

那么接下来,我们就以上面的问题,看看如何解决。

本博客就是用最简单的方法,如果你已经理解了上两个博客设置固定IP的话,其实原理很简单,还记得我们为容器设定固定IP的时候,在创建容器实例添加了一个--net=none,也就是不使用默认的网络资源,其实在实际中,我们可以使用已经默认的docker0网桥,为容器实例添加一个新的网卡,这个网卡可以设置主机网络的固定IP,另外一个docker0网络与其他容器实例组成集群连接,不就解决问题了么。



如上图所示,在一个主机服务器上,安装完Docker程序后,默认创建一个docker0网桥,172.17.0.1,如果创建docker实例,实例上自动添加一个eth0网卡,IP默认172.17.0.x,在同一主机服务器上的容器实例都在docker0网桥上可以相互连接,为了节省IP资源,我们可以为容器C1添加一个新的网卡eth1,设置主机固定IP,这样我们就可以直接访问容器C1,而c1又可以与其他容器进行连接。

1、创建容器实例已经不需要添加--net=none

root@controller:~/docker-static-ip-master# docker exec -it test1 /bin/bash
root@b1308e21f885:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
29: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever


2、添加容器固定IP

root@b1308e21f885:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
29: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
31: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 62:68:d9:65:27:1d brd ff:ff:ff:ff:ff:ff
inet 192.168.14.243/24 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::6068:d9ff:fe65:271d/64 scope link
valid_lft forever preferred_lft forever


这种需求经常存在,例如SuperMap iServer集群,Hadoop\Spark集群等,都可以使用该方式设置网络,节省大量的主机网络IP资源。

需要注意的是,前面介绍了两种方式:

1、pipework的方式,直接为容器添加了一个eth1网卡,这个直接可以用

2、使用python脚本的方式,该脚本默认添加到eth0网卡,所以需要修改一下脚本即可,也比较简单,直接把脚本里面的eth0修改为eth1即可。

#!/usr/bin/python
# -*- coding:UTF-8 -*-

'''

__author__ = 'lioncui'
__date__ = '2015-6-16'

'''

import docker
import os
import time

try:
connect = docker.Client(base_url='unix:///var/run/docker.sock',version='1.17',timeout=120)
connect.version()
except:
exit()

def Duration(id, br, addr, gw):
try:
container_info = connect.inspect_container(resource_id=id)
pid = str(container_info['State']['Pid'])
except:
pid = 0

if int(pid) != 0:
if not os.path.exists('/var/run/netns'):
os.makedirs('/var/run/netns')
source_namespace = '/proc/'+pid+'/ns/net'
destination_namespace = '/var/run/netns/'+pid
if not os.path.exists(destination_namespace):
link = 'ln -s %s %s' % (source_namespace,destination_namespace)
os.system(link)
os.system('ip link add tap%s type veth peer name veth%s 2>> /var/log/docker-static-ip.log' % (pid,pid) )
os.system('brctl addif %s tap%s 2>> /var/log/docker-static-ip.log' % (br,pid) )
os.system('ip link set tap%s up 2>> /var/log/docker-static-ip.log' % pid )
os.system('ip link set veth%s netns %s 2>> /var/log/docker-static-ip.log' % (pid,pid) )
os.system('ip netns exec %s ip link set dev veth%s name eth1 2>> /var/log/docker-static-ip.log' % (pid,pid) )
os.system('ip netns exec %s ip link set eth1 up 2>> /var/log/docker-static-ip.log' % pid)
os.system('ip netns exec %s ip addr add %s dev eth1 2>> /var/log/docker-static-ip.log' % (pid,addr) )
os.system('ip netns exec %s ip route add default via %s 2>> /var/log/docker-static-ip.log' % (pid,gw) )

syspid = os.fork()

if syspid == 0:
while True:
file = open('./containers.cfg')
if file:
for i in file:
i = i.strip('\n')
cfg = i.split(',')
Duration(*cfg)
file.close()
time.sleep(10)
else:
exit()


问题

当然,你也可能提到,你现在举得例子是一个容器主机,如果跨主机容器连接,通过172.17网段如何实现,而且他们可能出现IP重叠情况,带着这个问题,我们继续探求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: