Docker 架構演進之路

前言

Docker已經推出了5年,在這5年中它極大的改變了互聯網產品的架構,推進了新的產品開發、測試和運維方法。但是它自身也在激烈變化中。特別是最近2年隨著Docker開源項目的不斷演化,Docker內部結構發生了翻天覆地的變化。作為一個容器平臺的使用者,可以不用關注具體的Docker演進細則,但是必須明白Docker的衍化會對自己的PaaS平臺帶來什么樣的影響(如果您對Docker技術細節不關注,你可以直接看第2章和最后兩章)。本文材料來自于Docker社區,對Docker最近幾年的變化趨勢做出了總結。同時在結尾處給出了基于k8s PaaS平臺在底層容器上選型建議?!?/p>

演進方向


圖2-1 Docker結構圖

這里先把結論拋出來,Docker這幾年的架構演進方向:

1、原有引擎功能下沉入containerd,containerd向著獨立于Docker 作為通用容器運行時工具方向演進

2、swarm功能整合入引擎,swarmkit模塊不斷弱化,最終將被引擎吸收

3、引擎內部功能不斷解藕出新模塊,同時新功能不斷加入Docker 引擎。

一言以蔽之:containerd核心化,引擎集群化。

背景

Docker公司在集群管理服務編排工具競爭上落敗

Docker公司在2015年Docker 1.9推出了自己的集群管理服務編排工具swarm,剛開始swarm作為一個獨立的工具,在Docker 引擎之外。但是從Docker 1.12開始Docker公司將swarm整合入了Docker引擎。至此Docker swarm作為一個完整的服務編排工具和谷歌主導、紅帽支持的kubernetes社區直接沖突。于此同時Docker公司在2015開啟了自己的商業化之路,開源社區為了避免Docker公司商業化過程中將Docker淪為綁架社區的工具,所以順勢推出了多個Docker替代方案例如rkt。kubernetes社區推出了CRI-O標準,只要是遵從此標準的容器運行時都可以被K8s支持。一時間Docker大有被主流社區拋棄之勢!經過2年和K8s的競爭時間來到2017年,Docker swarm已經在事實上徹底落敗,Kubernetes社區已經成為開源項目中熱度最高的項目。為了應對如此多的不利因素,Docker公司在2017年將自己主導的containerd捐獻給CNCF基金會(k8s是旗下的子項目);并且將更多的Docker引擎的功能下沉到Containerd中。借此避免自己在開源社區中被邊緣化。

容器世界的標準化不斷推進

