91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

阿里開源富容器引擎 PouchContainer 的 network 連接機制

發布時間:2020-08-10 18:40:51 來源:網絡 閱讀:1495 作者:阿里系統軟件技術 欄目:建站服務器



PouchContainer 是阿里巴巴集團開源的高效、輕量級企業級富容器引擎技術,擁有隔離性強、可移植性高、資源占用少等特性。可以幫助企業快速實現存量業務容器化,同時提高超大規模下數據中心的物理資源利用率

PouchContainer 源自阿里巴巴內部場景,誕生初期,在如何為互聯網應用保駕護航方面,傾盡了阿里巴巴工程師們的設計心血。PouchContainer 的強隔離、富容器等技術特性是最好的證明。在阿里巴巴的體量規模下,PouchContainer 對業務的支撐得到雙 11 史無前例的檢驗,開源之后,阿里容器成為一項普惠技術,定位于「助力企業快速實現存量業務容器化」。

本文將給大家介紹 PouchContainer 實現 network 的機制以及將容器連接到 network 上的原理。為了充分闡述 network 的連接機制,本文將以Connect方法為例,敘述如何動態地將一個 container 連接到一個已存在的 network 上。

1. PouchContainer 實現 network 的機制

在目前的容器網絡虛擬化技術中,Docker 推行的 CNM (Container Network Model)模型是一種通用的解決方案,CNM 構建了一種成熟的容器虛擬化網絡模型,并定義了多種供開發者調用的標準化接口。PouchContainer 沿用了 CNM 模型,基于 libnetwork 來實現容器間通信。下面先對 Sandbox、Endpoint 和 Network 這三個 CNM 中的核心組件進行介紹。

Sandbox

Sandbox 一詞在不同的機制里,被分別賦予了不同的定義。例如,在 CRI(container runtime interface)里面 sandbox 就代表著 pod 的概念。而在 CNM 模型里,sandbox 代表著一個容器的網絡棧配置,包含管理容器的網卡,路由表以及 DNS 設置。Sandbox 的具體實現可以通過 Linux 系統的 network namespace,一個 FreeBSD Jail 或者其他類似的概念。一個 sandbox 可以包含多個 endpoints。

Endpoint

一個 endpoint 將 sandbox 連接到 network 上。一個 endpoint 的實現可以通過 veth pair,Open vSwitch internal port 或者其他的方式。比較常見的方法是用 veth pair,顧名思義,veth pair一定是成對出現的,因此會存在 veth0 和 veth2 兩塊網卡。創建容器時,其中一塊會被設置到容器內部,充當容器內部的eth0,所有目的地址為容器 IP 的數據包都要經過 eth0 網卡;另一塊(以下稱為 veth 設備)則會被連接到宿主機的網橋上。從 veth 設備出去的數據包,會轉發到對應的 eth0 設備上,當數據包的目的地址為 eth0 設備的 IP 時,就能被內核協議棧處理。用 veth pair 來連接兩個 network namespace,從而建立網絡連通關系。一個 Endpoint 只能屬于一個 Network,也只能屬于一個 Sandbox。

Network

一個 Network 是一組可以相互通信的 Endpoints 的集合。一個 network 的實現可以通過 Linux bridge,VLAN 或者其他方式。值得一提的是,一個 network 中可以包含很多個 endpoints。

可以看到,在如下圖所示的結構下,Container A 和 Container B 同屬于 backend network,這兩個 container通過各自紫色的 endpoint 構成 network 連接;container B和 container C 同屬于 frontend network,通過藍色的 endpoint 構成 network 連接。因此 container A 和 container B之間可以通信,container B和 container C之間也可以通信。

接下來重點看一下 container B 內部的兩個 endpoints,雖然 backend network 和 frontend network 在 container B 內都有各自對應的 endpoint,但紫色 endpoint 和藍色 endpoint 間不構成通信。因此 backend network 和 frontend network 是兩個完全隔離的 network,并不因為連接同一個 container 而產生連通。顯而易見,container A 和 container C 間其實是無法通信的。

阿里開源富容器引擎 PouchContainer 的 network 連接機制

2. PouchContainer 內置的 network 模式

2.1 bridge 模式

