docker網絡配置方法總結

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

# Edit this variable: the 'other' host.
REMOTE_IP=188.226.138.185
 
# Edit this variable: the bridge address on 'this' host.
BRIDGE_ADDRESS=172.16.42.1/24
 
# Name of the bridge (should match /etc/default/docker).
BRIDGE_NAME=docker0
 
# bridges
 
# Deactivate the docker0 bridge
ip link set $BRIDGE_NAME down
# Remove the docker0 bridge
brctl delbr $BRIDGE_NAME
# Delete the Open vSwitch bridge
ovs-vsctl del-br br0
# Add the docker0 bridge
brctl addbr $BRIDGE_NAME
# Set up the IP for the docker0 bridge
ip a add $BRIDGE_ADDRESS dev $BRIDGE_NAME
# Activate the bridge
ip link set $BRIDGE_NAME up
# Add the br0 Open vSwitch bridge
ovs-vsctl add-br br0
# Create the tunnel to the other host and attach it to the
# br0 bridge
ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=$REMOTE_IP
# Add the br0 bridge to docker0 bridge
brctl addif $BRIDGE_NAME br0
 
# iptables rules
 
# Enable NAT
iptables -t nat -A POSTROUTING -s 172.16.42.0/24 ! -d 172.16.42.0/24 -j MASQUERADE
# Accept incoming packets for existing connections
iptables -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Accept all non-intercontainer outgoing packets
iptables -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
# By default allow all outgoing traffic
iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT
 
# Restart Docker daemon to use the new BRIDGE_NAME
service docker restart

 

4. 使用weave爲容器配置IP(使用方法見http://www.cnblogs.com/feisky/p/4093717.html),weave的特性包括

  • 應用隔離:不一樣子網容器之間默認隔離的,即使它們位於同一臺物理機上也相互不通;不一樣物理機之間的容器默認也是隔離的
  • 物理機之間容器互通:weave connect $OTHER_HOST
  • 動態添加網絡:對於不是經過weave啓動的容器,能夠經過weave attach 10.0.1.1/24 $id來添加網絡(detach刪除網絡)
  • 安全性:能夠經過weave launch -password wEaVe設置一個密碼用於weave peers之間加密通訊
  • 與宿主機網絡通訊:weave expose 10.0.1.102/24,這個IP會配在weave網橋上
  • 查看weave路由狀態:weave ps
  • 經過NAT實現外網訪問docker容器

 

5. 修改主機docker默認的虛擬網段,而後在各自主機上分別把對方的docker網段加入到路由表中,配合iptables便可實現docker容器誇主機通訊。配置方法以下:

 

設有兩臺虛擬機

  • v1: 192.168.124.51
  • v2: 192.168.124.52

更改虛擬機docker0網段,v1爲172.17.1.1/24,v2爲172.17.2.1/24

#v1
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容器能夠互相訪問了。

相關文章
相關標籤/搜索