Docker公司在2013念推出Docker后,極大的顛覆了這個行業,也推進了業務容器化過程。2015 Docker公司主導之下社區推出了容器的第一個行業標準OCI標準(開放容器協議)。彼時Docker公司推出了第一個OCI標準的容器運行時runc。runc作為第一個oci標準運行時(runtime),只是一個參考實現,僅僅承擔容器與主機之間的交互。容器運行狀態檢查、監控,容器生命期管理,io管理、信號傳遞等一些列容器運行必不可少的功能卻“無處安放”。所以Docker公司將Containerd定位為一個生產環境下的OCI 標準運行時。它承擔了runc所缺少的大部分容器運行必要功能:生命期管理,io管理,信號管理。在2017年的時候OCI v1標準發布,Docker公司將Docker鏡像格式捐獻給了OCI協議。所以在2017年發布的Containerd1.0中存儲管理這些原來由引擎承擔的功能也進入了Containerd(網絡管理功能,在https://containerd.io路線圖中被列為roadmap,但是在2016年12月份Containerd的主要維護者投票中,網絡功能不被列入containerd的功能范疇 而繼續交給上層完成,在github containerd的readme中2017 1月12日正式將網絡部分功能從containerd 維護范疇中刪除)。

Containerd

Containerd在Docker 1.11中才正式出現,剛開始時0.x版本;2017年才推出了1.x標準。如上文所說,Container?d作為一個生產環境可用的Oci 實現,它利用了OCI 運行時和鏡像格式.下圖展現了Containerd對自己在社區中地位作出了詮釋


圖2-1 Containerd在Paas社區上的定位

可以看到Containerd作為PaaS工具的通用容器運行時適配層,它利用已有的oci運行時(Containerd使用runc作為運行時,在windows上則是hcsshim),屏蔽底層操作系統的差異;為Paas提供通用的容器支撐。從這個圖可以看到Containerd計劃支持所有現有應用廣泛的Paas平臺工具。現在可以確認的是AWS ECS,k8s,Docker上使用containerd。Mesos和cloud foundry今天(2018年9月)尚未確定。

下圖為Containerd 1.x的架構圖


圖2-2 Containerd1.x架構圖

從此架構圖可以清楚的看到Containerd對上提供grpc接口方式的api,而Metric api是度量功能使用的。所有的編排工具容器適配層都可以使用grpc api作為containerd的客戶端,使用containerd操作容器。

Distribution用于容器鏡像的pull和push動作(這部分出現在Containerd中完全是因為oci v1標準推出Docker公司將自己鏡像格式貢獻了出去,所以containerd理所當然需要對鏡像進行管理了)。Bundle(在docker的語景里是容器運行的目錄集)子系統用于容器存儲管理它的作用就是原來的graphdriver,它提供將容器鏡像拆解成容器運行時刻需要的Bundle。Runtime子系統用于容器執行和監控,就是它直接操作runtime,傳遞和接收信號(signal),中轉fifo,記錄日志。Content、Metadata和Snapshots是存儲管理組建,Excutor和Supervisor是執行體組建。整個系統通過Event事件驅動。

根據github上containerd的介紹containerd項目工作內容集中在如下幾個領域上:

1、執行:容器創建、運行、停止、暫停、恢復,exec,信號傳遞、和刪除。

2、cow 文件系統支持:在overlay,aufs和其他cow文件系統上內置了存儲功能

3、度量系統

4、發布:容器鏡像的pull和push,鏡像的管理和獲取

下面內容不作為containerd項目的工作范疇:

1、網絡:網絡的創建和管理由高層來完成

2、build:鏡像的構建

3、volumes:volume管理:mounts,bind等針對volume的功能應該有高層來完成

4、logging

此處需要說明一下網絡曾經作為containerd社區爭論的焦點。但是在16年年底的社區維護者投票中多數人支持網絡不留在containerd中,因為按照大多數維護者的認識網絡過于復雜,而且網絡設置常常需要跨越節點。這部分功能由containerd的客戶端(Docker Engine 或k8s)做更合適。

這里順便介紹一下Containerd版本兼容規則:Containerd同一個大版本下的連續兩個小版本是兼容的。例Containerd1.1.0和1.2.0卻是兼容的,1.0.0和1.2.0卻不保證兼容。

Docker的演進

下圖介紹了containerd在1.11之前(不含)的Docker架構


圖3-1Docker1.11(不含)之前的架構

可以看到在Docker1.11之前,沒有containerd模塊,由libcontainer直接操作主機os接口。

下圖介紹了在Docker 1.11--Docker 17.10之間的docker架構


圖3-2 Docker 1.12-17.10之前(含)架構

從圖3-2看到這一時期的Docker架構變化就是引入了Containerd和runc,由Containerd完成容器生命期管理。

下圖列出了Docker 17.11(Docker 17.12為真正的stable版)開始的架構


圖3-3 docker 17.12以后架構


需要注意的一點圖網絡部分并不在containerd中,仍然在docker engine里。

Docker 17的具體架構演進

這里介紹的內容均來自于Moby社區的roadmap和Docker\docker-ce 的分析。

17.06---17.10的路線圖描述此一時期,moby社區(引擎)的主要工作是:

1、插件功能的提升:方便插件的發布(通過registry以docker鏡像方式發布),解決插件開發的共性問題(插件任何時候的需要active,在用戶容器啟動之前就start,以及插件寫在困難)

2、引擎內部解藕:api已完成重構,builder實現在daemon中已完全獨立。

3、提升引擎集群管理能力:當前跨節點網絡(overlay網絡)和節點發現已經整合到引擎里。但是引擎尚不能不依賴于swarmkit完成task調度

4、cli從engine中獨立出來(這一點源自于github moby代碼分析)。

17.11--18.03 的路線描述此一時期,moby社區(引擎)的主要工作:

1、引擎使用Containerd1.0

2、引擎內部解藕,計劃整合buildkit工具

Docker架構演進大事記

1、Docker 1.9 推出swarm,作為獨立工具,用于集群管理和服務編排

2、Docker 1.11 推出containerd和runc。

3、Docker 1.12 swarm進入引擎

4、Docker 17.06 引擎社區更名為moby,do?c?ke?r社區版本更名為docker-ce(類似于紅帽的fedora和rhel)

5、Docker 17.12 Docker正式引入containerd 1.0

6、Docker 18.06 正式在engine里加入了buildkit,在設置一個環境變量后可以使用buildkit完成docker build過程。

Docker 18.06.1正式將containerd 1.1引入docker。


k8s社區對Docker 17.03之后版本態度

在Docker 17.03后Docker因為moby和containerd等原因版本變動比較大,我們可以看到k8s r11發布后的2018年9月仍然沒有將Docker 17.03以后(不含)版本作為k8s的兼容Docker版本。從社區的討論來看社區已經推薦將containerd直接對接cri,完成k8s的集成。見https://github.com/kubernetes/kubernetes/issues/42926,其中cpuguy83(此人為moby社區的主要維護者)推薦直接使用containerd替代docker 17.03以后的版本對接k8s。本來docker在k8s社區中的兼容性測試由k8s sig-node 工作組完成,但是通過k8s討論可以看到sig-node并沒有計劃做docker 17.03以后docker的兼容性測試。

最新消息是2018年9月27日k8s出r12 rc的時候,kubeadm里已經加入了對docker18.06的支持,且完成了ci測試。12 rc 文檔里將docker17.12,18.03,18.06之后列入支持表。但在k8s中 sig-node工作組負責底層容器接口,docker在k8s版本的兼容性測試本應由此工作組完成,但是sig-node對于docker 17.03版本以后docker版本的態度依然冷淡,一直未列入明確的工作計劃中。sig-node工作組兩位主席是谷歌和紅帽的,它們對于cri更感興趣。在2018年5月,sig-node和containerd社區共同完成了cri-containerd合入containerd1.1的工作,并發布了containerd 整合到kubenetes的GA。完成此部分工作后,k8s驅動containerd的結構更簡單明確。下圖介紹了docker,containerd在k8s上的架構圖:


docker在k8s上的架構圖




containerd1.1在k8s上的架構圖

從上面兩幅圖我們可以看到containerd1.1在k8s上擁有更簡單的結構圖,驅動更為簡單。而且根據k8s社區的測試,直接使用containerd替代docker可以獲得容器啟動時間、內存消耗和cpu消耗減少的紅利。上述結論來自于:

https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/

所以sig-node工作組對docker 高版本不感冒。目前多方力量博弈,未來k8s下層的runtime花落誰家還再觀察。


kubelet調用docker容器的方式

docker-manager是老的kubelet介入docker的方式。

cri從k8s 1.6開始正式進入k8s

cri直接介入containerd是從18年4月,containerd1.1開始


PaaS平臺選型建議

如果你正在對基于k8s的PaaS平臺進行生產環境選型,我建議你使用Docker17.03,因為它成熟穩定且k8s r9,r10和r11做過穩定、兼容性測試。如果你喜歡嘗試新事物,我建議你跳過Docker17.03之后,直接在kublet上使用containerd1.1。如果你喜歡docker新版本,那么你可以嘗試docker18.06,因為Docker17.12是Docker變化最劇烈的一個版本穩定性不好說,且kuberadm中r12 rc里加入了對18.06的支持所以用最新的好了。而且更關鍵的一點docker 18.06.1使用containerd 1.1,它支持一個特性:上層容器控制平臺的namespace隔離,簡單點說就是docker和k8s均可以在同一個節點上操作同一個containerd,且相互隔離不可見。如此可以預留選擇傳統k8s+docker組合時刻,保留將來切換成k8s+containerd組合的可能性,進而為自己的框架保持演進的靈活性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,367評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,001評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,213評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,535評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,317評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,868評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,963評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,090評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,599評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,549評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,712評論 1 367
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,233評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,961評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,353評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,607評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,321評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,686評論 2 370

推薦閱讀更多精彩內容

  • 作者:sparkdev 出處:http://www.cnblogs.com/sparkdev/ Docker 和容...
    Java小生閱讀 434評論 0 1
  • 從chroot,control groups,lxc,warden,一路走到如今的docker、rocket、wi...
    yiduyangyi閱讀 2,539評論 0 5
  • 有時候羨慕別人的友誼,羨慕的一塌糊涂,胡思亂想,甚至失眠,我一直擁有不了太多群體的友誼,好友兩三,最多也是三個一群...
    aiyajacqui閱讀 188評論 0 0
  • 大兒正月初九去了重慶,明天小兒又要去蘭州。對于他們的遠行,我是歡喜的。他們是去上學,是去認知世界,是去汲取...
    Haifen閱讀 696評論 3 4
  • 關鍵詞:單親媽媽 題主:女 問: 我是個單親媽媽。七年前丈夫意外去世,留下個三歲的女兒。我一兩年時間,生活過得行尸...
    冷愛閱讀 487評論 0 0