摘要:本文將描述以下內容框架模的實現原理框架模型下的網絡模型如上所示。的一種典型實現是。將這些加入到,即實現了多個的互通。注意三種接口都有其對應的實現如接口的實現為。而插件型的是運行在上,通過通道與之間進行通信。
簡介
Libnetwork是從docker1.6開始,逐漸將docker項目中的網絡部分抽離出來形成的Lib,作用是為其他應用程序(如docker engine)提供一套抽象的容器網絡模型,該模型也被稱為Container Network Model,簡稱CNM。本文將描述以下內容
CNM框架模
Libnetwork的實現原理
plugin demo
CNM 框架
CNM模型下的docker網絡模型如上所示。它由Sandbox, Endpoint, Network 三種組件組成。注意,該模型只是規定了三種組件各自的作用,他們都有各自的具體實現方式。
Sandbox: Sandbox包含了一個Container的網絡相關的配置,如網卡Interface,路由表等。Sandbox在Linux上的典型實現是Network namespace。在Linux系統上的docker環境中,Container,Network namespace,Sandbox 這三者是綁定在一起的。一個Sandbox可以包含多個Endpoint,這些Endpoint 可以來自多個Network
Endpoint: Sandbox加入Network的方式是通過Endpoint完成的。Endpoint的典型實現方式是veth pair,每個Endpoint 都是由某個Network創建,創建后,它就歸屬于該Network,同時,Endpoint還可以加入(Join)一個Sandbox,加入后,相當于該Sandbox也加入了此Network。
Network:Network的一種典型實現是Linux bridge。一個Network可以創建多個Endpoint。將這些Endpoint加入到Sandbox,即實現了多個Sandbox的互通。
總結起來:如果要想兩個Container之間可以直接通信,那么最簡單的辦法就是由一個Network創建兩個Endpoint,分別加入這兩個Container對應的Sandbox。
注意: 不同Network之間默認的隔離性是docker通過設置iptables完成的,通過改變iptables的設置,可以使得兩個Network互通。
Libnetwork 實現 核心對象LibNetwork是CNM框架的實現,Network、Sandbox、Endpoint三種接口描述了前面的三種組件,三種接口分別在network.go 、sandbox.go 、 endpoint.go實現
三個接口需要實現的方法的關系如上圖所示。注意:三種接口都有其對應的實現(如Network接口的實現為network)。
NetworkController 為 docker engine提供創建Network的API,比如我們在使用命令 docker network create 創建網絡時,都是通過controller創建。
除此之外NetworkController接口的實現結構controller還維護了一張Driver的注冊表(Registry),它記錄了所有支持的Driver
Driver 每個Network都有對應的底層Driver,這些Driver負責在主機上真正實現需要網絡功能(如創建Veth設備)。Driver有兩種類型:1. 內置型(如Bridge Host None) 2. 插件型。
無論是哪種類型,其工作方式都類似,docker engine發送請求,Libnetwork做一些框架性的動作,然后將請求傳給Driver做一些特異性的動作。兩者的差別在于,內置性的Driver是內置在Libnetwork內部,它們也就是docker原生支持的網絡類型。而插件型的Driver是運行在Host上,通過socket通道與Libnetwork之間進行通信。
在 controller.go 中的 New() 是創建controller的入口。
func New(cfgOptions ...config.Option) (NetworkContriller, error) { c := controller{ id: stringid.GenerateRandomID(); sandboxes: sandboxTable{}, ..... } drvRegistry, err := drvregistry.New(......) for _, i := range getInitizers(c.cfg.Daemon.Experimental){ drvRegistry.AddDriver(i.ntype,i.fn, dcfg) } c.drvRegistry = drvRegistry }
可以看到,首先是創建controller,此外 它還創建了drvRegistry記錄注冊的Driver,并將 getInitizers() 的返回內置型的 Driver 添加到 drvRegistry 上。
func getInitializers(experimental bool) []initialize { return []initializer { {bridge.Init, "bridge"}, {host.Init, "host"}, {macvlan.Init, "macvlan"}, {null.Init, "null"}, {remote.Init, "remote"}, {overlay.Init, "overlay"}, ...... } }
getInitizers() 包含的內置型Driver如上圖所示,其中的每一項的Init()方法會被調用
創建網絡
創建 network 的入口NewNetwork()同樣在controller.go中,它首先創建一個通用的 network 結構,進而解析出 其Driver 類型,然后調用特定 Driver 的 CreateNetwork() 方法。注意,如果是該網絡的類型不在 drvRegistry 上,則 Libnetwork 會嘗試從 Plugin 路徑 (/var/run/docker/plugins) 尋找 plugin-name.sock .之后,向該 socket 發送創建網絡的 request
以 bridge 為例,其最后會調用到 drivers/bridge/bridge.go 的 createNetwork() 方法,該方法中,使用netlink提供的接口建立了 bridge net device
容器加入在使用 docker run 啟動容器時可以通過指定 -net 參數將容器連接到特定的網絡。入口是 docker 項目中的 container_operations.go 的 connectToNetwork() 方法
圖中左側部分是屬于 docker engine ,中間部分屬于 Libnetwork , 右側部分屬于 Driver 。可以它首先創建Endpoint,創建 Sandbox 和 Endpoint,然后將 Endpoint 加入該 Sandbox 。
Plugin Demo將 docker 原生 Bridge 網絡的功能插件化,制作名為 myPlugin 的網絡插件,效果和原生的 Bridge 一樣.
Code
root@sb:/home/yc# ls -l /run/docker/plugins/ total 0 srw-rw---- 1 root root 0 8月 26 14:41 myplugin.sock root@sb:/home/yc# docker network create --driver myplugin mynet 460db416c6f90fb16c499c5fd56b5e984d6472a113f5d8ed3f8633174159aa53 root@sb:/home/yc# docker network ls NETWORK ID NAME DRIVER SCOPE 6f5763ae335d bridge bridge local 71d355df68ec host host local 460db416c6f9 mynet myplugin local 91360b8a5fe4 none null local docker run -tid --net=mynet busybox 617a314c4f69f835ab1a4e5cf9ce211a55e4651be4fa47e4ebd849c34c192e9d root@sb:/home/yc# docker network inspect mynet [ { "Name": "mynet", "Id": "460db416c6f90fb16c499c5fd56b5e984d6472a113f5d8ed3f8633174159aa53", "Created": "2018-08-26T14:42:51.998760172+08:00", "Scope": "local", "Driver": "myplugin", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "617a314c4f69f835ab1a4e5cf9ce211a55e4651be4fa47e4ebd849c34c192e9d": { "Name": "gallant_wozniak", "EndpointID": "90ce305bea6a2054ee953f6fcebd0d23c94058026ac594d686f4d731464d45d8", "MacAddress": "", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/27531.html
摘要:網絡結構上圖為的網絡模型,大體上可分為和兩個組件其中運行在每臺宿主機上主要負責與交互實現插件邏輯配置底層進程實現具體的網絡功能組件是與交互的核心邏輯以常用的為例該邏輯即是實現框架下所規定的種種接口實現與的消息交互關于和請查看與框架與實現同 Contiv網絡結構 showImg(https://segmentfault.com/img/remote/1460000017001034?w=...
摘要:網絡主要是單機網絡和多主機通信模式。下面分別介紹一下的各個網絡模式。設計的網絡模型。是以對定義的元數據。用戶可以通過定義這樣的元數據來自定義和驅動的行為。 前言 理解docker,主要從namesapce,cgroups,聯合文件,運行時(runC),網絡幾個方面。接下來我們會花一些時間,分別介紹。 docker系列--namespace解讀 docker系列--cgroups解讀 ...
摘要:網絡主要是單機網絡和多主機通信模式。下面分別介紹一下的各個網絡模式。設計的網絡模型。是以對定義的元數據。用戶可以通過定義這樣的元數據來自定義和驅動的行為。 前言 理解docker,主要從namesapce,cgroups,聯合文件,運行時(runC),網絡幾個方面。接下來我們會花一些時間,分別介紹。 docker系列--namespace解讀 docker系列--cgroups解讀 ...
摘要:網絡主要是單機網絡和多主機通信模式。下面分別介紹一下的各個網絡模式。設計的網絡模型。是以對定義的元數據。用戶可以通過定義這樣的元數據來自定義和驅動的行為。 前言 理解docker,主要從namesapce,cgroups,聯合文件,運行時(runC),網絡幾個方面。接下來我們會花一些時間,分別介紹。 docker系列--namespace解讀 docker系列--cgroups解讀 ...
閱讀 2178·2021-11-24 09:38
閱讀 3242·2021-11-08 13:27
閱讀 3083·2021-09-10 10:51
閱讀 3143·2019-08-29 12:20
閱讀 663·2019-08-28 18:28
閱讀 3459·2019-08-26 11:53
閱讀 2706·2019-08-26 11:46
閱讀 1515·2019-08-26 10:56