为Docker容器设置固定IP实现网络联通

目标

本博客已经为大家推出了关于Docker的系列内容,相信各位已经对容器产生了浓厚的兴趣,但是如果你深入进来可能会发现,容器与虚拟机的差别还是比较大,特别是在网络方面,还需要很多完善,当然,随着docker 1.11版本的推出,容器的网络技术越来越完善,接下来,我们就给各位介绍几个我们平常经常会碰到的一些需求。

1、通过Pipework为Docker容器设置

例如

宿主机A 和宿主机B是网络联通关系,在宿主机A上面创建了多个容器组成集群,但是我希望通过宿主机B也可以访问到宿主机A的容器,当然,你也可能会说,端口映射非常方便,如果我需要的端口比较多,或者着如果我临时需要增加某些端口,可能设置起来比较麻烦,那么如果我们将宿主机A里面的容器的IP与宿主机的IP在同一个网络,不就可以直接来进行互联互通了么。


步骤

其实这些需求在以前可能需要比较多繁杂的步骤,对于我们非网络出身的用户来说比较麻烦,但是docker原厂工程师在github上推出了pipework工具,这个工具可以使用一条命令就可以实现更改容器的IP,更准确来说为容器IP添加一个新的网卡,这岂不是非常好的事情,感谢开源!


原理