bridge 模式是 PouchContainer 默認的網絡模式,在創建容器不指定 network 模式,即不寫--net參數,該容器就會以 bridge 模式創建。pouchd啟動的時候,會自動在主機上創建一個虛擬網橋 p0。后續以 bridge 模式創建容器時,pouchd從 p0 網橋所在的 IP 網段中選取一個未使用的 IP 分配給容器的 eth0 網卡,p0 的 IP 是這些容器的默認網關。

阿里開源富容器引擎 PouchContainer 的 network 連接機制 

2.2 host 模式

在啟動容器的時候,選擇 host 模式,那么容器將不會獲得獨立的 network namespace,而是和主機共享 network namespace。因此,這個容器也就沒有自己的網卡和 IP 配置,會使用主機的 IP 和端口,但 fs 和 pid 等與主機還是隔離的。

阿里開源富容器引擎 PouchContainer 的 network 連接機制

2.3 container 模式

以 container 模式創建的容器,會和已經存在的容器共享一個 network namespace,直接沿用其 veth 設備對。

阿里開源富容器引擎 PouchContainer 的 network 連接機制

2.4 none 模式

使用 none 模式創建的容器,擁有獨立的 network namespace,但是不會對容器進行任何的網絡配置。因此,可以認為 none 模式下的容器,是不和其它容器通信的。不過,在容器創建后,可以再給它添加網卡、配置 IP,這樣就可以與同一個 network 下的容器通信了。

阿里開源富容器引擎 PouchContainer 的 network 連接機制

2.5 CNM 與 network 模式的概念交叉

一個 network 是一個唯一的、可識別的 endpoint 組,組內的 endpoint 可以相互通訊。對比 CNM 來看,endpoint 可以簡單理解成 veth 設備對,容器的 sandbox 里可以有多個 endpoints,每個 endpoint 代表和一個特定 network 的連接關系。

3. network connect 的流程分析

// daemon/mgr/container.go

// Connect is used to connect a container to a network.
func (mgr *ContainerManager) Connect(ctx context.Context, name string, networkIDOrName string, epConfig *types.EndpointSettings) error {
    ……
    if err := mgr.updateNetworkConfig(c, n.Name, epConfig); err != nil {
        return err
    } else 
    if err := mgr.connectToNetwork(ctx, c, networkIDOrName, epConfig); err != nil {
        return err
    }
    return c.Write(mgr.Store)
}

可以看到在Connect函數里,首先根據傳入的參數獲取到具體的 container 和 network。而epConfig參數里面,存放的是在 CLI 端通過 flag 傳入的參數,如 container 在特定 network 中的別名、指定的 IP 范圍等。

查看c.State.Status來判斷 container 此時的狀態,dead 狀態的 container 是無法執行 connect 操作的。對于非 running 但是還 live的container,只是簡單地調用updateNetworkConfig()來更新 container 的網絡配置,將傳入的epConfig加入到容器的 network 配置中。在這種情況下,不會為 container 分配網卡,因此 container 并沒有成功連通到 network 中。對于 running 狀態的 container,調用connectToNetwork()來進行后續的操作,connectToNetwork()會根據給定的 network 和 container 進行網卡的配置,再在主機上分配一個網卡,最后將網卡加入到 container 的 sandbox 里面。這樣,container 就成功地連接到 network 上了!具體的流程會在后續進行解析。

c.Write(mgr.Store)的作用,是將 container 連接到 network 上的一系列配置寫入 container 的 metadata 里面,這樣就保證了數據的持久化。否則,建立的 network 連接只是一次性的,所有的數據和相關配置在pouchd重啟后都會丟失。

// daemon/mgr/container.go

func (mgr *ContainerManager) connectToNetwork(ctx context.Context, container *Container, networkIDOrName string, epConfig *types.EndpointSettings) (err error) {
    ……
    endpoint := mgr.buildContainerEndpoint(container)
    ……
    if _, err := mgr.NetworkMgr.EndpointCreate(ctx, endpoint); err != nil {
        ……
    }
    return mgr.updateNetworkConfig(container, networkIDOrName, endpoint.EndpointConfig)
}

