Docker为容器分配指定物理网段的静态IP

转载 2015年07月06日 16:24:42

Docker为容器分配指定物理网段的静态IP

小马 2015-02-06 85 阅读

官方有关于网桥和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 interface
auto lo
iface lo inet loopback

# The primary network interface
#auto eth0
#iface eth0 inet dhcp
#
auto br0
iface 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.13
root@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 -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
dfe83012cda2        centos:centos6.6    /bin/bash           About an hour ago   Up 23 minutes                           test
root@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/bash
if [ -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"
        exit
fi

CONTAINERID=$1
SETIP=$2
SETMASK=$3
GATEWAY=$4

pid=`docker inspect -f '{{.State.Pid}}' $CONTAINERID`
mkdir -p /var/run/netns
find -L /var/run/netns -type l -delete
ln -s /proc/$pid/ns/net /var/run/netns/$pid
ip link add A type veth peer name B
brctl addif br0 A
ip link set A up
ip link set B netns $pid
ip netns exec $pid ip link set dev B name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0
ip 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}}' dfe83012cda2
true
root@ubuntu-docker:~#

为容器创建net命名空间,建立点对点连接(容器命名空间网卡和宿主上生成的网卡点对点),确保存放net命名空间的目录/var/run/netns存在,然后删除该目录失效的链接,再将容器的net命名空间文件软链接到/var/run/netns,以便执行ip netns能够读取。

mkdir -p /var/run/netns
find -L /var/run/netns -type l -delete
ln -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 A
ip 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 eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0
ip 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的命名会造成冲突,不过解决还是很简单的,嘿嘿。

上述方式有一个更简单的开源shell 可以直接使用https://github.com/jpetazzo/pipework
文章出处:http://www.xiaomastack.com/2015/02/06/docker-static-ip/


docker 指定IP地址、与主机同网段IP

首先讲一下docker的网络模式: 我们使用docker run创建容器时,可以使用--net选项指定容器的网络模式,docker一共有4中网络模式: 1:bridge模式,--net=bridg...

分布式进阶(十二)Docker固定Container IP

使用pipework工具。 前提:每个Container所做的工作现在还很少,可以不用save、commit。 为了便于通信,自定义一个网桥(192.168.1.180/24),使之IP与宿主主机IP...

为Docker容器指定自定义网段的固定IP/静态IP地址

为Docker容器指定自定义网段的固定IP/静态IP地址 作者:雨水,日期:2016-04-09  CSDN博客: http://blog.csdn.net/gobitan 摘要:Docker...
  • gobitan
  • gobitan
  • 2016年04月09日 12:17
  • 18135

docker学习笔记---给容器分配局域网IP

给容器分配公网IP 准备工作: 1 方便获取容器的ip 和pid的几个脚本:docker-pi    docker-pid docker-ip #!/bin/sh   exec docker in...
  • rually
  • rually
  • 2016年07月15日 17:55
  • 4118

Docker网络设置

Docker容器互联的几个基本方法(1)容器挂载主机目录:-v –volumns-from(2)容器之间互联: –link(3)外部访问容器:-p(4)直接使用宿主机网络 docker run...

(OK) Docker中使用固定IP——docker run -i -t --rm --net='none'

Docker中使用固定IP 2014-12-11 默认情况下启动一个container,其会自动获取一个跟docker0同网段的IP,而且重启container其IP一般会发生变化,但有时候我...
  • ztguang
  • ztguang
  • 2016年05月13日 20:47
  • 2172

Docker 使用物理网络IP地址 及四种网络模式

一、编辑网卡配置文件,桥接网卡 生成br0网卡配置文件 cd /etc/sysconfig/network-scripts/ cp ifcfg-eth0 ifcfg-eth0.bak cp ifcf...
  • fgf00
  • fgf00
  • 2016年09月18日 16:25
  • 5775

docker中创建虚拟网卡

docker本身对于host来说就是一个虚拟化的东西,要在其中创建一个虚拟网卡,还真要花费点心思。下面为大家分享一下配置虚拟网卡的方法。 如果在旧版本的docker中,我所发现的目前就一种方法:就是在...

Docker容器通过独立IP暴露给局域网的方法

Docker容器非常轻量,系统开销非常少,比VMware或者VirtualBox用起来方便,部署起来也非常容易。官方推荐我们通过端口映射的方式把Docker容器的服务提供给宿主机或者局域网其他容器使用...

Centos 6 Docker配置桥接网络

为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docke...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Docker为容器分配指定物理网段的静态IP
举报原因:
原因补充:

(最多只允许输入30个字)