环境:(图上的右边IP 应该是192.168.14.117,不改了

VMWare Workstation 12

Ubuntu14.04   

Docker1.10


容器虚拟机有两个网卡,eth0和eth1,eth1作为管理口 192.168.14.223,我的笔记本IP相当于与虚拟机一个网络的另一个机器,IP为192.168.14.117,我的目标就是通过我的笔记本访问到容器虚拟机的容器实例。


1、在容器虚拟机里面创建两个容器实例

这里,我并不需要默认docker0网桥分配的172.17.0.1网段,所以我设置--net=none

[html]  view plain  copy
  1. root@controller:~# docker run -d --name test1 --net=none ubuntu:14.04 /bin/bash  
  2. ef8a344fd5f99f1711b9e0f1b3c7303d91cb750747ad723d1e3838983b352304  
  3. root@controller:~# docker run -d --name test2 --net=none ubuntu:14.04 /bin/bash  
  4. ef5179fe1058cb71aa710642c9b6cb3417213e194e5c8d76ba0def28077ce267  

2、下载pipework

[html]  view plain  copy
  1. git clone https://github.com/jpetazzo/pipework  
  2. cp pipework/pipework /usr/local/bin/  
  3. chmod +x /usr/local/bin/pipework  


3、接下来,通过pipework命令直接为容器设置固定IP
[html]  view plain  copy
  1. root@controller:~# pipework br0 test1 192.168.14.243/24@192.168.14.254  
  2. root@controller:~# pipework br0 test2 192.168.14.244/24@192.168.14.254  
pipework包含了200多行的shell脚本,通过network namespace,veth pair以及linux bridge完成容器网络的设置,执行过程大概包括:

  • 查看主机是否包含br0(可以自定义)网桥,如果不存在就创建
  • 向容器实例test1添加一块网卡(可以设置网卡名),并配置固定IP:192.168.14.243   
  • 若test1已经有默认的路由,则删除掉,将@后面的192.168.14.254设置为默认路由的网关
  • 将test1容器实例连接到创建的br0上

4、我们进入test2容器,查看IP是否已经设置

[html]  view plain  copy
  1. root@controller:~# docker ps -a  
  2. CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES  
  3. 4940085f9358        ubuntu:14.04        "/bin/bash"         48 seconds ago      Up 48 seconds                           test2  
  4. 19da8f983a5c        ubuntu:14.04        "/bin/bash"         54 seconds ago      Up 54 seconds                           test1  
  5. root@controller:~# docker exec -it 4940085f9358 /bin/bash  
  6. root@4940085f9358:/# ip a  
  7. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default  
  8.     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
  9.     inet 127.0.0.1/8 scope host lo  
  10.        valid_lft forever preferred_lft forever  
  11.     inet6 ::1/128 scope host  
  12.        valid_lft forever preferred_lft forever  
  13. 9: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000  
  14.     link/ether 76:b0:22:b6:3b:b6 brd ff:ff:ff:ff:ff:ff  
  15.     inet 192.168.14.244/24 scope global eth1  
  16.        valid_lft forever preferred_lft forever  
  17.     inet6 fe80::74b0:22ff:feb6:3bb6/64 scope link  
  18.        valid_lft forever preferred_lft forever  

然后再test2容器里面,ping test1和网关测试

[html]  view plain  copy
  1. root@4940085f9358:/# ping 192.168.14.243  
  2. PING 192.168.14.243 (192.168.14.243) 56(84) bytes of data.  
  3. 64 bytes from 192.168.14.243: icmp_seq=1 ttl=64 time=0.087 ms  
  4. 64 bytes from 192.168.14.243: icmp_seq=2 ttl=64 time=0.128 ms  
  5. ^C  
  6. --- 192.168.14.243 ping statistics ---  
  7. 2 packets transmitted, 2 received, 0% packet loss, time 999ms  
  8. rtt min/avg/max/mdev = 0.087/0.107/0.128/0.022 ms  
  9. root@4940085f9358:/# ping 192.168.14.254  
  10. PING 192.168.14.254 (192.168.14.254) 56(84) bytes of data.  
  11. From 192.168.14.244 icmp_seq=1 Destination Host Unreachable  
  12. From 192.168.14.244 icmp_seq=2 Destination Host Unreachable  
  13. From 192.168.14.244 icmp_seq=3 Destination Host Unreachable  
  14. From 192.168.14.244 icmp_seq=4 Destination Host Unreachable  
  15. From 192.168.14.244 icmp_seq=5 Destination Host Unreachable  
  16. From 192.168.14.244 icmp_seq=6 Destination Host Unreachable  
  17. ^C  
  18. --- 192.168.14.254 ping statistics ---  
  19. 9 packets transmitted, 0 received, +6 errors, 100% packet loss, time 7999ms  
  20. pipe 4  

说明配置都没有问题


5、我们再看上图,目前c1和C2我们已经联通,而且都在14网段,那么现在宿主机还是ping不通容器实例,我们只需要将宿主机的eth0网卡添加到br0网桥即可

[html]  view plain  copy
  1. root@controller:~# brctl addif br0 eth0  
[html]  view plain  copy
  1. root@controller:~# brctl show  
  2. bridge name     bridge id               STP enabled     interfaces  
  3. br0             8000.000c29d35afe       no              eth0  
  4.                                                         veth1pl1844  
  5.                                                         veth1pl1866  
  6. docker0         8000.0242e420d7c6       no  
然后再进行相关测试

[html]  view plain  copy
  1. root@controller:~# ping 192.168.14.243  
  2. PING 192.168.14.243 (192.168.14.243) 56(84) bytes of data.  
  3. 64 bytes from 192.168.14.243: icmp_seq=1 ttl=64 time=0.398 ms  
  4. 64 bytes from 192.168.14.243: icmp_seq=2 ttl=64 time=0.831 ms  
  5. 64 bytes from 192.168.14.243: icmp_seq=3 ttl=64 time=0.842 ms  
  6. 64 bytes from 192.168.14.243: icmp_seq=4 ttl=64 time=0.844 ms  
  7. 64 bytes from 192.168.14.243: icmp_seq=5 ttl=64 time=0.876 ms  
  8. ^C  
  9. --- 192.168.14.243 ping statistics ---  
  10. 5 packets transmitted, 5 received, 0% packet loss, time 4005ms  
  11. rtt min/avg/max/mdev = 0.398/0.758/0.876/0.181 ms  
  12. root@controller:~# ping 192.168.14.244  
  13. PING 192.168.14.244 (192.168.14.244) 56(84) bytes of data.  
  14. 64 bytes from 192.168.14.244: icmp_seq=1 ttl=64 time=0.262 ms  
  15. 64 bytes from 192.168.14.244: icmp_seq=2 ttl=64 time=1.00 ms  

我们看到宿主机也可以ping通固定IP的容器实例,那么接下来在我的笔记本测试应该就很简单了,因为我的笔记本都是windows10,所以在cmd直接测试
[html]  view plain  copy
  1. C:\Users\Administrator>ping 192.168.14.244  
  2.   
  3. 正在 Ping 192.168.14.244 具有 32 字节的数据:  
  4. 来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64  
  5. 来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64  
  6. 来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64  
  7.   
  8. 192.168.14.244 的 Ping 统计信息:  
  9.     数据包: 已发送 = 3,已接收 = 3,丢失 = 0 (0% 丢失),  
  10. 往返行程的估计时间(以毫秒为单位):  
  11.     最短 = 0ms,最长 = 0ms,平均 = 0ms  
  12. Control-C  
  13. ^C  
  14. C:\Users\Administrator>ping 192.168.14.243  
  15.   
  16. 正在 Ping 192.168.14.243 具有 32 字节的数据:  
  17. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  18. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  19. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  20. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  21.   
  22. 192.168.14.243 的 Ping 统计信息:  
  23.     数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),  
  24. 往返行程的估计时间(以毫秒为单位):  
  25.     最短 = 0ms,最长 = 0ms,平均 = 0ms  