endpoint 里面包含三部分的信息,一部分的信息來自于 container,一部分的信息來自 network,最后一部分信息是 connect 命令里 flag 中的配置。buildContainerEndpoint()的邏輯比較簡單,就是獲取到 endpoint 需要的 container 相關信息。隨后調用了NetworkMgrEndpointCreate()來進行具體的構建。

// daemon/mgr/network.go

// EndpointCreate is used to create network endpoint.
func (nm *NetworkManager) EndpointCreate(ctx context.Context, endpoint *types.Endpoint) (string, error) {
    ……
    // create endpoint
    epOptions, err := endpointOptions(n, endpoint)
    ……
    endpointName := containerID[:8]
    ep, err := n.CreateEndpoint(endpointName, epOptions...)
    ……

    // create sandbox
    sb := nm.getNetworkSandbox(containerID)
    if sb == nil {
        sandboxOptions, err := buildSandboxOptions(nm.config, endpoint)
        ……
        sb, err = nm.controller.NewSandbox(containerID, sandboxOptions...)
        ……
    }

    // endpoint joins into sandbox
    joinOptions, err := joinOptions(endpoint)
    ……
    if err := ep.Join(sb, joinOptions...); err != nil {
        return "", fmt.Errorf("failed to join sandbox(%v)", err)
    }

    // update endpoint settings
    epInfo := ep.Info()
    if epInfo.Gateway() != nil {
        endpointConfig.Gateway = epInfo.Gateway().String()
    }
    if epInfo.GatewayIPv6().To16() != nil {
        endpointConfig.IPV6Gateway = epInfo.GatewayIPv6().String()
    }
    endpoint.ID = ep.ID()
    endpointConfig.EndpointID = ep.ID()
    endpointConfig.NetworkID = n.ID()
    iface := epInfo.Iface()
    ……
    return endpointName, nil

}

創建 endpoint 的整個過程,都是調用 libnetwork 來實現的。首先調用endpointOptions()來構建接口要求的EndpointOption參數,這個 setter 函數類型的參數能將不同的 option 傳遞給 network 和 endpoint 的接口。隨后調用 libnetwork 的
CreateEndpoint()接口來進行具體的構建。CreateEndpoint()執行的實際工作包括為這個 endpoint 分配 IP 和接口(Iface),對應的配置會被應用到 Endpoint 中,其中包括 iptables 的配置規則和端口信息等。

Sandbox 所代表的就是 container 獨有的 network namespace,其創建也是基于 libnetwork。sandbox 里面包含 container 建立網絡通信的標志性信息,如 IP 地址、Mac 地址、路由和 DNS 等配置。會對已存在的 sandbox 進行遍歷,判斷是否存在相應的 sandbox,存在的話就直接返回對應的 sandbox。在 none 模式下,container 沿用主機的 namespace,返回的 sandbox 為空,這時候會創建一個新的 sandbox。sandbox 的創建過程,就是調用 namespace 和 cgroup 來創建一個獨立 sandbox 空間。

將 endpoint 加入到 sandbox 的操作,實際上就是將網卡分配給 container 的過程,將 endpoint 分配到的網絡資源注入到 sandbox 中。網卡是建立連接的核心,container 通過虛擬網卡連接到 network,從而與其它 container 進行通信。

最后一步,將變化同步更新到 endpoint 的配置里面。

4. 總結

回顧建立 network 連接的整個流程,可以簡單的分成幾步。container 在通信時需要唯一的 network namespace 來標志自己,那么就要有 sandbox 的創建;通信的實現需要網卡作為基礎,那么就要有 endpoint 的創建;最后將endpoint  加入 sandbox,建立容器間通信的基礎,連接的建立就成功完成了。

如果想更多了解 PouchContainer,請訪問 https://pouchcontainer.io




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

明光市| 札达县| 砀山县| 鹤庆县| 平乐县| 闽侯县| 巨鹿县| 会理县| 黎川县| 华池县| 揭西县| 肇州县| 尼勒克县| 江北区| 乌兰察布市| 静乐县| 东安县| 丁青县| 时尚| 嵊州市| 霞浦县| 开封市| 恩平市| 宁远县| 临邑县| 封丘县| 陵川县| 嵩明县| 盐亭县| 林州市| 怀来县| 扶风县| 齐河县| 栾城县| 中西区| 重庆市| 大渡口区| 白山市| 洛隆县| 北安市| 城固县|