docker啓動時,會在宿主主機上建立一個名爲docker0的虛擬網絡接口,默認選擇172.17.42.1/16,一個16位的子網掩碼給容器提供了65534個IP地址。docker0只是一個在綁定到這上面的其餘網卡間自動轉發數據包的虛擬以太網橋,它可使容器和主機相互通訊,容器與容器間通訊。問題是,如何讓位於不一樣主機上的docker容器能夠通訊。如何有效配置docker網絡目前來講仍是一個較複雜的工做,於是也涌現了不少的開源項目來解決這個問題,如flannel、Kubernetes、weave、pipework等等。html
1. flannel 前端
CoreOS團隊出品,是一個基於etcd的覆蓋網絡(overlay network)併爲每臺主機提供一個獨立子網的服務。Rudder簡化了集羣中Docker容器的網絡配置,避免了多主機上容器子網衝突的問題,更能夠大幅度減小端口映射方面的工做。具體代碼見https://github.com/coreos/flannel,其工做原理爲:git
An overlay network is first configured with an IP range and the size of the subnet for each host. For example, one could configure the overlay to use 10.100.0.0/16 and each host to receive a /24 subnet. Host A could then receive 10.100.5.0/24 and host B could get 10.100.18.0/24. flannel uses etcd to maintain a mapping between allocated subnets and real host IP addresses. For the data path, flannel uses UDP to encapsulate IP datagrams to transmit them to the remote host. We chose UDP as the transport protocol for its ease of passing through firewalls. For example, AWS Classic cannot be configured to pass IPoIP or GRE traffic as its security groups only support TCP/UDP/ICMP.(摘自https://coreos.com/blog/introducing-rudder/)github
2. Kubernetesdocker
Kubernetes是由Google推出的針對容器管理和編排的開源項目,它讓用戶可以在跨容器主機集羣的狀況下輕鬆地管理、監測、控制容器化應用部署。Kubernete有一個特殊的與SDN很是類似的網絡化概念:經過一個服務代理建立一個能夠分配給任意數目容器的IP地址,前端的應用程序或使用該服務的用戶僅經過這一IP地址調用服務,不須要關心其餘的細節。這種代理方案有點SDN的味道,可是它並非構建在典型的SDN的第2-3層機制之上。安全
Kubernetes uses a proxying method, whereby a particular service — defined as a query across containers — gets its own IP address. Behind that address could be hordes of containers that all provide the same service — but on the front end, the application or user tapping that service just uses the one IP address.bash
This means the number of containers running a service can grow or shrink as necessary, and no customer or application tapping the service has to care. Imagine if that service were a mobile network back-end process, for instance; during traffic surges, more containers running the process could be added, and they could be deleted once traffic returned to normal. Discovery of the specific containers running the service is handled in the background, as is the load balancing among those containers. Without the proxying, you could add more containers, but you’d have to tell users and applications about it; Google’s method eliminates that need for configuration. (https://www.sdncentral.com/news/docker-kubernetes-containers-open-sdn-possibilities/2014/07/)網絡
3. 爲不一樣宿主機上全部容器配置相同網段的IP地址,配置方法見http://www.cnblogs.com/feisky/p/4063162.html,這篇文章是基於Linux bridge的,固然也能夠用其餘的方法,如用OpenvSwitch+GRE創建宿主機之間的鏈接:app
# From http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/ ide
4. 使用weave爲容器配置IP(使用方法見http://www.cnblogs.com/feisky/p/4093717.html),weave的特性包括
5. 修改主機docker默認的虛擬網段,而後在各自主機上分別把對方的docker網段加入到路由表中,配合iptables便可實現docker容器誇主機通訊。配置方法以下:
設有兩臺虛擬機
更改虛擬機docker0網段,v1爲172.17.1.1/24,v2爲172.17.2.1/24
sudo ifconfig docker0 172.17.1.1 netmask 255.255.255.0
sudo bash -c 'echo DOCKER_OPTS="-B=docker0" >> /etc/default/docker' sudo service docker restart # v2 sudo ifconfig docker0 172.17.2.1 netmask 255.255.255.0
sudo bash -c 'echo DOCKER_OPTS="-B=docker0" >> /etc/default/docker'
sudo service docker restart
而後在v1上把v2的docker虛擬網段加入到路由表中,在v2上將v1的docker虛擬網段加入到本身的路由表中
# v1 192.168.124.51 sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 192.168.124.52 sudo iptables -t nat -F POSTROUTING sudo iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -d 172.17.0.0/16 -j MASQUERADE # v2 192.168.124.52 sudo route add -net 172.17.1.0 netmask 255.255.255.0 gw 192.168.124.51 sudo iptables -t nat -F POSTROUTING sudo iptables -t nat -A POSTROUTING -s 172.17.2.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
至此,兩臺虛擬機中的docker容器能夠互相訪問了。