八徊哑、Docker Container 網(wǎng)絡(luò) 下(摘自《Docker源碼分析》)

1袜刷、Docker Client 配置容器網(wǎng)絡(luò)模式

Docker 目前支持 4 種網(wǎng)絡(luò)模式,分別是 bridge莺丑、host著蟹、container、none

配置 Docker Container 網(wǎng)絡(luò)環(huán)境與創(chuàng)建 Docker Container 網(wǎng)絡(luò)環(huán)境有一些區(qū)別
  • 配置網(wǎng)絡(luò)環(huán)境指用戶通過向 Docker Client 傳遞網(wǎng)絡(luò)參數(shù)梢莽,實現(xiàn) Docker Container 網(wǎng)絡(luò)環(huán)境參數(shù)的配置萧豆,這部分配置由 Docker Client 傳遞至 Docker Daemon,并由 Docker Daemon 保存
  • 創(chuàng)建網(wǎng)絡(luò)環(huán)境指昏名,用戶通過 Docker Client 向 Docker Daemon 發(fā)送容器啟動命令之后涮雷,Docker Daemon 根據(jù)之前保存的網(wǎng)絡(luò)參數(shù),實現(xiàn) Docker Container 的啟動轻局,并在啟動過程中完成 Docker Container 網(wǎng)絡(luò)環(huán)境的創(chuàng)建洪鸭。

1.1、Docker Client 使用

Docker 架構(gòu)中仑扑,用戶可以通過 Docker Client 來配置 Docker Container 的網(wǎng)絡(luò)模式览爵。配置過程主要通過 docker run 命令來完成,實現(xiàn)配置的方式是在 docker run 命令中添加網(wǎng)絡(luò)參數(shù)镇饮。

Docker Client 解析出 run 命令之后蜓竹,立即調(diào)用相應(yīng)的處理函數(shù) CmdRun 進行處理關(guān)于 run 請求的具體內(nèi)容。CmdRun 的作用主要可以歸納為三點:

*解析 Docker Client 傳入的參數(shù)盒让,解析出 config、hostconfig 和 cmd 對象等司蔬;
*發(fā)送請求至 Docker Daemon邑茄,創(chuàng)建一個 container 對象,完成 Docker Container 啟動前的準備工作俊啼;
*發(fā)送請求至 Docker Daemon肺缕,啟動相應(yīng)的 Docker Container(包含創(chuàng)建 Docker Container 網(wǎng)絡(luò)環(huán)境創(chuàng)建)。

1.2授帕、runconfig 包解析

config 的類型為 Config 結(jié)構(gòu)體同木,hostConfig 的類型為 HostConfig 結(jié)構(gòu)體,兩種類型的定義均位于 runconfig 包跛十。Config 與 HostConfig 類型同用以描述 Docker Container 的配置信息彤路,然而兩者之間又有著本質(zhì)的區(qū)別,最大的區(qū)別在于兩者各自的作用范疇:
*Config 結(jié)構(gòu)體:描述 Docker Container 獨立的配置信息芥映。獨立的含義是:Config 這部分信息描述的是容器本身洲尊,而不會與容器所在 host 宿主機相關(guān)远豺;
*HostConfig 結(jié)構(gòu)體:描述 Docker Container 與宿主機相關(guān)的配置信息。

1.2.1坞嘀、Config 結(jié)構(gòu)體

結(jié)構(gòu)體的定義如下:

