多主機的網絡直連需求源于ACS的金融云業務場景。 在此場景下,Docker容器運行在阿里云的ECS VM之中, Docker傳統的網絡解決方案采用NAT的方式實現容器間互聯,不同宿主機的容器之間無法感知到真實ip地址,因此無法滿足如配置中心這樣的架構。而ECS又不支持給VM獨立增加IP,從而迫使我們在短期內只能一個VM跑一個Docker的方案,勢必會造成資源的浪費。OVS的直連方案隔離了宿主機和Docker容器的網絡平面,提供了VM運行多Docker容器的能力,結合上ACS的容器編排能力,能大大提高資源的利用率,降低成本。
1. Docker主機網絡互聯的概述如果要實現多主機的容器網絡通信,Docker,原生的網絡模型可以采用Port Mapping的方式,本質上是對兩個有互訪需求的container用iptables實現了SNAT/DNAT。但這并不能算真正意義的直連互訪,因為兩個容器內可見的IP地址并非是容器本身的IP地址,而是容器所在宿主機的地址。那么對于一些Java的應用,如配置中心,則無法正常工作。(假設配置中心的服務器和客戶端分別在兩個容器內,客戶端將會采用容器的自身地址去服務器注冊,而這個地址對其他人來說是不可見的)
圍繞多主機的Docker 容器互訪,開源社區衍生出許多項目,有Weave,Flannel, Sockerplane,Opencontrail,Docker的1.9版本之后,Libnetwork也提供了原生的Overlay網絡。這些解決方案其實就是在原有宿主機網絡平面上再封裝一個容器的網絡平面,也稱為Overlay網絡。這里的封裝封裝,又可以分成兩類。這些封裝大致分成兩類,用戶態封裝(如Weave)或內核態封裝(如Sockplane)。
Weave把容器報文嗅探到用戶態空間,封裝在UDP報文,然后在遠端主機解封并注入容器網絡。貼一張比較早的Weave實現原理,現在Weave也有基于OVS的Fastpath。
Flannel則提供了多種封裝協議,UDP,Vxlan,基于亞馬遜VPCaws-vpc、gce、Socketplane 采用的是Openvswitch Vxlan。基于Openvswitch Vxlan的封裝在性能上有明顯的優勢。網上有一組性能對比圖可以參考下:
從數據來看,Weave的用戶態封裝的方式無論在帶寬和延遲上都有很大的損耗,而采用Openvswitch Vxlan的方式,基本無損耗。
2. OVS多主機互聯的設計和實現要點本節主要介紹下如何去設計Overlay網絡。
1)ARP,首要要解決的是ARP的問題。在經典的物理網絡中,當一個主機A訪問另外一個主機B的時候,A發出的第一包就是ARP Request的廣播包,物理交換機會廣播這個ARP Request,如果雙方同屬一個Subnet,那么B會直接回復ARP Reply給A,后續AB就可以進行正常的IP通信。如果AB處于不同的Subnet,網關會回復A的ARP 請求。
那么在容器網絡該如何處理呢?一般來說ARP的處理有兩種模式:
第一種:如實的把報文廣播出去,如Weave。Weave建立一套能夠在Weave節點之間互相學習的網絡拓撲的機制,從而能夠實現無論是在網絡穩態(即所有節點都能知道了整個網絡拓撲),或是部分網絡(網絡拓撲還在學習過程中)都能正確的廣播這些包。基本也是采用Spintree來避免廣播環路,而真正實現廣播報文的發生。而RFC 提到是利用基礎交換機的IP組播功能,畢竟如果通過主機把廣播轉化為單播是比較效率低下的。
第二種:考慮SDN的方案,SND控制器有全局的網絡拓撲信息,或者采用SDN的交換機。SDN控制器的要實現的功能是ARP 代理。
2)第二個要解決的問題是,容器訪問其他網絡如公網的需求。一般的采用Nat的方式,使得容器具有其宿主機的網絡訪問能力,如果宿主機能訪問外網,那么容器也可以。
3)第三個要考慮的問題是,容器對外提供服務。這里的解決方法是類似Docker 提供Port Mapping,然后把容器掛載到負載均衡設備,對外提供服務。
根據以上的設計要點,我們的設計如下:
主要設計點的方案是:
通過OVS代理ARPAntrouter組件和ZK扮演SDN Controller的角色NAT/Portmapping的方式解決公網和外網服務的功能另外,根據Docker的插件機制,以及基于易用性的設計,我們還提供了以下優化:
OVS和網絡插件都以容器的方式運行。增加了Docker 指定IP啟動容器的Patch。把IPAM Driver 集成到 Vxlan 網絡插件內部,使得Vxlan網絡之間的IP地址完全獨立。實踐展示這里假定我們已經有一個Swarm集群。前面提到插件以容器的方式提供服務,所以先啟動OVS和 Vxlan插件容器。
然后創建一個Vxlan網絡
查看下網絡
創建兩個容器
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu
查看IP地址
測試網絡聯通:
測試外網:
子網內互通:
可以在創建是時候指定多個Subnet/Gateway,以建立多子網的Vxlan 網絡也可以在后續創建新的Vxlan網絡,VxlanID 相同的Vxlan網絡內,容器互通
那么這個Vxlan網絡和之前的Vxlan網絡是互通的。
因此ACS 的Vxlan網絡是一個支持自定義網絡規劃的網絡,這在金融云,阿里云經典VM,或者是測試集群資源的規劃上將大有裨益。
4 性能最后提供一組性能數據,這是兩個跨主機的容器在物理機的測試結果:帶寬113MB/s,物理機是117MB/s,可以看出帶寬基本無損耗。
Q&A
Q:我見你是一臺主機創建了一個Vxlan,如果有上萬臺機器,豈不是要創建上萬個Vxlan?
A:創建網絡是通過Swarm管理的,因此只需創建一次。
Q:這個對網絡硬件有要求么?
A:沒有具體的要求,倒是相應的內核版本要編譯OVS的Kernel模塊。
Q:有沒有試過Docker自帶的Overlay網絡,和OVS有什么區別?
A:Docker自帶的Overlway網絡,通過Serf提供的鄰居節點發現功能,如實的廣播ARP,而我們OVS網絡,ARP都被代理了。另外Overlay需要更高的內核支持,應該是3.19,OVS沒有這個限制。另外我們還提供多租戶內網絡地址復用。
Q:我以前OVS和Docker容器重啟后,容器的IP變化了怎么辦?
A:在Vxlan網絡里面,在容器的生命周期內,IP不變。
Q:為什么不直接使用大二層,就像之前的IaaS,2個主機的容器在Vlan里面可以互通?
A: 關于Vlan,我們也有自己的Vlan網絡插件。Vlan和Vxlan場景不同,Vxlan的優勢是可以節省IP地址資源。
文章轉載自:dockerone微信公眾號