最近因为工作要求需要用学习使用docker,最后卡在了网络配置这一块。默认情况下启动容器的时候,docker容器使用的是bridge策略比如:

docker run -ti ubuntu:latest /bin/bash
等效于
docker run -ti --net=bridge ubuntu:latest /bin/bash

bridge策略下,docker容器自动为我们分配了一个IP地址,并连接到docker0的网桥上。但这里有一个问题,这个IP地址并不是静态分配的,这对我们的对容器的实例的网络管理造成一了些困难。这里笔者并不想直接给出解决方案,因为那样子并没有什么卵用,理解原理,一步一步踏实走才是。

相信看过docker介绍的读者都知道docker是借助于cGroup和namespace技术来实现资源控制和隔离的。在开始之前读者需要去看一下linux上namespace的使用,本文并不想带入太多的其它不相关的主题。好了现在假设你已经了解namespace了,那你肯定想知道docker在网络上是怎么利用namespace来做手脚的。大致过程应该和下面的一致:(下面只是个人猜测,因为笔者并没有太多时间去研究它的源码)

1、创建一个Net Namespace  netns1。

2、创建一对veth,将peer加入到netns1,将别一端接入到网桥bridge0中。

3、为这两个veth分配IP。

4、用netns1启动容器中的程序比如/bin/bash。

可惜的是,docker run并没有一个选项让我们去指定所分配的IP,因为网络的确是个大难题。那就得自己动手丰衣足食了。

从上面我们知道,docker在网络这里用到了Net namespace,veth和网桥bridge。注意如果你意图使用ip netns list去查看docker在启动容器的时候使用了那个netns,你会失望地发现没有对应netns。其实并不是没有,而是docker为了掩盖一些细节,在做完初始化工作后,docker便将这个netns从/var/run/netns中删除了,我们完全可以用下面的方式让它打回原形:

ln -s /proc/${container's pid}/ns/net /var/run/netns/${the's name you want to display}
ip netns list

好了,现在说一下我们给容器分配静态IP的思路:

1、用--net=none方式启动容器,这样容器有了自己的namespace(这一步我们无法干预的,so let it go!)

2、获取容器的进程号PID,然后根据PID将它的Net namespace打回原型。

3、创建一个bridge0,用brctl工具(可以通过安装bridge-utils工具来实现)。

4、创建一对veth:vethBridge,vethContainer,将peer端vethContainer加入到窗口的Net namespace中,将vethBridge接入到bridge0中:brctl add...

5、设置vethContainer的IP。

6、重启容器的network service。

下面以我机器为例(deepin 2015 kernel 4.5.0)

1、 启动容器:

2、获取容器的进程号:

3、根据进程号将容器的Net namespace打回原型:

4、创建网桥bridge0

5、创建veth,配置对应的veth,最后重启容器的network service

6、在容器中可以看到静态分配的IP: 192.168.9.10

注意,现在容器还不能与主机通信,因为主机没有到bridge的设备,如果需要和主机进行通信的话可以添加一对veth,将一端接入bridge。如果容器需要我外部通信的话,可以通过启用内核转发,并在iptables中添加相应的转发规则。