问题

pipework目前还有缺陷,就是容器重启后IP设置会自动消失,需要重新设置,后面我们再介绍其他更加有效的方法。


当然,关于容器的网络还有更多事情要做,例如如何实现跨宿主机所在的容器实例网络连接等,后面我们一块探讨该问题。

2、通过Python脚本实现并解决pipework缺陷

题记


前面已经提到通过使用pipework方式,为容器设置固定IP,但是该方法有一个问题就是如果我们的容器实例重启,设置的固定IP会丢失,这显然回事一件令人头疼的事情,如果我们重启后IP依然保持设置的,岂不是一件很好的事情,接下来我们就介绍一下如何完成这个需求。


通过这个图可以看到,与上一篇使用pipework架构基本类似,本次只是用了一个网卡,而且我只创建了一个容器实例C1,相关环境可以参考上一篇介绍。

1、为容器服务器设置br0网桥,该网桥写入到配置文件里面,dns-nameservers如果需求可以添加

[html]  view plain  copy
  1. root@controller:~# cat /etc/network/interfaces  
  2. # This file describes the network interfaces available on your system  
  3. # and how to activate them. For more information, see interfaces(5).  
  4.   
  5. # The loopback network interface  
  6. auto lo  
  7. iface lo inet loopback  
  8.   
  9. # The primary network interface  
  10. #auto eth0  
  11. #iface eth0 inet static  
  12. #       address 10.0.0.11  
  13. #       netmask 255.255.255.0  
  14. auto br0  
  15. iface br0 inet static  
  16. address 192.168.14.225  
  17. netmask 255.255.255.0  
  18. gateway 192.168.14.254  
  19. bridge_ports eth0  
  20. bridge_stp off  

2、安装相应的包文件

[html]  view plain  copy
  1. #安装pip  
  2. apt-get install python-pip python-dev build-essential  
  3.    
  4. #安装docker python的api  
  5. pip install docker-py   

3、启动一个容器实例

[html]  view plain  copy
  1. root@controller:~# docker ps -a  
  2. CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES  
  3. root@controller:~# docker run -i -t --name test1 --net=none ubuntu:14.04 /bin/bash  
  4. root@443b6fa7416a:/#  
  5. root@443b6fa7416a:/# ip a  
  6. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default  
  7.     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
  8.     inet 127.0.0.1/8 scope host lo  
  9.        valid_lft forever preferred_lft forever  
  10.     inet6 ::1/128 scope host  
  11.        valid_lft forever preferred_lft forever  

4、下载相关文件docker-static-ip-master.zip
解压之后,进入该文件夹,该文件夹其实就是通过python脚本实现了设置固定IP的步骤。

我们需要修改相关的配置文件,添加需要设置的容器实例信息

