FW Docker为容器分配指定物理网段的静态IP
官方有关于网桥和IP配置的文档地址:https://docs.docker.com/articles/networking/
1、宿主机(系统采用ubuntu-14.04.1-server-amd64)的网络采用桥接模式(默认是DHCP模式,还有一种模式就是静态IP),网桥的网段与物理网段相同。目前的物理网段为192.168.5.1/24,网关是192.168.1.1,物理网卡设备为eth0
编辑配置文件/etc/network/interfaces,自定义网桥br0
root@ubuntu-docker:~# cat /etc/network/interfaces# This file describes the network interfaces available on your system# and how to activate them. For more information, see interfaces(5).# The loopback network interfaceauto loiface lo inet loopback# The primary network interface#auto eth0#iface eth0 inet dhcp#auto br0iface br0 inet static address 192.168.5.116 netmask 255.255.255.0 gateway 192.168.5.1 bridge_ports eth0 bridge_stp off dns-nameservers 192.168.1.12 192.168.1.13root@ubuntu-docker:~# |
配置保存退出后,重启网络
root@ubuntu-docker:~# ifdown -a && ifup -a |
配置完成后用ifconfig可以看到br0和eth0的状态信息如下(宿主机的ip地址为192.168.5.116):
br0 Link encap:Ethernet HWaddr 00:0c:29:dc:47:11 inet addr:192.168.5.116 Bcast:192.168.5.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fedc:4711/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:737 errors:0 dropped:0 overruns:0 frame:0 TX packets:226 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:70000 (70.0 KB) TX bytes:26394 (26.3 KB)eth0 Link encap:Ethernet HWaddr 00:0c:29:dc:47:11 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:70065 errors:0 dropped:151 overruns:0 frame:0 TX packets:19621 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:23933126 (23.9 MB) TX bytes:2321651 (2.3 MB) |
2、网桥配置好后,剩下的就是docker相关的网络配置了。
a)容器启动的网络模式必须为none,用–net=none指定,比如
docker run -it --rm --net=none eeed74b237f9 /bin/bash |
b)获取目标容器的id,我的是dfe83012cda2
root@ubuntu-docker:~# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdfe83012cda2 centos:centos6.6 /bin/bash About an hour ago Up 23 minutes testroot@ubuntu-docker:~# |
c)配置ip的步骤有点繁琐,我写了个脚本。然后给脚本传递相关的参数就可以设置ip了。比如为容器dfe83012cda2设置静态ip地址192.168.5.123,掩码255.255.255.0,网关192.168.5.1。有个问题就是当容器重启后,设定的ip会丢失,此时需要重新执行该脚本一次。
root@ubuntu-docker:~# sh manual_con_static_ip.sh dfe83012cda2 192.168.5.123 24 192.168.5.1 |
脚本的内容如下(参考官方文档编写)
#/bin/bashif [ -z $1 ] || [ -z $2 ] || [ -z $3 ] || [ -z $4 ];then echo "*****Input the necessary parameters: CONTAINERID IP MASK GATEWAY" echo "*****Call the script like: sh manual_con_static_ip.sh b0e18b6a4432 192.168.5.123 24 192.168.5.1" exitfiCONTAINERID=$1SETIP=$2SETMASK=$3GATEWAY=$4pid=`docker inspect -f '{{.State.Pid}}' $CONTAINERID`mkdir -p /var/run/netnsfind -L /var/run/netns -type l -deleteln -s /proc/$pid/ns/net /var/run/netns/$pidip link add A type veth peer name Bbrctl addif br0 Aip link set A upip link set B netns $pidip netns exec $pid ip link set dev B name eth0ip netns exec $pid ip link set eth0 upip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0ip netns exec $pid ip route add default via $GATEWAY |
脚本包含的信息量较大,下面分行解有关语句的作用:
pid=`docker inspect -f '{{.State.Pid}}' $CONTAINERID` |
为了操作容器需要获取容器的进程号PID,docker inspect 可以查看容器的底层信息,查看容器dfe83012cda2所有的底层相关信息,用docker inspect dfe83012cda2就可以查看。-f参数可以格式化输出给定的信息,比如查看容器的状态
root@ubuntu-docker:~# docker inspect -f '{{.State.Running}}' dfe83012cda2trueroot@ubuntu-docker:~# |
为容器创建net命名空间,建立点对点连接(容器命名空间网卡和宿主上生成的网卡点对点),确保存放net命名空间的目录/var/run/netns存在,然后删除该目录失效的链接,再将容器的net命名空间文件软链接到/var/run/netns,以便执行ip netns能够读取。
mkdir -p /var/run/netnsfind -L /var/run/netns -type l -deleteln -s /proc/$pid/ns/net /var/run/netns/$pid |
在宿主上创建2张直连网卡(A与B直连),将B作为容器里的网卡,A作为宿主机的网卡。
ip link add A type veth peer name B |
将网卡A桥接到br0上,并启动网卡A
brctl addif br0 Aip link set A up |
将网卡B加入到相应的容器net命名空间,当网卡B加入到容器的net命名空间后,宿主机将无法查看到该网卡信息(执行ip netns时默认读取的目录是/var/run/netns)
ip link set B netns $pid |
ip netns exec能进入容器的net命名空间,可以用来配置容器net命名空间的网络参数,配置容器内的网卡B
ip netns exec $pid ip link set dev B name eth0ip netns exec $pid ip link set eth0 upip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0ip netns exec $pid ip route add default via $GATEWAY |
接下来先了解下docker为容器创建网络的过程《http://dockerpool.com/static/books/docker_practice/underly/network.html》,就会明白为什么要这么配置了。
1)创建一对虚拟接口,分别放到本地主机和新容器中;
2)本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
3)容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的名字空间可见;
4)从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。
当我们使用–net=none参数启动容器后,docker不对容器进行网络配置。如果需要容器网络可用需要我们按照相同的步骤配置容器的网络。
脚本还有一个BUG,就是当有多个容器需要配置网卡的时候,脚本中的网卡A和网卡B的命名会造成冲突,不过解决还是很简单的,嘿嘿。
后来把脚本优化了下,可能使用起来更合理:
#/bin/bashif [ -z $1 ] || [ -z $2 ] || [ -z $3 ] || [ -z $4 ] || [ -z $5 ];then echo "*****Input the necessary parameters: CONTAINERID IP MASK GATEWAY ETHNAME" echo "*****Call the script like: sh manual_con_static_ip.sh b0e18b6a4432 192.168.5.123 24 192.168.5.1 deth0" exitfi CONTAINERID=$1SETIP=$2SETMASK=$3GATEWAY=$4ETHNAME=$5#判断宿主机网卡是否存在ifconfig $ETHNAME > /dev/null 2>&1if [ $? -eq 0 ]; then read -p "$ETHNAME exist,do you want delelte it? y/n " del if [[ $del == 'y' ]]; then ip link del $ETHNAME else exit fifi#pid=`docker inspect -f '{{.State.Pid}}' $CONTAINERID`mkdir -p /var/run/netnsfind -L /var/run/netns -type l -deleteif [ -f /var/run/netns/$pid ]; then rm -f /var/run/netns/$pidfiln -s /proc/$pid/ns/net /var/run/netns/$pid#ip link add $ETHNAME type veth peer name Bbrctl addif br3 $ETHNAMEip link set $ETHNAME upip link set B netns $pid#先删除容器内已存在的eth0ip netns exec $pid ip link del eth0 > /dev/null 2>&1#设置容器新的网卡eth0ip netns exec $pid ip link set dev B name eth0ip netns exec $pid ip link set eth0 upip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0ip netns exec $pid ip route add default via $GATEWAY |
文章出处:http://www.xiaomastack.com/2015/02/06/docker-static-ip/
6 Comments
Add your comment
- Cenwen139 2015/08/26 at 19:51
小马哥,我使用您的脚步配置了容器内的网络后容器内部已经能看到配置的ip网关子网掩码了可以ping 通宿主和容器自己的ip。但是ping其他物理机的ip还是ping不通
FW Docker为容器分配指定物理网段的静态IP的更多相关文章
- (转帖) 为Docker容器指定自定义网段的固定IP/静态IP地址
作者:雨水,日期:2016-04-09 CSDN博客: http://blog.csdn.net/gobitan 摘要:Docker容器运行的时候默认会自动分配一个默认网桥所在网段的IP地址.但很多 ...
- docker 创建容器时指定容器ip
Docker创建容器时默认采用bridge网络,自行分配ip,不允许自己指定. 在实际部署中,我们需要指定容器ip,不允许其自行分配ip,尤其是搭建集群时,固定ip是必须的. 我们可以创建自己的bri ...
- 为Docker容器指定自定义网段的固定IP/静态IP地址
第一步:创建自定义网络 备注:这里选取了172.172.0.0网段,也可以指定其他任意空闲的网段 docker network create --subnet=172.172.0.0/16 docke ...
- docker 运行容器时指定--sysctl参数来设置系统参数
指定--sysctl参数来设置系统参数,通过这些参数来调整系统性能,Docker通过一个 ValidateSysctl函数来限制 sysctl参数可以传入的项,源码如下: // docker/opts ...
- Docker 添加容器SSH服务
很多时候我们需要登陆到容器内部操作,此时我们就需要开启容器的SSH支持了,下面的小例子将具体介绍三种分配IP地址的方法,分别是pipworl分配,commit分配,Docker分配等. 基于commi ...
- 为Docker容器设置静态IP
此文已由作者袁欢授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 创建docker容器 docker run -it --name=yh -h yh --net=none de ...
- docker容器分配静态IP
最近因为工作要求需要用学习使用docker,最后卡在了网络配置这一块.默认情况下启动容器的时候,docker容器使用的是bridge策略比如: docker run -ti ubuntu:latest ...
- docker 现实---联网多台物理主机,容器桥到物理网络(三)
docker 默认桥接卡docker0 只有当这个单元中的所有容器桥接卡.例如,在主机虚拟网络适配器容器看通常称为veth*** 和docker只要把这些卡桥接在一起,例如下面的附图: waterm ...
- docker应用-5(使用overlay 网络进行容器间跨物理主机通信)
同一个主机上的Docker容器之间通信 docker 引擎会在主机上增加一个docker0网卡,该网卡具有双重身份: 1.从容器视角,网桥(交换机)身份docker0 对于运行在同一个主机上的各个容器 ...
随机推荐
- jmeter也有loadrunner一样的图像
一.准备工具 1.JMeterPlugins-Standard-1.4.0.zip下载地址: http://yunpan.cn/c6Dk9tDdj8Lvq 访问密码 4538 2.ServerAge ...
- 简单几何(直线求交点) POJ 2074 Line of Sight
题目传送门 题意:从一条马路(线段)看对面的房子(线段),问连续的能看到房子全部的最长区间 分析:自己的思路WA了:先对障碍物根据坐标排序,然后在相邻的障碍物的间隔找到区间,这样还要判断是否被其他障碍 ...
- LightOJ1201 A Perfect Murder(树形DP)
一道经典的树型DP入门题.dp[u][0/1]表示u点不选或选时以u为根的子树最多能选择的点数. 题目给的有向有环图可以看作森林,注意不是树,因为题目没有说图是连通的! #include<cst ...
- C#的async和await
C# 5.0中引入了async 和 await.这两个关键字可以让你更方便的写出异步代码. 看个例子: public class MyClass { public MyClass() { Displa ...
- asp.net 微信企业号办公系统-表单及流程设计配置实例
在环境搭建好之后,我们就来学习一下怎样快速创建一个流程,并执行和流转该流程(我们这里讲的只是入门,不涉及到具体流程参数设置). 创建一个流程步骤为:在数据库在创建表-->设计表单-->设置 ...
- 使用Spring的注解方式实现AOP
Spring对AOP的实现提供了很好的支持.下面我们就使用Spring的注解来完成AOP做一个例子. 首先,为了使用Spring的AOP注解功能,必须导入如下几个包.aspectjrt.jar,asp ...
- Java导出Highcharts生成的图表为图片源码
本文转载自:http://blog.csdn.net/dengsilinming/article/details/7352054 需要的jar包: 需要的js文件:(可以通过http://www.hi ...
- [zt]不到最后一秒你永远不知道结局且震撼你心灵的高端电影
总有一部电影,让你憋着尿直到看完~~~ http://share.renren.com/share/230538513/17679574169?from=0101090202&shfrom=0 ...
- Css3 - 动画旋转
旋转1: <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="U ...
- java工程包的命名(-dev.jar,-javadoc.jar,jar)
1.-javadoc.jar 这个应该是一个doc包,就是API,相当于帮助文档,用来说明类.方法.静态变量 都是干什么的. 2.-dev.jar,.jar都有可能包含源码,也可能都不包含