上面我们使用的是系统默认的网桥接口docker0,其默认的IP地址为172.17.0.XXX,我们可以自定义桥接口并且制定静态的IP地址。
首先,service
stop docker服务,添加我们自己的桥接口,这是使用到了brctl命令,如果没有安装可以使用下面的命令进行安装:yum install bridge-utils,
先删除docker0,这里删不删都一样,因为在重新启动后还是会创建docker0接口,
ifconfig
docker0 down
brctl
delbr docker0
添加自定义的桥接口bridge0
brctl addbr bridge0
ifcofnig bridge0 up
ip addr add 192.168.1.1/24 dev bridge0
然后在docker的配置文件中添加docker启动时的选项-b=bridge0,对于centos,其docker的配置文件在/etc/sysconfig/docker,网上的方案都是直接使用echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/sysconfig/docker,但是我在试验时,该方案确实失效的,我的docker的版本信息如下:
[root@centos ~]# docker --version
Docker version 1.3.2, build 39fa2fa/1.3.2
这时使用service docker restart进行重启后,并没有生效,使用的默认桥接口还是docker0,通过下面的命令可以看到其中的启动信息,
systemctl status docker.service
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled)
Active: active (running) since Tue 2015-05-26 18:37:18 CST; 35s ago
Docs:
Main PID: 2676 (docker)
CGroup: /system.slice/docker.service
└─2676 /usr/bin/docker -d --selinux-enabled -H fd://
从上面的启动信息可以看出在启动docker时并没有添加-d的选项信息,也就是在/etc/sysconfig/docker文件中添加DOCKER_OPTS=”-b=bridge0”信息并没有生效,从上面的信息中可以看懂docker启动时读取的是OPTIONS=--selinux-enabled –H 选项信息,在OPTIONS选项的后面添加-b=bridge0选项后,重新启动docker,通过查看启动信息,在启动的docker时添加了 –b选项信息,
[root@10-10-63-106 ~]# systemctl status docker.service
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled)
Active: active (running) since Tue 2015-05-26 18:38:54 CST; 42min ago
Docs:
Main PID: 2777 (docker)
CGroup: /system.slice/docker.service
└─2777 /usr/bin/docker -d --selinux-enabled -H fd:// -b=bridge0
May 26 18:38:58 10-10-63-106 docker[2777]: [c73bb08c] +job resize(1470c13c7a9c04eb8fc1b895329f226e515049b7861c8a54c6175df2ad...1, 134)
这时运行一个container可以看到分配的IP地址与启动docker时指定的桥接口保持一个网段。
root@centos ~]# docker run -i -t centos6.3-base-v2 /bin/bash
[root@19d4ed8ed680 /]# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:01:03
inet addr:192.168.1.3 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:c0ff:fea8:103/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:508 (508.0 b) TX bytes:508 (508.0 b)
也可以通过下面的方式启动docker,/usr/bin/docker -d -b=br0,这样启动的docker也指定了桥接口。
通过brctl show可以看到桥下面的接口情况
[root@centos ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.8a668bde14c6 no vethadb9a97
通过Iptables我们可以看到下面的一些转发的规则
root@10-10-63-106 ~]# iptables-save
# Generated by iptables-save v1.4.21 on Thu Jul 2 09:32:46 2015
*nat
:PREROUTING ACCEPT [412541:23651952]
:INPUT ACCEPT [412534:23651412]
:OUTPUT ACCEPT [44:3535]
:POSTROUTING ACCEPT [45:3619]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 192.168.2.0/24 ! -o br0 -j MASQUERADE
-A POSTROUTING -s 192.168.1.0/24 ! -o bridge0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
重点关注上面标红的那条NAT规则,这条规则的意思是对源IP是 192.168.2.0/24网段数据包,并且不是从br0接口发送出去的,对其作源NAT规则,也就是从Container发出来的数据包,对其源地址进行修改,源地址修改为本地接口eth0的IP地址,其中MASQUERADE表示直接从宿主机的eth0上选取IP地址,作为源IP地址。
下面是在接口eth0上抓取的数据包,在eth0上的抓包可以看到已经做了SNAT,
下面是在宿主机上的br0接口抓取的数据包
参考文献:
http://blog.csdn.net/wsscy2004/article/details/25887785