你好,我是張磊巡通。今天我和你分享的主題是:從容器到容器云尘执,談?wù)?Kubernetes 的本質(zhì)。
在前面的四篇文章中宴凉,我以 Docker 項(xiàng)目為例誊锭,一步步剖析了Linux 容器的具體實(shí)現(xiàn)方式。通過這些講解你應(yīng)該能夠明白:一個(gè)“容器”弥锄,實(shí)際上是一個(gè)由 Linux Namespace炉旷、Linux Cgroups 和 rootfs 三種技術(shù)構(gòu)建出來的進(jìn)程的隔離環(huán)境签孔。
從這個(gè)結(jié)構(gòu)中我們不難看出,一個(gè)正在運(yùn)行的 Linux 容器窘行,其實(shí)可以被“一分為二”地看待:
1. 一組聯(lián)合掛載在 /var/lib/docker/aufs/mnt 上的 rootfs,這一部分我們稱為“容器鏡像”(Container Image)图仓,是容器的靜態(tài)視圖罐盔;
2. 一個(gè)由 Namespace+Cgroups 構(gòu)成的隔離環(huán)境,這一部分我們稱為“容器運(yùn)行時(shí)”(Container Runtime)救崔,是容器的動(dòng)態(tài)視圖惶看。
更進(jìn)一步地說,作為一名開發(fā)者六孵,我并不關(guān)心容器運(yùn)行時(shí)的差異纬黎。因?yàn)椋谡麄€(gè)“開發(fā) - 測(cè)試 - 發(fā)布”的流程中劫窒,真正承載著容器信息進(jìn)行傳遞的本今,是容器鏡像,而不是容器運(yùn)行時(shí)主巍。
這個(gè)重要假設(shè)冠息,正是容器技術(shù)圈在 Docker 項(xiàng)目成功后不久,就迅速走向了“容器編排”這個(gè)“上層建筑”的主要原因:作為一家云服務(wù)商或者基礎(chǔ)設(shè)施提供商孕索,我只要能夠?qū)⒂脩籼峤坏腄ocker 鏡像以容器的方式運(yùn)行起來逛艰,就能成為這個(gè)非常熱鬧的容器生態(tài)圖上的一個(gè)承載點(diǎn),從而將整個(gè)容器技術(shù)棧上的價(jià)值搞旭,沉淀在我的這個(gè)節(jié)點(diǎn)上散怖。
更重要的是,只要從我這個(gè)承載點(diǎn)向 Docker 鏡像制作者和使用者方向回溯肄渗,整條路徑上的各個(gè)服務(wù)節(jié)點(diǎn)镇眷,比如 CI/CD、監(jiān)控恳啥、安全偏灿、網(wǎng)絡(luò)、存儲(chǔ)等等钝的,都有我可以發(fā)揮和盈利的余地翁垂。這個(gè)邏輯,正是所有云計(jì)算提供商如此熱衷于容器技術(shù)的重要原因:通過容器鏡像硝桩,它們可以和潛在用戶(即沿猜,開發(fā)者)直接關(guān)聯(lián)起來。
從一個(gè)開發(fā)者和單一的容器鏡像碗脊,到無數(shù)開發(fā)者和龐大的容器集群啼肩,容器技術(shù)實(shí)現(xiàn)了從“容器”到“容器云”的飛躍,標(biāo)志著它真正得到了市場(chǎng)和生態(tài)的認(rèn)可。
這樣祈坠,容器就從一個(gè)開發(fā)者手里的小工具害碾,一躍成為了云計(jì)算領(lǐng)域的絕對(duì)主角;而能夠定義容器組織和管理規(guī)范的“容器編排”技術(shù)赦拘,則當(dāng)仁不讓地坐上了容器技術(shù)領(lǐng)域的“頭把交椅”慌随。
這其中,最具代表性的容器編排工具躺同,當(dāng)屬 Docker 公司的Compose+Swarm 組合阁猜,以及Google 與 RedHat 公司共同主導(dǎo)的 Kubernetes 項(xiàng)目。
我在前面介紹容器技術(shù)發(fā)展歷史的四篇預(yù)習(xí)文章中蹋艺,已經(jīng)對(duì)這兩個(gè)開源項(xiàng)目做了詳細(xì)地剖析和評(píng)述剃袍。所以,在今天的這次分享中捎谨,我會(huì)專注于本專欄的主角 Kubernetes 項(xiàng)目民效,談一談它的設(shè)計(jì)與架構(gòu)。
跟很多基礎(chǔ)設(shè)施領(lǐng)域先有工程實(shí)踐侍芝、后有方法論的發(fā)展路線不同研铆,Kubernetes 項(xiàng)目的理論基礎(chǔ)則要比工程實(shí)踐走得靠前得多,這當(dāng)然要?dú)w功于 Google 公司在2015 年 4 月發(fā)布的 Borg 論文了州叠。
Borg 系統(tǒng)棵红,一直以來都被譽(yù)為 Google 公司內(nèi)部最強(qiáng)大的“秘密武器”。雖然略顯夸張咧栗,但這個(gè)說法倒不算是吹牛逆甜。
因?yàn)椋啾扔?Spanner致板、BigTable 等相對(duì)上層的項(xiàng)目交煞,Borg 要承擔(dān)的責(zé)任,是承載Google公司整個(gè)基礎(chǔ)設(shè)施的核心依賴斟或。在 Google 公司已經(jīng)公開發(fā)表的基礎(chǔ)設(shè)施體系論文中素征,Borg 項(xiàng)目當(dāng)仁不讓地位居整個(gè)基礎(chǔ)設(shè)施技術(shù)棧的最底層。
上面這幅圖萝挤,來自于 Google Omega 論文的第一作者的博士畢業(yè)論文御毅。它描繪了當(dāng)時(shí)Google已經(jīng)公開發(fā)表的整個(gè)基礎(chǔ)設(shè)施棧。在這個(gè)圖里怜珍,你既可以找到 MapReduce端蛆、BigTable 等知名項(xiàng)目,也能看到 Borg 和它的繼任者 Omega 位于整個(gè)技術(shù)棧的最底層酥泛。
正是由于這樣的定位今豆,Borg 可以說是 Google 最不可能開源的一個(gè)項(xiàng)目嫌拣。而幸運(yùn)地是,得益于Docker 項(xiàng)目和容器技術(shù)的風(fēng)靡呆躲,它卻終于得以以另一種方式與開源社區(qū)見面异逐,這個(gè)方式就是Kubernetes 項(xiàng)目。
所以歼秽,相比于“小打小鬧”的 Docker 公司应役、“舊瓶裝新酒”的Mesos 社區(qū),Kubernetes 項(xiàng)目從一開始就比較幸運(yùn)地站上了一個(gè)他人難以企及的高度:在它的成長階段燥筷,這個(gè)項(xiàng)目每一個(gè)核心特性的提出,幾乎都脫胎于 Borg/Omega 系統(tǒng)的設(shè)計(jì)與經(jīng)驗(yàn)院崇。更重要的是肆氓,這些特性在開源社區(qū)落地的過程中,又在整個(gè)社區(qū)的合力之下得到了極大的改進(jìn)底瓣,修復(fù)了很多當(dāng)年遺留在Borg體系中的缺陷和問題谢揪。
所以,盡管在發(fā)布之初被批評(píng)是“曲高和寡”捐凭,但是在逐漸覺察到 Docker 技術(shù)棧的“稚嫩”和Mesos 社區(qū)的“老邁”之后拨扶,這個(gè)社區(qū)很快就明白了:Kubernetes 項(xiàng)目在 Borg 體系的指導(dǎo)下,體現(xiàn)出了一種獨(dú)有的“先進(jìn)性”與“完備性”茁肠,而這些特質(zhì)才是一個(gè)基礎(chǔ)設(shè)施領(lǐng)域開源項(xiàng)目賴以生存的核心價(jià)值患民。
為了更好地理解這兩種特質(zhì),我們不妨從 Kubernetes 的頂層設(shè)計(jì)說起垦梆。
首先匹颤,Kubernetes 項(xiàng)目要解決的問題是什么?
編排托猩?調(diào)度印蓖?容器云?還是集群管理京腥?
實(shí)際上赦肃,這個(gè)問題到目前為止都沒有固定的答案。因?yàn)樵诓煌陌l(fā)展階段公浪,Kubernetes 需要著重解決的問題是不同的他宛。
但是,對(duì)于大多數(shù)用戶來說因悲,他們希望 Kubernetes 項(xiàng)目帶來的體驗(yàn)是確定的:現(xiàn)在我有了應(yīng)用的容器鏡像堕汞,請(qǐng)幫我在一個(gè)給定的集群上把這個(gè)應(yīng)用運(yùn)行起來。
更進(jìn)一步地說晃琳,我還希望 Kubernetes 能給我提供路由網(wǎng)關(guān)讯检、水平擴(kuò)展人灼、監(jiān)控奈泪、備份涝桅、災(zāi)難恢復(fù)等一系列運(yùn)維能力冯遂。
等一下,這些功能聽起來好像有些耳熟裸准?這不就是經(jīng)典 PaaS(比如炒俱,Cloud Foundry)項(xiàng)目的能力嗎?
而且僵芹,有了 Docker 之后拇派,我根本不需要什么Kubernetes、PaaS茧彤,只要使用 Docker 公司的Compose+Swarm 項(xiàng)目曾掂,就完全可以很方便地 DIY 出這些功能了溜歪!
所以說蝴猪,如果 Kubernetes 項(xiàng)目只是停留在拉取用戶鏡像、運(yùn)行容器动壤,以及提供常見的運(yùn)維功能的話,那么別說跟“原生”的 Docker Swarm 項(xiàng)目競(jìng)爭(zhēng)了爬早,哪怕跟經(jīng)典的 PaaS 項(xiàng)目相比也難有什么優(yōu)勢(shì)可言。
而實(shí)際上桨啃,在定義核心功能的過程中照瘾,Kubernetes 項(xiàng)目正是依托著 Borg 項(xiàng)目的理論優(yōu)勢(shì)析命,才在短短幾個(gè)月內(nèi)迅速站穩(wěn)了腳跟,進(jìn)而確定了一個(gè)如下圖所示的全局架構(gòu):
我們可以看到,Kubernetes 項(xiàng)目的架構(gòu)凹耙,跟它的原型項(xiàng)目Borg 非常類似,都由 Master 和Node 兩種節(jié)點(diǎn)組成建钥,而這兩種角色分別對(duì)應(yīng)著控制節(jié)點(diǎn)和計(jì)算節(jié)點(diǎn)。
其中镐依,控制節(jié)點(diǎn)槐壳,即 Master 節(jié)點(diǎn),由三個(gè)緊密協(xié)作的獨(dú)立組件組合而成带兜,它們分別是負(fù)責(zé)API服務(wù)的 kube-apiserver刑巧、負(fù)責(zé)調(diào)度的kube-scheduler,以及負(fù)責(zé)容器編排的kube-controller-manager浑彰。整個(gè)集群的持久化數(shù)據(jù)蚯斯,則由 kube-apiserver 處理后保存在 Ectd 中拍嵌。
而計(jì)算節(jié)點(diǎn)上最核心的部分,則是一個(gè)叫作 kubelet 的組件狈蚤。
在 Kubernetes 項(xiàng)目中锌畸,kubelet 主要負(fù)責(zé)同容器運(yùn)行時(shí)(比如 Docker 項(xiàng)目)打交道潭枣。而這個(gè)交互所依賴的盆犁,是一個(gè)稱作 CRI(Container Runtime Interface)的遠(yuǎn)程調(diào)用接口,這個(gè)接口定義了容器運(yùn)行時(shí)的各項(xiàng)核心操作伊佃,比如:啟動(dòng)一個(gè)容器需要的所有參數(shù)沛善。
這也是為何,Kubernetes 項(xiàng)目并不關(guān)心你部署的是什么容器運(yùn)行時(shí)胀葱、使用的什么技術(shù)實(shí)現(xiàn),只要你的這個(gè)容器運(yùn)行時(shí)能夠運(yùn)行標(biāo)準(zhǔn)的容器鏡像轧葛,它就可以通過實(shí)現(xiàn) CRI 接入到Kubernetes項(xiàng)目當(dāng)中尿扯。
而具體的容器運(yùn)行時(shí),比如 Docker 項(xiàng)目辟宗,則一般通過 OCI 這個(gè)容器運(yùn)行時(shí)規(guī)范同底層的Linux 操作系統(tǒng)進(jìn)行交互空幻,即:把 CRI 請(qǐng)求翻譯成對(duì) Linux 操作系統(tǒng)的調(diào)用(操作Linux Namespace 和 Cgroups 等)秕铛。
此外,kubelet 還通過 gRPC 協(xié)議同一個(gè)叫作 Device Plugin 的插件進(jìn)行交互镜遣。這個(gè)插件,是Kubernetes 項(xiàng)目用來管理 GPU 等宿主機(jī)物理設(shè)備的主要組件寓辱,也是基于Kubernetes 項(xiàng)目進(jìn)行機(jī)器學(xué)習(xí)訓(xùn)練、高性能作業(yè)支持等工作必須關(guān)注的功能这敬。
而kubelet 的另一個(gè)重要功能崔涂,則是調(diào)用網(wǎng)絡(luò)插件和存儲(chǔ)插件為容器配置網(wǎng)絡(luò)和持久化存儲(chǔ)。這兩個(gè)插件與 kubelet 進(jìn)行交互的接口汛闸,分別是 CNI(Container Networking Interface)和CSI(Container Storage Interface)尸闸。
實(shí)際上,kubelet 這個(gè)奇怪的名字宙址,來自于 Borg 項(xiàng)目里的同源組件 Borglet。不過注益,如果你瀏覽過 Borg 論文的話,就會(huì)發(fā)現(xiàn)啤月,這個(gè)命名方式可能是kubelet 組件與 Borglet 組件的唯一相似之處劳跃。因?yàn)?Borg 項(xiàng)目谎仲,并不支持我們這里所講的容器技術(shù),而只是簡單地使用了Linux Cgroups 對(duì)進(jìn)程進(jìn)行限制刨仑。
這就意味著郑诺,像 Docker 這樣的“容器鏡像”在 Borg 中是不存在的,Borglet 組件也自然不需要像 kubelet 這樣考慮如何同 Docker 進(jìn)行交互杉武、如何對(duì)容器鏡像進(jìn)行管理的問題间景,也不需要支持 CRI十拣、CNI缰趋、CSI 等諸多容器技術(shù)接口仔涩。
可以說晰骑,kubelet 完全就是為了實(shí)現(xiàn) Kubernetes 項(xiàng)目對(duì)容器的管理能力而重新實(shí)現(xiàn)的一個(gè)組件蚂会,與 Borg 之間并沒有直接的傳承關(guān)系娱挨。
? ? ? ?備注:雖然不使用 Docker淮韭,但 Google 內(nèi)部確實(shí)在使用一個(gè)包管理工具占键,名叫Midas Package Manager (MPM),其實(shí)它可以部分取代 Docker 鏡像的角色皮服。
那么,Borg 對(duì)于 Kubernetes 項(xiàng)目的指導(dǎo)作用又體現(xiàn)在哪里呢紧武?
答案是,Master 節(jié)點(diǎn)禾怠。
雖然在 Master 節(jié)點(diǎn)的實(shí)現(xiàn)細(xì)節(jié)上 Borg 項(xiàng)目與 Kubernetes 項(xiàng)目不盡相同膀哲,但它們的出發(fā)點(diǎn)卻高度一致,即:如何編排云矫、管理、調(diào)度用戶提交的作業(yè)?
所以极舔,Borg 項(xiàng)目完全可以把 Docker 鏡像看做是一種新的應(yīng)用打包方式揪胃。這樣,Borg 團(tuán)隊(duì)過去在大規(guī)模作業(yè)管理與編排上的經(jīng)驗(yàn)就可以直接“套”在 Kubernetes 項(xiàng)目上了。
這些經(jīng)驗(yàn)最主要的表現(xiàn)就是捌年,從一開始褒颈,Kubernetes 項(xiàng)目就沒有像同時(shí)期的各種“容器云”項(xiàng)目那樣币狠,把 Docker 作為整個(gè)架構(gòu)的核心凳兵,而僅僅把它作為最底層的一個(gè)容器運(yùn)行時(shí)實(shí)現(xiàn)百新。
而 Kubernetes 項(xiàng)目要著重解決的問題,則來自于 Borg的研究人員在論文中提到的一個(gè)非常重要的觀點(diǎn):
運(yùn)行在大規(guī)模集群中的各種任務(wù)之間留荔,實(shí)際上存在著各種各樣的關(guān)系吟孙。這些關(guān)系的處理,才是作業(yè)編排和管理系統(tǒng)最困難的地方聚蝶。
事實(shí)也正是如此杰妓。
其實(shí),這種任務(wù)與任務(wù)之間的關(guān)系碘勉,在我們平常的各種技術(shù)場(chǎng)景中隨處可見巷挥。比如,一個(gè)Web應(yīng)用與數(shù)據(jù)庫之間的訪問關(guān)系验靡,一個(gè)負(fù)載均衡器和它的后端服務(wù)之間的代理關(guān)系倍宾,一個(gè)門戶應(yīng)用與授權(quán)組件之間的調(diào)用關(guān)系雏节。
更進(jìn)一步地說,同屬于一個(gè)服務(wù)單位的不同功能之間高职,也完全可能存在這樣的關(guān)系钩乍。比如,一個(gè)Web 應(yīng)用與日志搜集組件之間的文件交換關(guān)系怔锌。
而在容器技術(shù)普及之前寥粹,傳統(tǒng)虛擬機(jī)環(huán)境對(duì)這種關(guān)系的處理方法都是比較“粗粒度”的。你會(huì)經(jīng)常發(fā)現(xiàn)很多功能并不相關(guān)的應(yīng)用被一股腦兒地部署在同一臺(tái)虛擬機(jī)中埃元,只是因?yàn)樗鼈冎g偶爾會(huì)互相發(fā)起幾個(gè) HTTP 請(qǐng)求涝涤。
更常見的情況則是,一個(gè)應(yīng)用被部署在虛擬機(jī)里之后岛杀,你還得手動(dòng)維護(hù)很多跟它協(xié)作的守護(hù)進(jìn)程(Daemon)阔拳,用來處理它的日志搜集、災(zāi)難恢復(fù)类嗤、數(shù)據(jù)備份等輔助工作糊肠。
但容器技術(shù)出現(xiàn)以后,你就不難發(fā)現(xiàn)遗锣,在“功能單位”的劃分上罪针,容器有著獨(dú)一無二的“細(xì)粒度”優(yōu)勢(shì):畢竟容器的本質(zhì),只是一個(gè)進(jìn)程而已黄伊。
也就是說泪酱,只要你愿意,那些原先擁擠在同一個(gè)虛擬機(jī)里的各個(gè)應(yīng)用还最、組件墓阀、守護(hù)進(jìn)程,都可以被分別做成鏡像拓轻,然后運(yùn)行在一個(gè)個(gè)專屬的容器中斯撮。它們之間互不干涉,擁有各自的資源配額扶叉,可以被調(diào)度在整個(gè)集群里的任何一臺(tái)機(jī)器上勿锅。而這,正是一個(gè) PaaS 系統(tǒng)最理想的工作狀態(tài)枣氧,也是所謂“微服務(wù)”思想得以落地的先決條件溢十。
當(dāng)然,如果只做到“封裝微服務(wù)达吞、調(diào)度單容器”這一層次张弛,Docker Swarm 項(xiàng)目就已經(jīng)綽綽有余了。如果再加上 Compose 項(xiàng)目,你甚至還具備了處理一些簡單依賴關(guān)系的能力吞鸭,比如:一個(gè)“Web 容器”和它要訪問的數(shù)據(jù)庫“DB 容器”寺董。
在 Compose 項(xiàng)目中,你可以為這樣的兩個(gè)容器定義一個(gè)“l(fā)ink”刻剥,而 Docker 項(xiàng)目則會(huì)負(fù)責(zé)維護(hù)這個(gè)“l(fā)ink”關(guān)系遮咖,其具體做法是:Docker 會(huì)在 Web 容器中,將 DB 容器的 IP地址造虏、端口等信息以環(huán)境變量的方式注入進(jìn)去盯滚,供應(yīng)用進(jìn)程使用,比如:
DB_NAME=/web/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
DB_PORT_5432_TCP_PROTO=tcp
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_ADDR=172.17.0.5
而當(dāng) DB 容器發(fā)生變化時(shí)(比如酗电,鏡像更新,被遷移到其他宿主機(jī)上等等)内列,這些環(huán)境變量的值會(huì)由 Docker 項(xiàng)目自動(dòng)更新撵术。這就是平臺(tái)項(xiàng)目自動(dòng)地處理容器間關(guān)系的典型例子。
可是话瞧,如果我們現(xiàn)在的需求是嫩与,要求這個(gè)項(xiàng)目能夠處理前面提到的所有類型的關(guān)系,甚至還要能夠支持未來可能出現(xiàn)的更多種類的關(guān)系呢交排?
這時(shí)划滋,“l(fā)ink”這種單獨(dú)針對(duì)一種案例設(shè)計(jì)的解決方案就太過簡單了。如果你做過架構(gòu)方面的工作埃篓,就會(huì)深有感觸:一旦要追求項(xiàng)目的普適性处坪,那就一定要從頂層開始做好設(shè)計(jì)。
所以架专,Kubernetes 項(xiàng)目最主要的設(shè)計(jì)思想是同窘,從更宏觀的角度,以統(tǒng)一的方式來定義任務(wù)之間的各種關(guān)系部脚,并且為將來支持更多種類的關(guān)系留有余地想邦。
比如,Kubernetes 項(xiàng)目對(duì)容器間的“訪問”進(jìn)行了分類委刘,首先總結(jié)出了一類非常常見的“緊密交互”的關(guān)系丧没,即:這些應(yīng)用之間需要非常頻繁的交互和訪問;又或者锡移,它們會(huì)直接通過本地文件進(jìn)行信息交換呕童。
在常規(guī)環(huán)境下,這些應(yīng)用往往會(huì)被直接部署在同一臺(tái)機(jī)器上淆珊,通過 Localhost 通信拉庵,通過本地磁盤目錄交換文件。而在 Kubernetes 項(xiàng)目中,這些容器則會(huì)被劃分為一個(gè)“Pod”钞支,Pod 里的容器共享同一個(gè) Network Namespace茫蛹、同一組數(shù)據(jù)卷,從而達(dá)到高效率交換信息的目的烁挟。
Pod 是 Kubernetes 項(xiàng)目中最基礎(chǔ)的一個(gè)對(duì)象婴洼,源自于Google Borg 論文中一個(gè)名叫 Alloc 的設(shè)計(jì)。在后續(xù)的章節(jié)中撼嗓,我們會(huì)對(duì) Pod 做更進(jìn)一步地闡述柬采。
而對(duì)于另外一種更為常見的需求,比如 Web 應(yīng)用與數(shù)據(jù)庫之間的訪問關(guān)系且警,Kubernetes 項(xiàng)目則提供了一種叫作“Service”的服務(wù)粉捻。像這樣的兩個(gè)應(yīng)用,往往故意不部署在同一臺(tái)機(jī)器上斑芜,這樣即使 Web 應(yīng)用所在的機(jī)器宕機(jī)了肩刃,數(shù)據(jù)庫也完全不受影響⌒油罚可是盈包,我們知道,對(duì)于一個(gè)容器來說醇王,它的 IP 地址等信息不是固定的呢燥,那么 Web 應(yīng)用又怎么找到數(shù)據(jù)庫容器的 Pod 呢?
所以寓娩,Kubernetes 項(xiàng)目的做法是給 Pod 綁定一個(gè) Service 服務(wù)叛氨,而 Service 服務(wù)聲明的 IP 地址等信息是“終生不變”的。這個(gè)Service 服務(wù)的主要作用棘伴,就是作為 Pod 的代理入口(Portal)力试,從而代替 Pod 對(duì)外暴露一個(gè)固定的網(wǎng)絡(luò)地址。
這樣排嫌,對(duì)于 Web 應(yīng)用的 Pod 來說畸裳,它需要關(guān)心的就是數(shù)據(jù)庫 Pod 的 Service 信息。不難想象淳地,Service 后端真正代理的 Pod 的 IP 地址怖糊、端口等信息的自動(dòng)更新、維護(hù)颇象,則是Kubernetes 項(xiàng)目的職責(zé)伍伤。
像這樣,圍繞著容器和 Pod 不斷向真實(shí)的技術(shù)場(chǎng)景擴(kuò)展遣钳,我們就能夠摸索出一幅如下所示的Kubernetes 項(xiàng)目核心功能的“全景圖”扰魂。
按照這幅圖的線索,我們從容器這個(gè)最基礎(chǔ)的概念出發(fā),首先遇到了容器間“緊密協(xié)作”關(guān)系的難題劝评,于是就擴(kuò)展到了 Pod姐直;有了 Pod 之后,我們希望能一次啟動(dòng)多個(gè)應(yīng)用的實(shí)例蒋畜,這樣就需要 Deployment 這個(gè) Pod 的多實(shí)例管理器声畏;而有了這樣一組相同的 Pod 后,我們又需要通過一個(gè)固定的 IP 地址和端口以負(fù)載均衡的方式訪問它姻成,于是就有了Service插龄。
可是,如果現(xiàn)在兩個(gè)不同 Pod 之間不僅有“訪問關(guān)系”科展,還要求在發(fā)起時(shí)加上授權(quán)信息均牢。最典型的例子就是 Web 應(yīng)用對(duì)數(shù)據(jù)庫訪問時(shí)需要 Credential(數(shù)據(jù)庫的用戶名和密碼)信息。那么才睹,在 Kubernetes 中這樣的關(guān)系又如何處理呢徘跪?
Kubernetes 項(xiàng)目提供了一種叫作 Secret 的對(duì)象,它其實(shí)是一個(gè)保存在Etcd 里的鍵值對(duì)數(shù)據(jù)砂竖。這樣,你把 Credential 信息以 Secret 的方式存在 Etcd 里鹃答,Kubernetes 就會(huì)在你指定的Pod(比如乎澄,Web 應(yīng)用的 Pod)啟動(dòng)時(shí),自動(dòng)把 Secret 里的數(shù)據(jù)以 Volume 的方式掛載到容器里测摔。這樣置济,這個(gè) Web 應(yīng)用就可以訪問數(shù)據(jù)庫了。
除了應(yīng)用與應(yīng)用之間的關(guān)系外锋八,應(yīng)用運(yùn)行的形態(tài)是影響“如何容器化這個(gè)應(yīng)用”的第二個(gè)重要因素浙于。
為此,Kubernetes 定義了新的挟纱、基于 Pod 改進(jìn)后的對(duì)象羞酗。比如 Job,用來描述一次性運(yùn)行的Pod(比如紊服,大數(shù)據(jù)任務(wù))檀轨;再比如 DaemonSet,用來描述每個(gè)宿主機(jī)上必須且只能運(yùn)行一個(gè)副本的守護(hù)進(jìn)程服務(wù)欺嗤;又比如 CronJob参萄,則用于描述定時(shí)任務(wù)等等。
如此種種煎饼,正是 Kubernetes 項(xiàng)目定義容器間寫關(guān)留系言和形態(tài)的主要方法讹挎。
可以看到,Kubernetes 項(xiàng)目并沒有像其他項(xiàng)目那樣,為每一個(gè)管理功能創(chuàng)建一個(gè)指令筒溃,然后在項(xiàng)目中實(shí)現(xiàn)其中的邏輯马篮。這種做法,的確可以解決當(dāng)前的問題铡羡,但是在更多的問題來臨之后积蔚,往往會(huì)力不從心。
相比之下烦周,在 Kubernetes 項(xiàng)目中尽爆,我們所推崇的使用方法是:
* 首先,通過一個(gè)“編排對(duì)象”读慎,比如 Pod漱贱、Job、CronJob 等夭委,來描述你試圖管理的應(yīng)用幅狮;
* 然后,再為它定義一些“服務(wù)對(duì)象”株灸,比如 Service崇摄、Secret、Horizontal Pod Autoscaler(自動(dòng)水平擴(kuò)展器)等慌烧。這些對(duì)象逐抑,會(huì)負(fù)責(zé)具體的平臺(tái)級(jí)功能。
這種使用方法屹蚊,就是所謂的“聲明式 API”厕氨。這種 API 對(duì)應(yīng)的“編排對(duì)象”和“服務(wù)對(duì)象”,都是 Kubernetes 項(xiàng)目中的 API 對(duì)象(API Object)汹粤。
這就是 Kubernetes 最核心的設(shè)計(jì)理念命斧,也是接下來我會(huì)重點(diǎn)剖析的關(guān)鍵技術(shù)點(diǎn)。
最后嘱兼,我來回答一個(gè)更直接的問題:Kubernetes 項(xiàng)目如何啟動(dòng)一個(gè)容器化任務(wù)呢国葬?
比如,我現(xiàn)在已經(jīng)制作好了一個(gè) Nginx 容器鏡像芹壕,希望讓平臺(tái)幫我啟動(dòng)這個(gè)鏡像胃惜。并且飞醉,我要求平臺(tái)幫我運(yùn)行兩個(gè)完全相同的 Nginx 副本绊困,以負(fù)載均衡的方式共同對(duì)外提供服務(wù)。
* 如果是自己 DIY 的話炕桨,可能需要啟動(dòng)兩臺(tái)虛擬機(jī)斯嚎,分別安裝兩個(gè)Nginx利虫,然后使用keepalived 為這兩個(gè)虛擬機(jī)做一個(gè)虛擬 IP挨厚。
* 而如果使用 Kubernetes 項(xiàng)目呢?你需要做的則是編寫如下這樣一個(gè) YAML 文件(比如名叫nginx-deployment.yaml):
apiVersion:apps/v1
kind:Deployment
metadata:
? ? ? name:nginx-deployment
? ? ? labels:
? ? ? app: nginx
spec:
? ? ? replicas: 2
? ? ? selector:
? ? ? ? ? matchLabels:
? ? ? ? ? ? ? ? app: nginx
? ? ? ?template:
? ? ? ? ? ? ?metadata:
? ? ? ? ? ? ? ? labels:
? ? ? ? ? ? ? ? ? ? ?app: nginx
? ? ? ? ? ? ?spec:
? ? ? ? ? ? ? ? ?containers:
? ? ? ? ? ? ? ? ?- name: nginx
? ? ? ? ? ? ? ? ? ?image:nginx:1.7.9
? ? ? ? ? ? ? ? ? ?ports:
? ? ? ? ? ? ? ? ? ?-containerPort: 80
在上面這個(gè) YAML 文件中糠惫,我們定義了一個(gè) Deployment對(duì)象疫剃,它的主體部分(spec.template 部分)是一個(gè)使用 Nginx 鏡像的 Pod,而這個(gè) Pod 的副本數(shù)是2(replicas=2)硼讽。
然后執(zhí)行:
$ kubectlcreate -f nginx-deployment.yaml
這樣巢价,兩個(gè)完全相同的 Nginx 容器副本就被啟動(dòng)了。
不過固阁,這么看來壤躲,做同樣一件事情,Kubernetes 用戶要做的工作也不少嘛备燃。
別急碉克,在后續(xù)的講解中,我會(huì)陸續(xù)介紹 Kubernetes 項(xiàng)目這種“聲明式 API”的種種好處并齐,以及基于它實(shí)現(xiàn)的強(qiáng)大的編排能力漏麦。
拭目以待吧。
總結(jié)
首先况褪,我和你一起回顧了容器的核心知識(shí)撕贞,說明了容器其實(shí)可以分為兩個(gè)部分:容器運(yùn)行時(shí)和容器鏡像。
然后测垛,我重點(diǎn)介紹了 Kubernetes 項(xiàng)目的架構(gòu)捏膨,詳細(xì)講解了它如何使用“聲明式 API”來描述容器化業(yè)務(wù)和容器間關(guān)系的設(shè)計(jì)思想。
實(shí)際上赐纱,過去很多的集群管理項(xiàng)目(比如 Yarn脊奋、Mesos熬北,以及 Swarm)所擅長的疙描,都是把一個(gè)容器,按照某種規(guī)則讶隐,放置在某個(gè)最佳節(jié)點(diǎn)上運(yùn)行起來起胰。這種功能,我們稱為“調(diào)度”巫延。
而 Kubernetes 項(xiàng)目所擅長的效五,是按照用戶的意愿和整個(gè)系統(tǒng)的規(guī)則,完全自動(dòng)化地處理好容器之間的各種關(guān)系炉峰。這種功能畏妖,就是我們經(jīng)常聽到的一個(gè)概念:編排。
所以說疼阔,Kubernetes 項(xiàng)目的本質(zhì)戒劫,是為用戶提供一個(gè)具有普遍意義的容器編排工具半夷。
不過,更重要的是迅细,Kubernetes 項(xiàng)目為用戶提供的不僅限于一個(gè)工具巫橄。它真正的價(jià)值,乃在于提供了一套基于容器構(gòu)建分布式系統(tǒng)的基礎(chǔ)依賴茵典。關(guān)于這一點(diǎn)湘换,相信你會(huì)在今后的學(xué)習(xí)中,體會(huì)的越來越深统阿。
思考題
1. 這今天的分享中彩倚,我介紹了 Kubernetes 項(xiàng)目的架構(gòu)。你是否了解了Docker Swarm(SwarmKit 項(xiàng)目)跟 Kubernetes 在架構(gòu)上和使用方法上的異同呢砂吞?
2. 在 Kubernetes 之前署恍,很多項(xiàng)目都沒辦法管理“有狀態(tài)”的容器,即蜻直,不能從一臺(tái)宿主機(jī)“遷移”到另一臺(tái)宿主機(jī)上的容器盯质。你是否能列舉出,阻止這種“遷移”的原因都有哪些呢概而?
感謝你的收聽呼巷,歡迎你給我留言。
文章回復(fù):
Geek_zz
對(duì)這個(gè)專欄看的越多赎瑰,越覺得作者講得有條理又有深度王悍,物超超超所值
2018-09-12
hugeo
學(xué)費(fèi)太值得了,老師太會(huì)教課了說得很清楚
2018-09-12
Jeff.W
從微服務(wù)架構(gòu)來講餐曼,多個(gè)獨(dú)立功能內(nèi)聚的服務(wù)帶來了整體的靈活性压储,但是同時(shí)也帶來了部署運(yùn)維的復(fù)雜度提升,這時(shí)Docker配合Devops帶來了不少的便利(輕量源譬、隔離集惋、一致性、CI踩娘、CD等)解決了不少問題刮刑,再配合compose,看起來一切都很美了养渴,為什么還需要K8s雷绢?可以試著這樣理解么?把微服務(wù)理解為人理卑,那么服務(wù)治理其實(shí)就是人之間的溝通而已翘紊,人太多了就需要生存空間和溝通方式的優(yōu)化,這就需要集群和編排了藐唠。Docker Compose帆疟,swarm孵滞,可以解決少數(shù)人之間的關(guān)系,比如把手機(jī)號(hào)給你鸯匹,你就可以方便的找到我坊饶,但是如果手機(jī)號(hào)變更的時(shí)候就會(huì)麻煩,人多了也會(huì)麻煩殴蓬。而k8s是站在上帝視角俯視蕓蕓眾生后的高度抽象匿级,他看到了大概有哪些類人(組織)以及不同組織有什么樣的特點(diǎn)(Job、CornJob染厅、Autoscaler痘绎、StatefulSet、DaemonSet...)肖粮,不同組織之間交流可能需要什么(ConfigMap,Secret...),這樣比價(jià)緊密的人們?cè)谙嗤琾od中孤页,通過Service-不會(huì)變更的手機(jī)號(hào),來和不同的組織進(jìn)行溝通涩馆,Deployment行施、RC則可以幫組人們快速構(gòu)建組織。Dokcer 后出的swarm mode魂那,有類似的視角抽象(比如Service)蛾号,不過相對(duì)來說并不完善。以上涯雅,是否可以這樣理解鲜结?
2018-09-16
作者回復(fù)
沒毛病
2018-09-16
Xiye
對(duì)于第二個(gè)問題,是不是像存儲(chǔ)在文件或者數(shù)據(jù)庫里的數(shù)據(jù)還是比較好遷移活逆,但是對(duì)于緩存精刷,臨時(shí)存儲(chǔ)的數(shù)據(jù)是不是就不太好遷移。
2018-09-12
作者回復(fù)
沒錯(cuò)蔗候!
2018-09-13
huan
1 我自己用swarm后怒允,感覺和docker 公司的整體風(fēng)格很一致:上手簡單,但是最后還是沒用的很好琴庵,因?yàn)楫吘剐枰嗟囊蕾囆枰诓煌萜髦g傳遞误算。k8s從更高視野看服務(wù)器軟件架構(gòu)從而提出更有效而且看起來更重的方案仰美,最終被證明是有效的迷殿。
2018-09-12
Tigerfive
感覺不能遷移“有狀態(tài)”的容器,是因?yàn)檫w移的是容器的rootfs咖杂,但是一些動(dòng)態(tài)視圖是沒有辦法伴隨遷移一同進(jìn)行遷移的庆寺。
2018-09-12
作者回復(fù)
是的,到目前為止诉字,遷移都是做不到的懦尝,只能刪除后在新的節(jié)點(diǎn)上重新創(chuàng)建
2018-09-12
pytimer
第二個(gè)問題: 我覺得應(yīng)該是很多容器數(shù)據(jù)都是掛載在本地路徑知纷,所以沒辦法直接進(jìn)行遷移。如果容器的數(shù)據(jù)掛載在共享存儲(chǔ)上陵霉,那是不是沒有kubernetes也是可以遷移有狀態(tài)的容器琅轧?
2018-09-12
作者回復(fù)
那就要看有多少種狀態(tài)需要處理啦
2018-09-12
Scott
為什么一個(gè)node上,kubelet與Device plugin要走gRPC踊挠,這個(gè)沒有CSI這樣的專門中間層嗎乍桂?
2018-09-16
作者回復(fù)
沒有,這一塊的設(shè)計(jì)我后面會(huì)講到
2018-09-17
骨湯雞蛋面
一直對(duì)CNI效床、CSI 有點(diǎn)困惑睹酌,為什么不將其納入到container runtime/oci 的范疇?
2018-09-13
作者回復(fù)
前面是paas層用的剩檀,后面是容器用的
2018-09-13
sprzhing
不能遷移是因?yàn)槿萜髟诒镜氐暮芏酄顟B(tài)修改不會(huì)commit到云端吧憋沿?
2018-09-12
silver
為什么說mesos是老邁和舊瓶裝新酒呢?Mesos本身所做的事情是有限的沪猴,很大一部分取決于它的scheduler,談?wù)搈esos不是很大一方面取決于scheduler么
2018-09-17
作者回復(fù)
mesos是舊瓶辐啄,marathon是新酒
2018-09-17
Gao
面向yaml文件編程
2018-09-16
Rod
@老師。我記得service的ip也是可變的运嗜。不變的是service name则披。通過kube dns解析。當(dāng)然service可以綁定主機(jī)名洗出。但是那樣就不能高可用士复。不知道我說的對(duì)不對(duì)?
2018-09-13
作者回復(fù)
service vip不會(huì)變翩活,除非你把它刪了重建阱洪。通過dns解析的是headless service,它不會(huì)分配vip菠镇。
2018-09-13
每日都想上班
我們單位正在使用k8s冗荸,很棒的課程,聽了后理解更加深入
2018-09-13
阿碩
整個(gè)集群的持久化數(shù)據(jù)利耍,則由 kube-apiserver 處理后保存在 Ectd 中蚌本。是不是Etcd呢?
2018-09-12
作者回復(fù)
對(duì)對(duì)
2018-09-13
天下
沒法遷移是不能方便解決相互之間的依賴隘梨,耦合度高的程癌,隨著項(xiàng)目的變大各種依賴會(huì)讓人崩潰。
2018-09-12
天勤
講的很透徹轴猎,物超所值嵌莉!
2018-09-26
Gmc2
精彩!
2018-09-25
kyleqian
之前用過HTCondor這樣的老牌調(diào)度系統(tǒng)捻脖,專注任務(wù)調(diào)度和依賴關(guān)系處理锐峭,咋一看和k8s有很多功能重疊(也能調(diào)度容器)中鼠。但感覺k8s結(jié)合容器更好地處理了打包、編排和擴(kuò)展性等問題沿癞,是開發(fā)運(yùn)維一體化的利器援雇,上層的應(yīng)用不用太關(guān)注底層基礎(chǔ)設(shè)施的變化,和這類傳統(tǒng)調(diào)度系統(tǒng)的關(guān)注點(diǎn)不在一個(gè)層次椎扬。
2018-09-25
作者回復(fù)
沒錯(cuò)熊杨,正是編排和調(diào)度的區(qū)別
2018-09-25
龍坤
容器OCI規(guī)范推出,那么統(tǒng)一規(guī)范的容器鏡像都可以在不同廠商自主研發(fā)的容器運(yùn)行時(shí)上運(yùn)行盗舰。隨著時(shí)間的推進(jìn)晶府,在容器編排上的需求,雖然有swarm和mesos的方案钻趋,但是對(duì)于一些有能力做基于容器PaaS平臺(tái)的大公司川陆,并且還有一些具有自主研發(fā)能力、野心大和具有一定PaaS平臺(tái)資源的蛮位,并想借用容器賺錢的大公司较沪,就不太樂意用這些方案(所以為什么大公司前期都迫切需要一個(gè)容器規(guī)范出現(xiàn)的原因吧)。這時(shí)也迫切需要一個(gè)可以對(duì)接自主研發(fā)的“運(yùn)行時(shí)”的工具出來失仁,并該工具能彌補(bǔ)容器編排不完美這個(gè)缺陷尸曼。個(gè)人覺得,Kubernetes的出現(xiàn)確實(shí)偉大萄焦,偉大到擊垮Docker公司原先建立的都圍著他轉(zhuǎn)的容器社區(qū)體系控轿,也偉大到可以又讓大公司賺錢。 --- 純屬個(gè)人理解
2018-09-22
作者回復(fù)
開源和商業(yè)不分家
2018-09-22
一帆
贊
2018-09-21
LiJiao
遷移可以簡單分為兩類:磁盤數(shù)據(jù)文件不變拂封,進(jìn)程重啟茬射;磁盤數(shù)據(jù)文件不變、內(nèi)存數(shù)據(jù)也不變冒签,相當(dāng)于連帶進(jìn)程一起挪過去在抛。第一種類型有很簡單的方法:掛載云盤,從空間上解耦萧恕。第二種類型就復(fù)雜了刚梭,需要將內(nèi)存數(shù)據(jù)一點(diǎn)點(diǎn)遷移過去,最后瞬間切換票唆。IaaS很早就應(yīng)用熱遷移技術(shù)了朴读。
Kubernetes則討巧了,只著眼于應(yīng)用惰说,直接約定容器是可以隨時(shí)被殺死的磨德,熱遷移就沒有那么重要了缘回。甚至連IP都隱藏了吆视,又繞過了一個(gè)大難題~
2018-09-21
zoroyouxi
專欄寫的太好了典挑,深入淺出,理解不難啦吧,但能組織好語言這么娓娓道來可知作者在這方面的功力您觉,即使接觸k8s有一段時(shí)間了也會(huì)有所啟發(fā),厲害??
2018-09-20
Hunsbiously
如果可能授滓,希望能夠講解一下這個(gè)視頻的內(nèi)容琳水。https://m.youtube.com/watch?v=ER9eIXL2_14#fauxfullscreen
2018-09-19
silverhawk
寫的很好,謝謝般堆。如果我現(xiàn)在有一個(gè)service已經(jīng)被打包成pod用k8s管理在孝,這個(gè)service對(duì)每個(gè)request需要查詢外部一個(gè)k,v store,那么現(xiàn)在想把這個(gè)k,v store比如redis也做成pod淮摔,是做到一個(gè)pod里面私沮,還是service這樣比較合適,聽起來好像做成service和橙,兩者之間還是繼續(xù)用GRPC仔燕?
2018-09-15
作者回復(fù)
對(duì),兩個(gè)分開的
we
老師魔招,問下pod和job 到底是關(guān)系晰搀? 我沒有懂呢
2018-09-14
作者回復(fù)
job是pod的管理器,后面會(huì)細(xì)講
2018-09-14
他說風(fēng)雨中
老師您好办斑,很喜歡看您的文章外恕,文采也很好,想問您一個(gè)問題乡翅,kubernetes1.10beta介紹的時(shí)候吁讨,在說到對(duì)cpu的支持的時(shí)候,只是一筆帶過峦朗,想問一下您kubernetes1.10對(duì)cpu到底支持到什么程度呢
2018-09-13
作者回復(fù)
cpuset cpushare都支持
2018-09-13
陳華
更新的太慢了迫不及待了建丧,
2018-09-13
燕嶺聽濤
終于跟上進(jìn)度了,清晰了好多
2018-09-13
李宏博
非常感謝波势,受益匪淺
2018-09-13
徐海浪
2: Kubernetes 項(xiàng)目Pod 綁定Service 服務(wù)翎朱,可以使得在遷移服務(wù)提供方時(shí),自動(dòng)管理內(nèi)部ip映射關(guān)系尺铣,使用方無感拴曲。我想到項(xiàng)目上的數(shù)據(jù)庫可以這么做的有Redis(NAT)/Mysql(主從)/MongoDB(副本集),web應(yīng)用在同一個(gè)Pod可以做負(fù)載均衡(?)凛忿,至于dubbo應(yīng)用自動(dòng)注冊(cè)更不用說澈灼,這樣在部署集成時(shí)可以用k8s拉起整個(gè)業(yè)務(wù)系統(tǒng)。
2018-09-13
隨風(fēng)
聽了幾遍,每遍都有收獲叁熔。??期待早點(diǎn)聽到istio的內(nèi)容委乌,在選型
2018-09-13
小偉
老師,你覺得作為一個(gè)運(yùn)維在學(xué)習(xí)k8s時(shí)重點(diǎn)關(guān)注哪些技術(shù)點(diǎn)將來在能發(fā)揮更大作業(yè)呢荣回?我們公司正準(zhǔn)備上架k8s項(xiàng)目遭贸,我都不知道該重點(diǎn)學(xué)習(xí)哪里?
2018-09-13
作者回復(fù)
就是專欄覆蓋的這些內(nèi)容心软。
2018-09-13
阿青壕吹,你學(xué)到了嗎
物超所值!I玖濉耳贬!
2018-09-12
Tank
Server Version: 18.06.0-ce
Storage Driver: devicemapper
Backing Filesystem: xfs
我本地的并非 aufs 我本地沒有設(shè)置過。這里面的原理是否可以講一下猎唁。
2018-09-12
作者回復(fù)
devicemapper是基于快照的效拭,你其實(shí)可以想象一下,層是不是就很像某一時(shí)刻的快照呢胖秒?
2018-09-12
廣興
嘗試第二個(gè)問題:例如mysql這種有狀態(tài)服務(wù)缎患,當(dāng)容器被調(diào)度到其他節(jié)點(diǎn)時(shí),ip和存儲(chǔ)的數(shù)據(jù)都無法同步了
2018-09-12
作者回復(fù)
不止這兩個(gè)狀態(tài)阎肝,想象一下主從結(jié)構(gòu)的mysql
2018-09-12
剃刀嗎啡
k8s的架構(gòu)分master和node和現(xiàn)在的Istio很像挤渔,也是分了控制面板和數(shù)據(jù)面板,估計(jì)Istio的設(shè)計(jì)借鑒了k8s
2018-09-12
作者回復(fù)
istio就是kubernetes一個(gè)體系下的東西风题,我很快會(huì)講到判导。類似于,阿里和支付寶吧沛硅。
2018-09-12
劉欣洲
Kubernetes 的成功是不是意味著Docker Swarm 的失斞廴小? DockerSwarm還有存在的必要性嗎摇肌?
作者回復(fù)
任何時(shí)候都有小眾市場(chǎng)的存在
2018-09-12
Geek_700d17
嘗試回答第二個(gè)問題擂红,阻止遷移的情況有volum 映射,造成數(shù)據(jù)文件與固定宿主機(jī)綁定围小;還有就是網(wǎng)絡(luò)問題昵骤。
2018-09-12
Geek_700d17
沙發(fā)