單個主機上容器之間如果要實現網絡互通比較容易實現,一種常見做法是把需要通信的容器網絡接口橋接到相同的主機網絡接口,這樣容器就處在相同的廣播域,它們的網絡地址是由docker來負責分配管理,所以會獲得同一網段的IP位址,網絡互通所需的條件全部滿足。
當容器處在不同的主機,情況就大不相同,因為主機的網絡環境隔離了容器的網絡環境,此時要實現網絡互通,就需要做更多的工作。本文依賴OpenvSwitch實現多主機容器間網絡通信。
1,使用GRE接口
實驗拓撲如下:
GRE
用比較通俗的說法解釋上圖,Host 1上的Container 1連接交換機docker0,docker0連接路由器ovs-br,Host 2上的Container2同理。然後兩臺路由器ovs-br通過GRE隧道相連。用隧道的原因是容器間的流量必須承載在Host 1和Host 2的網絡之上。
配置Host 1:
docker run -d --name container1 centos /bin/bash -c &34; 添加橋接設備ovs-brip link add veth0 type veth peer name veth1 veth1接入ovs-brbrctl addif docker0 veth0 啟動veth1ip link set veth0 up 配置GRE隧道,接口為gre0,remote_ip為Host 2的主機IPovs-vsctl add-port ovs-br gre0 -- set interface gre0 type=gre options:remote_ip= 10.1.48.2
配置Host 2(為了避免和Host 1上Container 1上的IP位址衝突,可以啟動兩個容器,將第二個啟動的容器作為Container2)
docker run -d --name container2 centos /bin/bash -c &34;ovs-vsctl add-br ovs-brip link add veth0 type veth peer name veth1ovs-vsctl add-port ovs-br veth1brctl addif docker0 veth0ip link set veth1 upip link set veth0 upovs-vsctl add-port ovs-br gre0 -- set interface gre0 type=gre options:remote_ip= 10.1.48.3
配置完畢後,進入Container 1,ping測試Container 2發現是可以ping通的。
2,使用VxLAN接口
拓撲如下:
VxLan
這次直接把docker自帶的網橋docker0去掉,因為它不是必需的。
ovs-vsctl add-br ovs-br ifconfig ovs-br 192.168.8.1/24啟動一個容器,不使用默認網橋設備docker run --net=none --privileged=true -it ubuntu 將ovs-br上的接口eth0與容器a8706151885d綁定ovs-docker add-port ovs-br eth0 a8706151885d #在Container 1內執行ifconfig eth0 192.168.8.2/24
Host 2上的配置類似,ovs-br的IP位址設置為192.168.8.4,容器內eth0的IP位址配置為192.168.8.3
配置完畢後,在Host 1的容器裡面 ping測試Host 2上的容器,發現是通的。ping測試的同時,在Host 2的網卡eth0抓下包,可以看到VxLAN的身影,如下圖所示:
pcap
關於VxLAN的詳情,可參考https://tools.ietf.org/html/rfc7348