[html]  view plain  copy
  1. root@controller:~# cd docker-static-ip-master/  
  2. root@controller:~/docker-static-ip-master# ls  
  3. containers.cfg  duration.py  README.md  
  4. root@controller:~/docker-static-ip-master# cat containers.cfg  
  5. #<container-id>,<bridge-name>,<ipaddress/netmask>,<gateway>  
  6. root@controller:~/docker-static-ip-master# docker ps -a  
  7. CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES  
  8. 443b6fa7416a        ubuntu:14.04        "/bin/bash"         3 minutes ago       Exited (0) 3 minutes ago                       test1  
  9. root@controller:~/docker-static-ip-master#  
  10. root@controller:~/docker-static-ip-master# echo "443b6fa7416a,br0,192.168.14.243/24,192.168.14.254" >> containers.cfg  
  11. root@controller:~/docker-static-ip-master# python duration.py  

5、查看信息(在容器实例)

[html]  view plain  copy
  1. root@443b6fa7416a:/# ip a  
  2. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default  
  3.     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
  4.     inet 127.0.0.1/8 scope host lo  
  5.        valid_lft forever preferred_lft forever  
  6.     inet6 ::1/128 scope host  
  7.        valid_lft forever preferred_lft forever  
  8. 7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000  
  9.     link/ether 3a:9d:3b:13:89:db brd ff:ff:ff:ff:ff:ff  
  10.     inet 192.168.14.243/24 scope global eth0  
  11.        valid_lft forever preferred_lft forever  
  12.     inet6 fe80::389d:3bff:fe13:89db/64 scope link  
  13.        valid_lft forever preferred_lft forever  

在容器实例测试连接

[html]  view plain  copy
  1. root@443b6fa7416a:/# ping 192.168.14.254  
  2. PING 192.168.14.254 (192.168.14.254) 56(84) bytes of data.  
  3. 64 bytes from 192.168.14.254: icmp_seq=1 ttl=255 time=22.5 ms  
  4. 64 bytes from 192.168.14.254: icmp_seq=2 ttl=254 time=2.00 ms  
  5. ^C  
  6. --- 192.168.14.254 ping statistics ---  
  7. 2 packets transmitted, 2 received, 0% packet loss, time 1002ms  
  8. rtt min/avg/max/mdev = 2.005/12.282/22.559/10.277 ms  
  9. root@443b6fa7416a:/# ping 192.168.14.225  
  10. PING 192.168.14.225 (192.168.14.225) 56(84) bytes of data.  
  11. 64 bytes from 192.168.14.225: icmp_seq=1 ttl=64 time=0.127 ms  
  12. 64 bytes from 192.168.14.225: icmp_seq=2 ttl=64 time=0.104 ms  
  13. ^C  
  14. --- 192.168.14.225 ping statistics ---  
  15. 2 packets transmitted, 2 received, 0% packet loss, time 999ms  
  16. rtt min/avg/max/mdev = 0.104/0.115/0.127/0.015 ms  

在宿主机查看信息

[html]  view plain  copy
  1. root@controller:~# ifconfig br0  
  2. br0       Link encap:Ethernet  HWaddr 00:0c:29:d3:5a:fe  
  3.           inet addr:192.168.14.225  Bcast:192.168.14.255  Mask:255.255.255.0  
  4.           inet6 addr: fe80::20c:29ff:fed3:5afe/64 Scope:Link  
  5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  6.           RX packets:7139 errors:0 dropped:0 overruns:0 frame:0  
  7.           TX packets:976 errors:0 dropped:0 overruns:0 carrier:0  
  8.           collisions:0 txqueuelen:0  
  9.           RX bytes:552522 (552.5 KB)  TX bytes:123821 (123.8 KB)  
  10.   
  11. root@controller:~# brctl show  
  12. bridge name     bridge id               STP enabled     interfaces  
  13. br0             8000.000c29d35afe       no              eth0  
  14.                                                         tap1923  
  15. docker0         8000.02427810a053       no  
  16. root@controller:~# ping 192.168.14.243  
  17. PING 192.168.14.243 (192.168.14.243) 56(84) bytes of data.  
  18. 64 bytes from 192.168.14.243: icmp_seq=1 ttl=64 time=0.033 ms  
  19. 64 bytes from 192.168.14.243: icmp_seq=2 ttl=64 time=0.065 ms  
  20. 64 bytes from 192.168.14.243: icmp_seq=3 ttl=64 time=0.100 ms  
  21. ^C  
  22. --- 192.168.14.243 ping statistics ---  
  23. 3 packets transmitted, 3 received, 0% packet loss, time 2000ms  
  24. rtt min/avg/max/mdev = 0.033/0.066/0.100/0.027 ms  