type Config struct {
   Hostname        string  //容器主機名
   Domainname      string //域名名稱
   User            string  //用戶名
   Memory          int64  // Memory limit (in bytes)容器內(nèi)存使用上限(單位:字節(jié))
   MemorySwap      int64  // Total memory usage (memory + swap); set `-1' to disable swap 容器所有的內(nèi)存使用上限(物理內(nèi)存 + 交互區(qū))躯护,關(guān)閉交互區(qū)支持置為 -1
   CpuShares       int64  // CPU shares (relative weight vs. other containers)容器 CPU 使用 share 值,其他容器的相對值
   Cpuset          string // Cpuset 0-2, 0,1CPU 核的使用集合
   AttachStdin     bool  //是否附加標準輸入
   AttachStdout    bool  //是否附加標準輸出
   AttachStderr    bool  //是否附加標準錯誤輸出
   PortSpecs       []string // Deprecated - Can be in the format of 8080/tcp 目前已被遺棄
   ExposedPorts    map[nat.Port]struct{}  //容器內(nèi)部暴露的端口號
   Tty             bool // Attach standard streams to a tty, including stdin if it is not closed.是否分配一個偽終端 tty
   OpenStdin       bool // Open stdin 在沒有附加標準輸入時丽涩,是否依然打開標準輸入
   StdinOnce       bool // If true, close stdin after the 1 attached client disconnects.若為真棺滞,表示第一個客戶關(guān)閉標準輸入后關(guān)閉標準輸入功能
   Env             []string //容器進程運行的環(huán)境變量
   Cmd             []string  //容器內(nèi)通過 ENTRYPOINT 運行的指令
   Image           string // Name of the image as it was passed by  容器 rootfs 所依賴的鏡像名稱
the operator (eg. could be symbolic)
   Volumes         map[string]struct{}  //容器需要從 host 宿主機上掛載的目錄
   WorkingDir      string  //容器內(nèi)部的指定工作目錄
   Entrypoint      []string //覆蓋鏡像屬性中默認的 ENTRYPOINT
   NetworkDisabled bool  //是否關(guān)閉容器網(wǎng)絡(luò)功能
   OnBuild         []string
}
1.2.2、HostConfig 結(jié)構(gòu)體

結(jié)構(gòu)體的定義如下:

type HostConfig struct {
   Binds           []string //從宿主機上綁定到容器的 volumes
   ContainerIDFile string  //文件名矢渊,文件用以寫入容器的 ID
   LxcConf         []utils.KeyValuePair  //添加自定義的 lxc 選項
   Privileged      bool  //是否賦予該容器擴展權(quán)限
   PortBindings    nat.PortMap  //容器綁定到 host 宿主機的端口
   Links           []string  //添加其他容器的鏈接到該容器
   PublishAllPorts bool  //是否向宿主機暴露所有端口信息
   Dns             []string  //自定義的 DNS 服務(wù)器地址
   DnsSearch       []string  //自定義的 DNS 查找服務(wù)器地址
   VolumesFrom     []string  //從指定的容器中掛載到該容器的 volumes
   Devices         []DeviceMapping  //為容器添加一個或多個宿主機設(shè)備
   NetworkMode     NetworkMode //為容器設(shè)置的網(wǎng)絡(luò)模式
   CapAdd          []string  //為容器用戶添加一個或多個 Linux Capabilities
   CapDrop         []string  //為容器用戶禁用一個或多個 Linux Capabilities
   RestartPolicy   RestartPolicy  //當(dāng)一個容器異常退出時采取的重啟策略
}
1.2.3继准、runconfig 解析網(wǎng)絡(luò)模式

runconfig 包中的 ParseSubcommand 函數(shù)調(diào)用 parseRun 函數(shù)完成命令請求的分析,該函數(shù)完成了四方面的工作:
*定義與容器配置信息相關(guān)的 flag 參數(shù)昆淡;
*解析 docker run 命令后緊跟的請求內(nèi)容锰瘸,將請求內(nèi)容全部保存至 flag 參數(shù)中,余下的內(nèi)容一個為鏡像 image 名昂灵,另一個為需要在容器內(nèi)執(zhí)行的 cmd 命令避凝;
*通過 flag 參數(shù)驗證參數(shù)的有效性,并處理得到 Config 結(jié)構(gòu)體與 HostConfig 結(jié)構(gòu)體需要的屬性值眨补;
*創(chuàng)建并初始化 Config 類型實例 config管削、HostConfig 類型實例 hostConfig,最總返回 config撑螺、hostConfig 與 cmd含思。

1.3、CmdRun 執(zhí)行

CmdRun 后續(xù)主要工作是:利用 Docker Daemon 暴露的 RESTful API 接口甘晤,將 docker run 的請求發(fā)送至 Docker Daemon含潘。

CmdRun 執(zhí)行過程中 Docker Client 與 Docker Daemon 的簡易交互圖如下:
CmdRun 中Docker Client 與Docker Daemon 交互圖.jpg

2、Docker Daemon 創(chuàng)建容器網(wǎng)絡(luò)流程

Docker Daemon 接收到 Docker Client 的請求大致可以分為兩次线婚,第一次為 create container遏弱,第二次為 start container

2.1、創(chuàng)建容器并配置網(wǎng)絡(luò)參數(shù)

Docker Daemon 首先接收并處理 create container 請求塞弊。需要注意的是:create container 并非創(chuàng)建了一個運行的容器漱逸,而是完成了以下三個主要的工作:
*通過 runconfig 包解析出 create container 請求中與 Docker Container 息息相關(guān)的 config 對象;
*在 Docker Daemon 內(nèi)部創(chuàng)建了與 Docker Container 對應(yīng)的 container 對象游沿;
*完成 Docker Container 啟動前的準備化工作饰抒,如準備所需鏡像、創(chuàng)建 rootfs 等诀黍。

與 Docker Container 網(wǎng)絡(luò)模式配置相關(guān)的內(nèi)容主要位于創(chuàng)建 container 對象中
container := &Container{
   ID:              id,
   Created:         time.Now().UTC(),
   Path:            entrypoint,
   Args:            args, //FIXME: de-duplicate from config
   Config:          config,
   hostConfig:      &runconfig.HostConfig{},
   Image:           img.ID, // Always use the resolved image id
   NetworkSettings: &NetworkSettings{},
   Name:            name,
   Driver:          daemon.driver.String(),
   ExecDriver:      daemon.execDriver.Name(),
   State:           NewState(), 
}
其中 hostConfig 對象將在 start container 請求執(zhí)行過程中被賦值袋坑,NetworkSettings 類型的作用是描述容器的網(wǎng)絡(luò)具體信息
type NetworkSettings struct {
    IPAddress   string  //IP 網(wǎng)絡(luò)地址
    IPPrefixLen int  //網(wǎng)絡(luò)標識位長度
    Gateway     string  //網(wǎng)關(guān)地址
    Bridge      string  //網(wǎng)橋地址
    PortMapping map[string]PortMapping // Deprecated 端口映射
    Ports       nat.PortMap  //端口號
}

2.2、啟動容器之網(wǎng)絡(luò)配置

啟動容器過程中眯勾,Docker Daemon 首先通過 runconfig 包中 ContainerHostConfigFromJob 函數(shù)咒彤,解析出請求中的 hostConfig 對象
Start 函數(shù)執(zhí)行過程中疆柔,與 Docker Container 網(wǎng)絡(luò)模式相關(guān)的部分主要有三部分:
*initializeNetwork(),初始化 container 對象中與網(wǎng)絡(luò)相關(guān)的屬性镶柱;
*populateCommand蜈漓,填充 Docker Container 內(nèi)部需要執(zhí)行的命令聘芜,Command 中含有進程啟動命令迈倍,還含有容器環(huán)境的配置信息追城,也包括網(wǎng)絡(luò)配置;
*container.waitForStart()故觅,實現(xiàn) Docker Container 內(nèi)部進程的啟動厂庇,進程啟動之后,為進程創(chuàng)建網(wǎng)絡(luò)環(huán)境等输吏。

3权旷、execdriver 網(wǎng)絡(luò)執(zhí)行流程

在 Docker Daemon 啟動容器的最后一步,即調(diào)用了 execdriver 的 Run 函數(shù)來執(zhí)行贯溅。通過分析 Run 函數(shù)的具體實現(xiàn)拄氯,關(guān)于 Docker Container 的網(wǎng)絡(luò)執(zhí)行流程主要包括兩個環(huán)節(jié):
(1) 創(chuàng)建 libcontainer 的 Config 對象
(2) 通過 libcontainer 中的 namespaces 包執(zhí)行啟動容器

Docker Container 網(wǎng)絡(luò)相關(guān)的流程,可以得到以下示意圖:
execdriver.Run 執(zhí)行流程圖.jpg
3.1它浅、 創(chuàng)建 libcontainer 的 Config 對象

libcontainer.Config 的作用是译柏,定義在一個容器化的環(huán)境中執(zhí)行一個進程所需要的所有配置項。createContainer 函數(shù)的存在姐霍,使用 Docker Daemon 層創(chuàng)建的 execdriver.Command鄙麦,創(chuàng)建更下層 libcontainer 所需要的 Config 對象。這個角度來看镊折,execdriver 更像是封裝了 libcontainer 對外的接口胯府,實現(xiàn)了將 Docker Daemon 認識的容器啟動信息轉(zhuǎn)換為底層 libcontainer 能真正使用的容器啟動配置選項。libcontainer.Config 類型與其內(nèi)部對象的關(guān)聯(lián)圖如下:

libcontainer.Config 類型關(guān)系圖.jpg

3.2恨胚、 調(diào)用 libcontainer 的 namespaces 啟動容器

創(chuàng)建完 libcontainer.Config 實例 container骂因,經(jīng)過一系列其他方面的處理之后,最終 execdriver 執(zhí)行 namespaces.Exec 函數(shù)實現(xiàn)啟動容器与纽,container 對象依然是 namespace.Exec 函數(shù)中一個非常重要的參數(shù)

4侣签、libcontainer 實現(xiàn)內(nèi)核態(tài)網(wǎng)絡(luò)配置

當(dāng) execdriver 調(diào)用 libcontainer 中 namespaces 包的 Exec 函數(shù)時塘装,libcontainer 開始發(fā)揮其實現(xiàn)容器功能的作用急迂。Docker Container 的網(wǎng)絡(luò)創(chuàng)建,因此從這個角度來看Exec 的實現(xiàn)可以分為三個步驟:
(1) 通過 createCommand 創(chuàng)建一個 Golang 語言內(nèi)的 exec.Cmd 對象蹦肴;

(2) 啟動命令 exec.Cmd僚碎,執(zhí)行容器內(nèi)第一個進程;

(3) 通過 InitializeNetworking 函數(shù)為容器進程初始化網(wǎng)絡(luò)環(huán)境阴幌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺阐,一起剝皮案震驚了整個濱河市卷中,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渊抽,老刑警劉巖蟆豫,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異懒闷,居然都是意外死亡十减,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門愤估,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帮辟,“玉大人,你說我怎么就攤上這事玩焰∮删裕” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵昔园,是天一觀的道長蔓榄。 經(jīng)常有香客問我,道長蒿赢,這世上最難降的妖魔是什么润樱? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮羡棵,結(jié)果婚禮上壹若,老公的妹妹穿的比我還像新娘。我一直安慰自己皂冰,他們只是感情好店展,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秃流,像睡著了一般赂蕴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舶胀,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天概说,我揣著相機與錄音,去河邊找鬼嚣伐。 笑死糖赔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的轩端。 我是一名探鬼主播放典,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奋构?” 一聲冷哼從身側(cè)響起壳影,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弥臼,沒想到半個月后宴咧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡径缅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年悠汽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芥驳。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柿冲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出兆旬,到底是詐尸還是另有隱情假抄,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布丽猬,位于F島的核電站宿饱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脚祟。R本人自食惡果不足惜谬以,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望由桌。 院中可真熱鬧为黎,春花似錦、人聲如沸行您。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娃循。三九已至炕檩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捌斧,已是汗流浹背笛质。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捞蚂,地道東北人妇押。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像洞难,于是被迫代替她去往敵國和親舆吮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容