目标
本博客已经为大家推出了关于Docker的系列内容,相信各位已经对容器产生了浓厚的兴趣,但是如果你深入进来可能会发现,容器与虚拟机的差别还是比较大,特别是在网络方面,还需要很多完善,当然,随着docker 1.11版本的推出,容器的网络技术越来越完善,接下来,我们就给各位介绍几个我们平常经常会碰到的一些需求。
--------------------------------------------------------------------------------------
Blog: http://blog.csdn.net/chinagissoft
QQ群:16403743
宗旨:专注于"GIS+"前沿技术的研究与交流,将云计算技术、大数据技术、容器技术、物联网与GIS进行深度融合,探讨"GIS+"技术和行业解决方案
转载说明:文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
--------------------------------------------------------------------------------------
例如
宿主机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
root@controller:~# docker run -d --name test1 --net=none ubuntu:14.04 /bin/bash
ef8a344fd5f99f1711b9e0f1b3c7303d91cb750747ad723d1e3838983b352304
root@controller:~# docker run -d --name test2 --net=none ubuntu:14.04 /bin/bash
ef5179fe1058cb71aa710642c9b6cb3417213e194e5c8d76ba0def28077ce267
2、下载pipework
git clone https://github.com/jpetazzo/pipework
cp pipework/pipework /usr/local/bin/
chmod +x /usr/local/bin/pipework
root@controller:~# pipework br0 test1 192.168.14.243/24@192.168.14.254
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是否已经设置
root@controller:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4940085f9358 ubuntu:14.04 "/bin/bash" 48 seconds ago Up 48 seconds test2
19da8f983a5c ubuntu:14.04 "/bin/bash" 54 seconds ago Up 54 seconds test1
root@controller:~# docker exec -it 4940085f9358 /bin/bash
root@4940085f9358:/# 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
9: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 76:b0:22:b6:3b:b6 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.244/24 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::74b0:22ff:feb6:3bb6/64 scope link
valid_lft forever preferred_lft forever
然后再test2容器里面,ping test1和网关测试
root@4940085f9358:/# ping 192.168.14.243
PING 192.168.14.243 (192.168.14.243) 56(84) bytes of data.
64 bytes from 192.168.14.243: icmp_seq=1 ttl=64 time=0.087 ms
64 bytes from 192.168.14.243: icmp_seq=2 ttl=64 time=0.128 ms
^C
--- 192.168.14.243 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.087/0.107/0.128/0.022 ms
root@4940085f9358:/# ping 192.168.14.254
PING 192.168.14.254 (192.168.14.254) 56(84) bytes of data.
From 192.168.14.244 icmp_seq=1 Destination Host Unreachable
From 192.168.14.244 icmp_seq=2 Destination Host Unreachable
From 192.168.14.244 icmp_seq=3 Destination Host Unreachable
From 192.168.14.244 icmp_seq=4 Destination Host Unreachable
From 192.168.14.244 icmp_seq=5 Destination Host Unreachable
From 192.168.14.244 icmp_seq=6 Destination Host Unreachable
^C
--- 192.168.14.254 ping statistics ---
9 packets transmitted, 0 received, +6 errors, 100% packet loss, time 7999ms
pipe 4
说明配置都没有问题
5、我们再看上图,目前c1和C2我们已经联通,而且都在14网段,那么现在宿主机还是ping不通容器实例,我们只需要将宿主机的eth0网卡添加到br0网桥即可
root@controller:~# brctl addif br0 eth0
root@controller:~# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c29d35afe no eth0
veth1pl1844
veth1pl1866
docker0 8000.0242e420d7c6 no
然后再进行相关测试
root@controller:~# ping 192.168.14.243
PING 192.168.14.243 (192.168.14.243) 56(84) bytes of data.
64 bytes from 192.168.14.243: icmp_seq=1 ttl=64 time=0.398 ms
64 bytes from 192.168.14.243: icmp_seq=2 ttl=64 time=0.831 ms
64 bytes from 192.168.14.243: icmp_seq=3 ttl=64 time=0.842 ms
64 bytes from 192.168.14.243: icmp_seq=4 ttl=64 time=0.844 ms
64 bytes from 192.168.14.243: icmp_seq=5 ttl=64 time=0.876 ms
^C
--- 192.168.14.243 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 0.398/0.758/0.876/0.181 ms
root@controller:~# ping 192.168.14.244
PING 192.168.14.244 (192.168.14.244) 56(84) bytes of data.
64 bytes from 192.168.14.244: icmp_seq=1 ttl=64 time=0.262 ms
64 bytes from 192.168.14.244: icmp_seq=2 ttl=64 time=1.00 ms
我们看到宿主机也可以ping通固定IP的容器实例,那么接下来在我的笔记本测试应该就很简单了,因为我的笔记本都是windows10,所以在cmd直接测试
C:\Users\Administrator>ping 192.168.14.244
正在 Ping 192.168.14.244 具有 32 字节的数据:
来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.14.244 的回复: 字节=32 时间<1ms TTL=64
192.168.14.244 的 Ping 统计信息:
数据包: 已发送 = 3,已接收 = 3,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
Control-C
^C
C:\Users\Administrator>ping 192.168.14.243
正在 Ping 192.168.14.243 具有 32 字节的数据:
来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.14.243 的回复: 字节=32 时间<1ms TTL=64
192.168.14.243 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
问题
pipework目前还有缺陷,就是容器重启后IP设置会自动消失,需要重新设置,后面我们再介绍其他更加有效的方法。
当然,关于容器的网络还有更多事情要做,例如如何实现跨宿主机所在的容器实例网络连接等,后面我们一块探讨该问题。