Docker libnetwork(CNM)設計簡介


The Container Network Model

CNM由以下三個組件構成:Sandbox,Endpoint以及Network

Sandbox

一個Sandbox包含了一個容器網絡棧的配置。其中包括了對容器的網卡,路由表以及對DNS設置的管理。通常,一個Sandbox的實現可以是一個Linux Network Namespace,一個FreeBSD Jail或者其他類似的東西。一個Sandbox可以包含多個處於不同Network的Endpoint。

Endpoint

Endpoint將一個Sandbox加入一個Network。Endpoint的實現可以是一個veth對,一個Open vSwitch internal port或者其他類似的東西。一個Endpoint只能屬於一個Network和一個Sandbox。

Network

Network是一個能夠互相通信的Endpoint的集合。Network的實現可以是一個Linux網橋,一個VLAN等等。

 

CNM Objects

NetworkController object為用戶(例如Docker Engine)創建和管理Network提供了簡單的API。libnetwork支持多種類型的driver(包括內置的和遠程的)。NetworkController允許用戶將特定的driver和給定的Network綁定在一起。

Driver object對於用戶並不是可見的,但是是它讓Network能夠正常工作。NetworkController提供了用專用的options/labels配置特定的driver的API,這些options/labels對於libnetwork是透明的,但是能被driver直接處理。其中Driver可以是內置的(例如Bridge,Host,None或者Overlay),也可以是遠程的(由plugin provider提供)用來滿足不同的使用和部署場景。此時,Driver擁有一個Network並且負責管理該Network(包括IPAM等等)。將來可以讓多個Driver參與處理各種Network的管理。

Network object是上述CNM:Network的具體實現。NetworkController提供了創建和管理Network object的API。當一個Network被創建或更新時,相應的Driver會收到一個事件通知。LibNetwork使用Network object作為一個抽象層,用於將一系列屬於同一個Network的Endpoint連接起來,並且隔離其余的Endpoint。而具體的對於連接和隔離的操作是由Driver提供的。連通的Endpoint可以位於同一個Host,也可以跨多個Host。因此,Network是一個全局的概念。

Endpoint代表了一個Service Endpoint。它為本容器暴露的Service和同一Network中的其他容器暴露的Service提供了連通性。Network object提供了用於創建和管理Endpoint的API。一個Endpoint只能和一個Network相連。Endpoint的創建和相應的Driver相對應,因為Driver負責為相應的Sandbox申請資源。因為Endpoint代表的是一個Service而不一定是特定的容器,因此Endpoint也是一個全局的概念。

Sandbox object代表了一個容器的網絡配置,例如IP地址,Mac地址,路由以及DNS。Sandbox object是用戶請求在一個Network里創建一個Endpoint時被創建的。該Network相對應的Driver負責申請相應的網絡資源(例如IP地址)並且返回一個SandboxInfo的結構給libnetwork。libnetwork通過一些特定於操作系統的結構(例如Linux中的netns)將網絡配置傳遞給容器,通常由一個Sandbox表示。一個Sandbox可以有多個Endpoint用於連接不同的Network。因為Sandbox和給定Host上的特定容器相關聯,因此它只是一個局部的概念。

 

CNM Attribute

Options 提供了一種通用靈活的機制,可以讓用戶直接向Driver傳遞特定的配置選項。Option其實只是一些key-value pair,其中key由一個字符串表示,value由一個generic object表示(例如go中的interface{})。Libnetwork只有在Option中的key和net-labels包中已知的Label匹配是才對它進行操作。同時Options也包含了下面要描述的Labels。通常,Options對於用戶是不可見的,但是Labels可以。

Labels和Options非常類似,事實上,它是Options的一個子集。Labels對於用戶是可見的,可以在UI中呈現通過使用--labels選項。它們從UI傳遞到Driver,從而Driver能夠使用它並且執行一些特定的操作(例如從一個Network中申請IP地址)

 

CNM Lifecycle

CNM的用戶通過與CNM的Object以及API的交互來管理對應容器的網絡。

  1. Driver要向NetworkController注冊。內置的Driver在Libnetwork內注冊,遠程的Driver則通過Plugin mechanism注冊。每一個Driver處理特定的networkType。
  2. NetworkController通過libnetwork.New()創建,用於Network的創建以及通過一些特定的Options配置Driver。
  3. Network通過給controller的NewNetwork()API提供name和networkType來創建。networkType參數用來選擇特定的Driver並且將創建的Network和該Driver相關聯。從此以后,對於Network的任何操作都由Driver處理。
  4. controller.NewNetwork()還有一個可選的options參數,用於提供特定Driver的options和Labels。
  5. network.CreateEndpoint()可以用於在給定的Network中創建一個新的Endpoint。同時該API還有一個可選的options參數供Driver使用。這個"options"既可以攜帶已知的labels,也可以攜帶和特定Driver相關的labels。之后調用相應的Driver的driver.CreateEndpoint,它可以為在一個Endpoint在Network中被創建時,為它們保留IP地址。Driver會通過driverapi中定義的InterfaceInfo進行這些地址的賦值。IP地址將和endpoint暴露的端口用來完善Endpoint作為Service的定義。事實上,Service endpoint不是其他什么東西,僅僅只是一個網絡地址以及該應用的容器監聽的端口號。
  6. endpoint.Join()用於將Endpoint與一個容器相連接。Join操作會先創建一個Sandbox如果對應的容器中還沒有的話。Driver可以使用Sandbox Key來識別連接到同一個容器的多個Endpoint。這個API同樣接受可選的options參數供Driver使用。
    • 雖然這並不是Libnetwork直接的設計要求,但是我們鼓勵像Docker這樣的用戶在執行容器的Start()操作時,即在容器可以操作之前,調用endpoint.Join()。
    • 另一個關於endpoint.join()這個API經常被提到的問題是,為什么我們需要一個API創建Endpoint和另一個API來join endpoint。事實上Endpoint代表的是一個Service,它可能有,也可能並沒有容器支持。當一個Endpoint被創建的時候,會預留它所需的資源,因此任何容器都能連接該Endpoint並且獲得一個一致的網絡行為。
  7. endpoint.Leave()會在容器停止的時候被調用。Driver可以清除它在調用Join()時獲取的狀態。Libnetwork會在最后一個Endpoint離開的時候刪除Sandbox。但是只要該Endpoint依舊存在,Libnetwork會依然保有IP地址並且在有新的容器加入的時候進行重用。這保證了容器的資源在停止並重啟的過程中能夠重用。
  8. endpoint.Delete()用於從一個Network中刪除Endpoint。這將導致Endpoint的刪除以及清空緩存的sandbox.Info
  9. network.Delete()用於刪除Network。如果還有Endpoint連接到該網絡,Libnetwork是不允許對它進行刪除的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM