Docker源碼分析(六):Docker Daemon網路

來源:互聯網
上載者:User

標籤:

1. 前言

Docker作為一個開源的輕量級虛擬化容器引擎技術,已然給雲端運算領域帶來了新的發展模式。Docker藉助容器技術徹底釋放了輕量級虛擬化技術的威力,讓容器的伸縮、應用的運行都變得前所未有的方便與高效。同時,Docker藉助強大的鏡像技術,讓應用的分發、部署與管理變得史無前例的便捷。然而,Docker畢竟是一項較為新穎的技術,在Docker的世界中,使用者並非一勞永逸,其中最為典型的便是Docker的網路問題。

毋庸置疑,對於Docker管理者和開發人員而言,如何有效、高效的管理Docker容器之間的互動以及Docker容器的網路一直是一個巨大的挑戰。目前,雲端運算領域中,絕大多數系統都採取分布式技術來設計並實現。然而,在原生態的Docker世界中,Docker的網路卻是不具備跨宿主機能力的,這也或多或少滯後了Docker在雲端運算領域的高速發展。

工業界中,Docker的網路問題的解決勢在必行,在此環境下,很多IT企業都開發了各自的新產品來協助完善Docker的網路。這些企業中不乏像Google一樣的互連網翹楚企業,同時也有不少初創企業率先出擊,在最前沿不懈探索。這些新產品中有,Google推出的容器管理和編排開源項目Kubernetes,Zett.io公司開發的通過虛擬網路串連跨宿主機容器的工具Weave,CoreOS團隊針對Kubernetes設計的網路覆蓋工具Flannel,Docker官方的工程師Jérôme Petazzoni自己設計的SDN網路解決方案Pipework,以及SocketPlane項目等。

 

對於Docker管理者與開發人員而言,Docker的跨宿主機通訊能力固然重要,但Docker自身的網路架構也同樣重要。只有深入瞭解Docker自身的網路設計與實現,才能在這基礎上擴充Docker的跨宿主機能力。

Docker自身的網路主要包含兩部分:Docker Daemon的網路設定,Docker Container的網路設定。本文主要分析Docker Daemon的網路。

2. Docker Daemon網路分析內容安排

本文從源碼的角度,分析Docker Daemon在啟動過程中,為Docker配置的網路環境,章節安排如下:

 

(1) Docker Daemon網路設定;

(2) 運行Docker Daemon網路初始化任務;

(3) 建立Docker橋接器。

本文為《Docker源碼分析》系列第六篇——Docker Daemon網路篇,第七篇將安排Docker Container網路篇。

3. Docker Daemon網路設定

Docker環境中,Docker管理員完全有許可權配置Docker Daemon運行過程中的網路模式。 關於Docker的網路模式,大家最熟知的應該就是“橋接”的模式。為橋接模式下,Docker的網路環境拓撲圖(包括Docker Daemon網路環境和Docker Container網路環境):

圖3.1 Docker網路橋接

然而,“橋接”是Docker網路模式中最為常用的模式。除此之外,Docker還為使用者提供了更多的可選項,下文將對此一一說來。

3.1 Docker Daemon網路設定介面

Docker Daemon每次啟動的過程中,都會初始化自身的網路環境,這樣的網路環境最終為Docker Container提供網路通訊服務。

Docker管理員配置Docker的網路環境,可以在Docker Daemon啟動時,通過Docker提供的介面來完成。換言之,可以使用docker二進位可執行檔,運行docker -d並添加相應的flag參數來完成。

其中涉及的flag參數有EnableIptables、EnableIpForward、BridgeIface、BridgeIP以及InterContainerCommunication。該五個參數的定義位於./docker/daemon/config.go,具體代碼如下:

flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable Docker‘s addition of iptables rules")flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge‘s IP, not compatible with -b")flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse ‘none‘ to disable container networking")flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")

以下介紹這5個flag的作用:

  • EnableIptables:確保Docker對於宿主機上的iptables規則擁有添加許可權;
  • EnableIpForward:確保net.ipv4.ip_forward可以使用,使得多網路介面裝置模式下,資料報可以在網路裝置之間轉寄;
  • BridgeIP:在Docker Daemon啟動過程中,為網路環境中的橋接器配置CIDR網路地址;
  • BridgeIface:為Docker網路環境指定具體的通訊橋接器,若BridgeIface的值為”none”,則說明不需要為Docker Container建立橋接器服務,關閉Docker Container的網路能力;
  • InterContainerCommunication:確保Docker容器之間可以完成通訊。

除了Docker會使用到的5個flag參數之外,Docker在建立網路環境時,還使用一個DefaultIP變數,如下:

opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")

該變數的作用是:當綁定容器的連接埠時,將DefaultIp作為預設使用的IP地址。

具備了以上Docker Daemon的網路背景知識,以下著重舉例分析使用BridgeIP和BridgeIface,在啟動Docker Daemon時進行網路設定:

啟動Docker Daemon使用命令

用途注釋

docker -d

啟動Docker Daemon,使用預設橋接器docker0,不指定CIDR網路地址

docker -d -b=”xxx”

啟動Docker Daemon,使用

橋接器xxx,不指定CIDR網路地址

docker -d --bip=”172.17.42.1”

啟動Docker Daemon,使用預設橋接器docker0,使用指定CIDR網路地址”172.17.42.1”

docker -d --bridge=”xxx” --bip=”10.0.42.1”

報錯,出現相容性問題,不能同時指定”BridgeIP”和”BridgeIface”

docker -d --bridge=”none”

啟動Docker Daemon,

不建立Docker網路環境

深入理解BridgeIface與BridgeIP,並熟練使用相應的flag參數,即做到了如何配置Docker Daemon的網路環境。需要特別注意的是,Docker Daemon的網路與Docker Container的網路存在很大的區別。Docker Daemon為Docker Container建立網路的大環境,Docker Container的網路需要Docker Daemon的網路提供支援,但不唯一。舉一個形象的例子,Docker Daemon可以建立docker0橋接器,為之後Docker Container的橋接模式提供支援,然而Docker Container仍然可以根據使用者需求建立自身網路,其中Docker Container的網路可以是橋接模式的網路,同時也可以直接共用使用宿主機的網路介面,另外還有其他模式,會在《Docker源碼分析》系列的第七篇——Docker Container網路篇中詳細介紹。

3.2 Docker Daemon網路初始化

正如上一節所言,Docker管理員可以通過與網路相關的flag參數BridgeIface與BridgeIP,來為Docker Daemon建立網路環境。最簡單的,Docker管理員通過執行”docker -d”就已經完成了運行Docker Daemon,而Docker Daemon在啟動的時候,根據以上兩個flag參數的值,建立相應的網路環境。

Docker Daemon網路初始化流程圖如下:

圖 3.2 Docker Daemon網路初始化流程圖

Docker Daemon網路初始化的流程總體而言,主要是根據解析flag參數來決定到底建立哪種類型的網路環境。從流程圖中可知,Docker Daemon建立網路環境時有兩個分支,不難發現分支代表的分別是:為Docker建立一個網路驅動、以及對Docker的網路不做任何的操作。

以下參照Docker Daemon網路初始化流程圖具體分析實現步驟。

3.2.1 啟動Docker Daemon傳遞flag參數

使用者啟動Docker Daemon,並在命令列中選擇性的傳入所需要的flag參數。

3.2.2 解析網路flag參數

flag包對命令列中的flag參數進行解析,其中和Docker Daemon網路設定相關的flag參數有5個,分別是:EnableIptables、EnableIpForward、BridgeIP、BridgeIface以及InterContanierCommunication,各個flag參數的作用上文已有介紹。

3.2.3 預先處理flag參數

預先處理與網路設定相關的flag參數資訊,包括檢測配置資訊的相容性、以及判斷是否建立Docker網路環境。

首先檢驗是否會出現彼此不相容的配置資訊,源碼位於./docker/daemon/daemon.go#L679-L685。

這部分的相容資訊有兩種。第一種是BridgeIP和BridgeIface配置資訊的相容性,具體表現為使用者啟動Docker Daemon時,若同時指定了BridgeIP和BridgIface的值,則出現相容問題。原因為這兩者屬於互斥對,換言之,若使用者指定了建立橋接器的裝置名稱,那麼該橋接器已經存在,無需指定橋接器的IP地址BridgeIP;若使用者指定了建立橋接器的網路IP地址BridgeIP,那麼該橋接器肯定還沒有建立成功,則Docker Daemon在建立橋接器時使用預設橋接器名“docker0”。具體如下:

// Check for mutually incompatible config optionsif config.BridgeIface != "" && config.BridgeIP != "" {return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")}

第二種是EnableIptables和InterContainerCommunication配置的相容性,具體是指不能同時指定這兩個flag參數為false。原因很簡單,如果指定InterContainerCommunication為false,則說明Docker Daemon不允許建立的Docker容器之間互相進行通訊。但是為了達到以上目的,Docker正是使用iptables過濾規則。因此,再次設定EnableIptables為false,關閉iptables的使用,即出現了自相矛盾的結果。代碼如下:

if !config.EnableIptables && !config.InterContainerCommunication {return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")}

檢驗完系統配置資訊的相容性問題,Docker Daemon接著會判斷是否需要為Docker Daemon配置網路環境。判斷的依據為BridgeIface的值是否與DisableNetworkBridge的值相等,DisableNetworkBridge在./docker/daemon/config.go#L13中被定義為const量,值為字串”none”。因此,若BridgeIface為”none”,則DisableNetwork為true,最終Docker Daemon不會建立網路環境;若BridgeIface不為”none”,則DisableNetwork為false,最終Docker Daemon需要建立網路環境(橋接模式)。

3.2.4 確定Docker網路模式

Docker網路模式由配置資訊DisableNetwork決定。由於在上一環節已經得出DisableNetwork的值,故這一環節可以確定Docker網路模式。該部分的源碼實現位於./docker/daemon/daemon.go#L792-L805,如下:

if !config.DisableNetwork {job := eng.Job("init_networkdriver")job.SetenvBool("EnableIptables", config.EnableIptables)job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)job.SetenvBool("EnableIpForward", config.EnableIpForward)job.Setenv("BridgeIface", config.BridgeIface)job.Setenv("BridgeIP", config.BridgeIP)job.Setenv("DefaultBindingIP", config.DefaultIp.String())if err := job.Run(); err != nil {return nil, err}}

若DisableNetwork為false,則說明需要建立網路環境,具體的模式為建立Docker橋接器模式。建立網路環境的步驟為:

(1) 建立名為”init_networkdriver”的job;

(2) 為該job配置環境變數,設定的環境變數有EnableIptables、InterContainerCommunication、EnableIpForward、BridgeIface、BridgeIP以及DefaultBindingIP;

(3) 運行job。

運行”init_network”即為建立Docker橋接器,這部分內容將會在下一節詳細分析。

若DisableNetwork為true。則說明不需要建立網路環境,網路模式屬於none模式。

以上便是Docker Daemon網路初始化的所有流程。

3.3 建立Docker橋接器

Docker的網路往往是Docker開發人員最常提起的話題。而Docker網路中最常使用的模式為bridge橋接模式。本小節將詳細分析建立Docker橋接器的建立流程。

建立Docker橋接器的實現通過”init_network”這個job的運行來完成。”init_network”的實現為InitDriver函數,位於./docker/daemon/networkdriver/bridge/driver.go#L79,運行流程如下:

圖3.3 Docker Daemon建立橋接器流程圖

3.3.1 提取環境變數

在InitDriver函數的實現過程中,Docker首先提取”init_networkdriver”這個job的環境變數。這樣的環境變數共有6個,各自的作用在上文已經詳細說明。具體的實現代碼為:

var (network        *net.IPNetenableIPTables = job.GetenvBool("EnableIptables")icc            = job.GetenvBool("InterContainerCommunication")ipForward      = job.GetenvBool("EnableIpForward")bridgeIP       = job.Getenv("BridgeIP"))if defaultIP := job.Getenv("DefaultBindingIP"); defaultIP != "" {defaultBindingIP = net.ParseIP(defaultIP)}bridgeIface = job.Getenv("BridgeIface")
3.3.2 確定Docker橋接器裝置名稱

提取job的環境變數之後,Docker隨即確定最終使用橋接器裝置的名稱。為此,Docker首先建立了一個名為usingDefaultBridge的bool變數,含義為是否使用預設的橋接器裝置,預設值為false。接著,若環境變數中bridgeIface的值為空白,則說明使用者啟動Docker時,沒有指定特定的橋接器裝置名稱,因此Docker首先將usingDefaultBridge置為true,然後使用預設的橋接器裝置名稱DefaultNetworkBridge,即docker0;若bridgeIface的值不為空白,則判斷條件不成立,繼續往下執行。這部分的代碼實現為:

usingDefaultBridge := falseif bridgeIface == "" {usingDefaultBridge = truebridgeIface = DefaultNetworkBridge}
3.3.3 尋找bridgeIface橋接器裝置

確定Docker橋接器裝置名稱bridgeIface之後,Docker首先通過bridgeIface裝置名稱在宿主機上尋找該裝置是否真實存在。若存在,則返回該橋接器裝置的IP地址,若不存在,則返回nil。實現代碼位於./docker/daemon/networkdriver/bridge/driver.go#L99,如下:

addr, err := networkdriver.GetIfaceAddr(bridgeIface)

GetIfaceAddr的實現位於./docker/daemon/networkdriver/utils.go,實現步驟為:首先通過Golang中net包的InterfaceByName方法擷取名為bridgeIface的橋接器裝置,會得出以下結果:

  • 若名為bridgeIface的橋接器裝置不存在,直接返回error;
  • 若名為bridgeIface的橋接器裝置存在,返回該橋接器裝置的IP地址。

需要強調的是:GetIfaceAddr函數返回error,說明當前宿主機上不存在名為bridgeIface的橋接器裝置。而這樣的結果會有兩種不同的情況:第一,使用者指定了bridgeIface,那麼usingDefaultBridge為false,而該bridgeIface橋接器裝置在宿主機上不存在;第二,使用者沒有指定bridgeIface,那麼usingDefaultBridge為true,bridgeIface名為docker0,而docker0橋接器在宿主機上也不存在。

當然,若GetIfaceAddr函數返回的是一個IP地址,則說明當前宿主機上存在名為bridgeIface的橋接器裝置。這樣的結果同樣會有兩種不同的情況:第一,使用者指定了bridgeIface,那麼usingDefaultBridge為false,而該bridgeIface橋接器裝置在宿主機上已經存在;第二,使用者沒有指定bridgeIface,那麼usingDefaultBridge為true,bridgeIface名為docker0,而docker0橋接器在宿主機上也已經存在。第二種情況一般是:使用者在宿主機上第一次啟動Docker Daemon時,建立了預設橋接器裝置docker0,而後docker0橋接器裝置一直存在於宿主機上,故之後在不指定橋接器裝置的情況下,重啟Docker Daemon,會出現docker0已經存在的情況。

以下兩小節將分別從bridgeIface已建立與bridgeIface未建立兩種不同的情況分析。

3.3.4 bridgeIface已建立的情況

Docker Daemon所在宿主機上bridgeIface的橋接器裝置存在時,Docker Daemon仍然需要驗證使用者在配置資訊中是否為橋接器裝置指定了IP地址。

使用者啟動Docker Daemon時,假如沒有指定bridgeIP參數資訊,則Docker Daemon使用名為bridgeIface的原有的IP地址。

當使用者指定了bridgeIP參數資訊時,則需要驗證:指定的bridgeIP參數資訊與bridgeIface橋接器裝置原有的IP地址資訊是否匹配。若兩者匹配,則驗證通過,繼續往下執行;若兩者不匹配,則驗證不通過,拋出錯誤,顯示“bridgeIP與已有橋接器配置資訊不匹配”。該部分內容位於./docker/daemon/networkdriver/bridge/driver.go#L119-L129,代碼如下:

network = addr.(*net.IPNet)// validate that the bridge ip matches the ip specified by BridgeIPif bridgeIP != "" {bip, _, err := net.ParseCIDR(bridgeIP)if err != nil {return job.Error(err)}if !network.IP.Equal(bip) {return job.Errorf("bridge ip (%s) does not match existing bridge configuration %s", network.IP, bip)}}
3.3.5 bridgeIface未建立的情況

Docker Daemon所在宿主機上bridgeIface的橋接器裝置未建立時,上文已經介紹將存在兩種情況:

l 使用者指定的bridgeIface未建立;

l 使用者未指定bridgeIface,而docker0暫未建立。

當使用者指定的bridgeIface不存在於宿主機時,即沒有使用Docker的預設橋接器裝置名稱docker0,Docker列印日誌資訊“指定橋接器裝置未找到”,並返回橋接器未找到的錯誤資訊。代碼實現如下:

if !usingDefaultBridge {job.Logf("bridge not found: %s", bridgeIface)return job.Error(err)}

當使用的預設橋接器裝置名稱,而docker0橋接器裝置還未建立時,Docker Daemon則立即實現建立橋接器的操作,並返回該docker0橋接器裝置的IP地址。代碼如下:

// If the iface is not found, try to create itjob.Logf("creating new bridge for %s", bridgeIface)if err := createBridge(bridgeIP); err != nil {return job.Error(err)}job.Logf("getting iface addr")addr, err = networkdriver.GetIfaceAddr(bridgeIface)if err != nil {return job.Error(err)}network = addr.(*net.IPNet)

建立Docker Daemon橋接器裝置docker0的實現,全部由createBridge(bridgeIP)來實現,createBridge的實現位於./docker/daemon/networkdriver/bridge/driver.go#L245。

createBridge函數實現過程的主要步驟為:

(1) 確定橋接器裝置docker0的IP地址;

(2) 通過createBridgeIface函數建立docker0橋接器裝置,並為橋接器裝置分配隨機的MAC地址;

(3) 將第一步中已經確定的IP地址,添加給新建立的docker0橋接器裝置;

(4) 啟動docker0橋接器裝置。

以下詳細分析4個步驟的具體實現。

首先Docker Daemon確定docker0的IP地址,實現方式為判斷使用者是否指定bridgeIP。若使用者未指定bridgeIP,則從Docker預先準備的IP網段列表addrs中尋找合適的網段。具體的代碼實現位於./docker/daemon/networkdriver/bridge/driver.go#L257-L278,如下:

if len(bridgeIP) != 0 {_, _, err := net.ParseCIDR(bridgeIP)if err != nil {return err}ifaceAddr = bridgeIP} else {for _, addr := range addrs {_, dockerNetwork, err := net.ParseCIDR(addr)if err != nil {return err}if err := networkdriver.CheckNameserverOverlaps(nameservers, dockerNetwork); err == nil {if err := networkdriver.CheckRouteOverlaps(dockerNetwork); err == nil {ifaceAddr = addrbreak} else {log.Debugf("%s %s", addr, err)}}}}

其中為橋接器裝置準備的候選網段地址addrs為:

addrs = []string{"172.17.42.1/16", // Don‘t use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23"10.0.42.1/16",   // Don‘t even try using the entire /8, that‘s too intrusive"10.1.42.1/16","10.42.42.1/16","172.16.42.1/24","172.16.43.1/24","172.16.44.1/24","10.0.42.1/24","10.0.43.1/24","192.168.42.1/24","192.168.43.1/24","192.168.44.1/24",}

通過以上的流程的執行,可以確定找到一個可用的IP網段地址,為ifaceAddr;若沒有找到,則返回錯誤記錄檔,表明沒有合適的IP地址賦予docker0橋接器裝置。

第二個步驟通過createBridgeIface函數建立docker0橋接器裝置。createBridgeIface函數的實現如下:

func createBridgeIface(name string) error {kv, err := kernel.GetKernelVersion()// only set the bridge‘s mac address if the kernel version is > 3.3// before that it was not supportedsetBridgeMacAddr := err == nil && (kv.Kernel >= 3 && kv.Major >= 3)log.Debugf("setting bridge mac address = %v", setBridgeMacAddr)return netlink.CreateBridge(name, setBridgeMacAddr)}

以上代碼通過宿主機Linux核心資訊,確定是否支援設定橋接器裝置的MAC地址。若Linux核心版本大於3.3,則支援配置MAC地址,否則則不支援。而Docker在不小於3.8的核心版本上運行才穩定,故可以認為核心支援配置MAC地址。最後通過netlink的CreateBridge函數實現建立docker0橋接器。

Netlink是Linux中一種較為特殊的socket通訊方式,提供了使用者應用間和核心進行雙向資料轉送的途徑。在這種模式下,使用者態可以使用標準的socket API來使用netlink強大的功能,而核心態需要使用專門的核心API才能使用netlink。

Libcontainer的netlink包中CreateBridge實現了建立實際的橋接器裝置,具體使用系統調用的代碼如下:

syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr)))

建立完橋接器裝置之後,為docker0橋接器裝置配置MAC地址,實現函數為setBridgeMacAddress。

第三個步驟是為建立docker0橋接器裝置綁定IP地址。上一步驟僅完成了建立名為docker0的橋接器裝置,之後仍需要為docker0橋接器裝置綁定IP地址。具體代碼實現為:

if netlink.NetworkLinkAddIp(iface, ipAddr, ipNet); err != nil {return fmt.Errorf("Unable to add private network: %s", err)}

NetworkLinkAddIP的實現同樣位於libcontainer中的netlink包,主要的功能為:通過netlink機製為一個網路介面裝置綁定一個IP地址。

第四個步驟是啟動docker0橋接器裝置。具體實現代碼為:

if err := netlink.NetworkLinkUp(iface); err != nil {return fmt.Errorf("Unable to start network bridge: %s", err)}

NetworkLinkUp的實現同樣位於libcontainer中的netlink包,功能為啟動docker橋接器裝置。

至此,docker0橋接器曆經確定IP、建立、綁定IP、啟動四個環節,createBridge關於docker0橋接器裝置的工作全部完成。

3.3.6 擷取橋接器裝置的網路地址

建立完橋接器裝置之後,橋接器裝置必然會存在一個網路地址。橋接器網路地址的作用為:Docker Daemon在建立Docker Container時,使用該網路地址為Docker Container分配IP地址。

Docker使用代碼network = addr.(*net.IPNet)擷取橋接器裝置的網路地址。

3.3.7 配置Docker Daemon的iptables

建立完橋接器之後,Docker Daemon為容器以及宿主機配置iptables,包括為container之間所需要的link操作提供支援,為host主機上所有的對外對內流量制定傳輸規則等。該部分詳情可以參看《Docker源碼分析(四):Docker Daemon之NewDaemon實現》。代碼位於./docker/daemon/networkdriver/bridge/driver/driver.go#L133,如下:

// Configure iptables for link supportif enableIPTables {if err := setupIPTables(addr, icc); err != nil {return job.Error(err)}}// We can always try removing the iptablesif err := iptables.RemoveExistingChain("DOCKER"); err != nil {return job.Error(err)}if enableIPTables {chain, err := iptables.NewChain("DOCKER", bridgeIface)if err != nil {return job.Error(err)}portmapper.SetIptablesChain(chain)}
3.3.8 配置網路裝置間資料報轉寄功能

在Linux系統上,資料包轉寄功能是被預設禁止的。資料包轉寄,就是當host主機存在多個網路裝置時,如果其中一個接收到資料包,並需要將其轉寄給另外的網路裝置。通過修改/proc/sys/net/ipv4/ip_forward的值,將其置為1,則可以保證系統內資料包可以實現轉寄功能,代碼如下:

if ipForward {// Enable IPv4 forwardingif err := ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte{‘1‘, ‘\n‘}, 0644); err != nil {job.Logf("WARNING: unable to enable IPv4 forwarding: %s\n", err)}}
3.3.9 註冊網路Handler

建立Docker Daemon網路環境的最後一個步驟是:註冊4個與網路相關的Handler。這4個Handler分別是allocate_interface、release_interface、allocate_port和link,作用分別是為Docker Container分配網路裝置,回收Docker Container網路裝置、為Docker Container分配連接埠資源、以及為Docker Container間執行link操作。

至此,Docker Daemon的網路環境初始化工作全部完成。

4 總結

在工業界,Docker的網路問題備受關注。Docker的網路環境可以分為Docker Daemon網路和Docker Container網路。本文從Docker Daemon的網路入手,分析了大家熟知的Docker 橋接模式。

Docker的容器技術以及鏡像技術,已經給Docker實踐者帶來了諸多效益。然而Docker網路的發展依然具有很大的潛力。下一篇Docker Container網路篇,將會帶來更為靈活的Docker網路設定。

 5 參考文獻

http://www.cnblogs.com/iceocean/articles/1594195.html

http://docs.studygolang.com/pkg/net/

Docker源碼分析(六):Docker Daemon網路

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.