docker容器分配静态IP的更多相关文章

  1. 为Docker容器设置静态IP

    此文已由作者袁欢授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 创建docker容器 docker run -it --name=yh -h yh --net=none de ...

  2. docker容器配置独立ip

    一般安装docker后都会通过端口转发的方式使用网络,比如 “-p 2294:22” 就将2294抓发到22端口来提供sftp服务,这样使用起来没有问题.但端口号很难记忆,如果前边有nginx等抓发工 ...

  3. 为docker容器设置独立ip

    docker 1.12使用新版macvlan设置与宿主机同网段ip ****************************************** 由于开发的一些特殊需求,需要将容器部署在与宿主 ...

  4. 虚机分配静态IP地址

    在为虚机分配静态IP地址池的IP时,如果报错“没有从与 VMSubnet 相关的 IP 池中为虚拟网络适配器 9i [MAC: 001DD8B71C17] 分配 CA (客户地址)” 使用“动态获取” ...

  5. OpenVPN分配静态IP以及同一网段内IP个数(64个)

    说明:简单的来说,同一网段内可用的IP数量只有64个:(不一定正确)最直接的解释就是每个客户端占用两个IP,因为根据IP掩码位/30得知可用的IP就是两个.对于为什么只有64个,下面是官方的解释. 解 ...

  6. 让Docker容器使用静态独立的外部IP(便于集群组建)

    需要使用Docker虚拟化Hadoop/Spark等测试环境,并且要可以对外提供服务,要求是完全分布式的部署(尽量模拟生产环境).那么我们会遇到几个问题: Container IP 是动态分配的 Co ...

  7. (为容器分配独立IP方法二)通过虚拟IP实现docker宿主机增加对外IP接口

    虚拟IP.何为虚拟IP,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个虚IP,使用这两个IP中的任意一个都可以连接到这台主机,所有项目中数据库链接一项配 ...

  8. docker (2)---存储、网络(利用docker容器上线静态网站)

    一.docker底层依赖的核心技术 1.命名空间 (Namespaces) 2.控制组 (Control Groups) 3.联合文件系统 (Union File System) 4.Linux 虚拟 ...

  9. 利用pipework为docker容器设置固定IP

    今天介绍如何在redhat/centos7系列机器上使用pipework为docker启动的容器指定一个固定ip,我们知道默认情况下,docker会使用 bridge网络模式为每一个启动的容器动态分配 ...

随机推荐

  1. JavaScript设计模式学习笔记

    1 JavaScript设计模式深入分析 私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量. 特权属性和方法:创建属 ...

  2. MySQL的左连接、右连接和全连接的实现

    表student:+----+-----------+------+| id | name | age |+----+-----------+------+| 1 | Jim | 18 || 2 | ...

  3. System Sounds: Alerts and Sound Effects

    #include <AudioToolbox/AudioToolbox.h> #include <CoreFoundation/CoreFoundation.h> // Def ...

  4. c语言结构体&常指针和常量指针的区别

    结构体: 关系密切但数据类型不尽相同, 常指针和常量指针的区别: char * const cp : 定义一个指向字符的指针常数,即const指针,常指针. const char* p : 定义一个指 ...

  5. (原创)项目部署-Tomcat设置默认访问项目及项目重复加载问题处理

    主要是通过配置<Tomcat安装目录>/conf/server.xml文件 步骤: 1.打开server.xml,在</Host>的上一行添加内容格式如下 <Contex ...

  6. 配置自己的OpenGL库,glew、freeglut库编译,库冲突解决(附OpenGL Demo程序)

    平台:Windows7,Visual C++ 2010 1. 引言 实验室的一个项目,用到OpenGL进行实时绘制,还用到一些其他的库,一个困扰我很久的问题就是编译时遇到的各种符号未定义,符号重定义之 ...

  7. 小米note3,华为手机,软键盘弹出之后,页面上定位的元素布局会乱掉

    原因:可能是因为,软键盘弹出时,改变了height,使height:100%,不能达到原来的高度. 解决办法: $(document).ready(function () { $('body').he ...

  8. JSon转化为DaTable

    /// <summary> /// 将json转换为DataTable /// </summary> /// <param name="strJson" ...

  9. IOS主要框架介绍(转)

    本文是<Sunvey the Major Framworks>一文的翻译 框架是一个目录,这个目录包含了共享库,访问共享库里代码的头文件,和其它的图片和声音的资源文件.一个共享库定义的方法 ...

  10. commons-httpclient中的超时设置

    connectionTimeout与soTimeout的差异,前者指创建一个有效的客户端到服务端链接的最大允许时间,后者指socket接收data的时间. connectionManager.getP ...