在我的笔记本测试连接
[html]  view plain  copy
  1. C:\Users\Administrator>ping 192.168.14.243  
  2.   
  3. 正在 Ping 192.168.14.243 具有 32 字节的数据:  
  4. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  5. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  6. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  7. 来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64  
  8.   
  9. 192.168.14.243 的 Ping 统计信息:  
  10.     数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),  
  11. 往返行程的估计时间(以毫秒为单位):  
  12.     最短 = 0ms,最长 = 0ms,平均 = 0ms  


6、重启容器实例,测试IP

[html]  view plain  copy
  1. root@443b6fa7416a:/# exitroot@controller:~#  
  2. root@controller:~# docker stop 443b6fa7416a  
  3. 443b6fa7416a  
  4. root@controller:~# docker start 443b6fa7416a  
  5. 443b6fa7416a  
  6. root@controller:~# docker exec -it 443b6fa7416a /bin/bash  
  7. root@443b6fa7416a:/# ifconfig  
  8. eth0      Link encap:Ethernet  HWaddr 4e:ef:ea:8d:0a:30  
  9.           inet addr:192.168.14.243  Bcast:0.0.0.0  Mask:255.255.255.0  
  10.           inet6 addr: fe80::4cef:eaff:fe8d:a30/64 Scope:Link  
  11.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  12.           RX packets:30 errors:0 dropped:0 overruns:0 frame:0  
  13.           TX packets:7 errors:0 dropped:0 overruns:0 carrier:0  
  14.           collisions:0 txqueuelen:1000  
  15.           RX bytes:2364 (2.3 KB)  TX bytes:578 (578.0 B)  
  16.   
  17. lo        Link encap:Local Loopback  
  18.           inet addr:127.0.0.1  Mask:255.0.0.0  
  19.           inet6 addr: ::1/128 Scope:Host  
  20.           UP LOOPBACK RUNNING  MTU:65536  Metric:1  
  21.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0  
  22.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0  
  23.           collisions:0 txqueuelen:0  
  24.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)  
  25.   
  26. root@443b6fa7416a:/# ping 192.168.14.225  
  27. PING 192.168.14.225 (192.168.14.225) 56(84) bytes of data.  
  28. 64 bytes from 192.168.14.225: icmp_seq=1 ttl=64 time=0.160 ms  
  29. 64 bytes from 192.168.14.225: icmp_seq=2 ttl=64 time=0.113 ms  
  30. 64 bytes from 192.168.14.225: icmp_seq=3 ttl=64 time=0.113 ms  
  31. ^C  
  32. --- 192.168.14.225 ping statistics ---  
  33. 3 packets transmitted, 3 received, 0% packet loss, time 1999ms  
  34. rtt min/avg/max/mdev = 0.113/0.128/0.160/0.025 ms  
  35. root@443b6fa7416a:/#  

3、如何节省IP资源防止主机网络广播风暴

题记

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

1、Docker容器占用大量的主机网络的IP地址资源

2、大量Docker容器可能引起广播风暴,导致主机所在网络性能下降

3、Docker容器连在主机的网络中可能引起安全问题

那么接下来,我们就以上面的问题,看看如何解决。


本博客就是用最简单的方法,如果你已经理解了上两个博客设置固定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重叠情况,带着这个问题,我们继续探求。


转自:http://blog.csdn.net/chinagissoft/article/details/51250839


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值