ITKeyword,专注技术干货聚合推荐

注册 | 登录

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

chinagissoft 分享于

2020腾讯云10周年活动,优惠非常大!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1040

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

推荐:为Docker容器设置固定IP实现网络联通(1)——通过Pipework为Docker容器设置

目标 本博客已经为大家推出了关于Docker的系列内容,相信各位已经对容器产生了浓厚的兴趣,但是如果你深入进来可能会发现,容器与虚拟机的差别还是比较大,特别

题记

前面我们提到使用两种方式实现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重叠情况,带着这个问题,我们继续探求。


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

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。