Kubernetes和Docker的關(guān)系是什么?
本文轉(zhuǎn)載自微信公眾號(hào)「無敵碼農(nóng)」,作者無敵碼農(nóng) 。轉(zhuǎn)載本文請(qǐng)聯(lián)系無敵碼農(nóng)公眾號(hào)。
作為一名容器時(shí)代的程序員相信你已經(jīng)或多或少接觸過Docker,但同時(shí)你也會(huì)發(fā)現(xiàn)Docker雖然流行了多年,但之前卻很少有公司直接將線上應(yīng)用通過Docker容器進(jìn)行大規(guī)模地部署。但最近三年,你會(huì)發(fā)現(xiàn)幾乎絕大多數(shù)有條件的公司都已經(jīng)在使用Kubernetes部署和發(fā)布自己的線上業(yè)務(wù)了。對(duì)一名普通開發(fā)人員來說,這一切可能發(fā)生得太快,以至于你還沒有搞清楚它是怎么發(fā)生的,也會(huì)疑惑Docker和Kubernetes之間到底是個(gè)什么關(guān)系。
在今天的內(nèi)容中,我們從Kubernetes的系統(tǒng)架構(gòu)及容器編排核心概念兩個(gè)方面來簡(jiǎn)單聊一聊這個(gè)問題,希望能幫助到你更好地理解Docker和Kubernetes之間因果關(guān)系。
Kubernetes介紹
在具體介紹Kubernetes之前不得不再提一下Docker,如果你用過Docker部署過程序,那么你一定會(huì)非常享受它帶給你的絲滑體驗(yàn),而聯(lián)想到在此之前發(fā)布一個(gè)程序需要寫各種腳本、進(jìn)行各種環(huán)境匹配的糟糕體驗(yàn),那么相信你的這種感覺會(huì)更加強(qiáng)烈。
而Docker之所以能做到這一點(diǎn),就在于它以“Docker鏡像”的方式一舉解決了應(yīng)用打包和發(fā)布這一困擾業(yè)界多年的技術(shù)難題,并且大大降低了普通開發(fā)人員運(yùn)維部署應(yīng)用的門檻。正是因?yàn)榻鉀Q了應(yīng)用打包這個(gè)根本性的問題,才使得Docker很快就被廣大開發(fā)/運(yùn)維人員所接受,迅速成為炙手可熱的技術(shù),并在一定時(shí)間內(nèi)引領(lǐng)了容器化技術(shù)發(fā)展的浪潮。
那么Docker這么好用為什么還會(huì)出現(xiàn)Kubernetes呢?事實(shí)是Docker作為單一的容器技術(shù)工具并不能很好地定義容器的“組織方式”和“管理規(guī)范”,難以獨(dú)立地支撐起生產(chǎn)級(jí)大規(guī)模容器化部署的要求。因此容器技術(shù)的發(fā)展就迅速走向了以Kubernetes為代表的“容器編排”的技術(shù)路線,而這也是為什么Docker容器沒有直接在生產(chǎn)環(huán)境中大規(guī)模部署的關(guān)鍵原因。
上面我們提到了“容器編排”的概念,了解到相對(duì)于Docker單一容器技術(shù)而言,Kubernetes容器編排技術(shù)可以很好地實(shí)現(xiàn)大規(guī)模容器的組織和管理,從而使容器技術(shù)實(shí)現(xiàn)了從“容器”到“容器云”的飛躍!那么Kubernetes技術(shù)是從何而來?而又真正解決了什么問題呢?
從背景上說,Kubernetes是由Google與RedHat公司共同主導(dǎo)的開源“容器編排”項(xiàng)目,它起源于Google公司的Borg系統(tǒng)。所以它在超大規(guī)模集群管理方面的經(jīng)驗(yàn)要明顯優(yōu)于其他容器編排技術(shù),加上Kubernetes在社區(qū)管理方面的民主化,使得它很快打敗了Docker公司推出的容器編排解決方案(Compose+Swarm),從而成為了容器編排領(lǐng)域事實(shí)上的標(biāo)準(zhǔn)。
而在功能上Kubernetes是一種綜合的基于容器構(gòu)建分布式系統(tǒng)的基礎(chǔ)架構(gòu)環(huán)境,它不僅能夠?qū)崿F(xiàn)基本的拉取用戶鏡像、運(yùn)行容器,還可以提供路由網(wǎng)關(guān)、水平擴(kuò)展、監(jiān)控、備份、災(zāi)難恢復(fù)等一系列運(yùn)維能力,而更重要的是Kubernetes可以按照用戶的意愿和整個(gè)系統(tǒng)的規(guī)則,高度自動(dòng)化的處理好容器之間的各種關(guān)系實(shí)現(xiàn)“編排”能力。
此外Kubernetes的出現(xiàn)也重新定義了微服務(wù)架構(gòu)的技術(shù)方向,目前通常所說的“云原生”及“Service Mesh(服務(wù)網(wǎng)格)”等概念,很大程度上也是依賴于Kubernetes所提供的基礎(chǔ)能力。由于篇幅和作者知識(shí)水平有限,這里就不展開去聊了,感興趣的讀者可以參考其他專業(yè)書籍或技術(shù)資料。
Kubernetes整體系統(tǒng)架構(gòu)
前面我們簡(jiǎn)單介紹了Kubernetes的起源和背景,接下來看看Kubernetes的整體系統(tǒng)架構(gòu),如下圖所示:

如上圖所示,Kubernetes在架構(gòu)上主要由Master和Node兩種類型的節(jié)點(diǎn)組成,這兩種節(jié)點(diǎn)分別對(duì)應(yīng)著控制節(jié)點(diǎn)和計(jì)算節(jié)點(diǎn)。其中Master即控制節(jié)點(diǎn),是整個(gè)Kubernetes集群的大腦,主要負(fù)責(zé)編排、管理和調(diào)度用戶提交的作業(yè),并能根據(jù)集群系統(tǒng)資源的整體使用情況將作業(yè)任務(wù)自動(dòng)分發(fā)到可用Node計(jì)算節(jié)點(diǎn)。具體看Master節(jié)點(diǎn)主要由三個(gè)緊密協(xié)作的獨(dú)立組件組合而成,它們分別是:
- kube-apiserver:是Kubernetes集群API服務(wù)的入口,主要提供資源訪問操作、認(rèn)證、授權(quán)、訪問控制及API注冊(cè)和發(fā)現(xiàn)等功能機(jī)制。
- kube-scheduler:負(fù)責(zé)Kubernetes的資源調(diào)度,能按照預(yù)定的調(diào)度策略將Pod調(diào)度到相應(yīng)的機(jī)器上。
- kube-controller-manager:負(fù)責(zé)容器編排及Kubernetes集群狀態(tài)的維護(hù),例如故障檢測(cè)、自動(dòng)擴(kuò)展、滾動(dòng)更新等。
需要說明的是,上述組件在工作狀態(tài)下還會(huì)產(chǎn)生許多需要進(jìn)行持久化的數(shù)據(jù),這些數(shù)據(jù)會(huì)通過kube-apiserver處理后統(tǒng)一保存到Etcd存儲(chǔ)服務(wù)中。所以從這個(gè)角度看kube-apiserver不僅是外部訪問Kubernetes集群的入口,也是維護(hù)整個(gè)Kubernetes集群狀態(tài)的信息中樞。
而在Kubernetes計(jì)算節(jié)點(diǎn)中,除了上述3個(gè)系統(tǒng)組件外,其他基本與Master節(jié)點(diǎn)相同,而其中最核心的部分就是kubelet組件。它的核心功能具如下:
- 通過CRI(Container Runtime Interface)遠(yuǎn)程接口同容器運(yùn)行時(shí)(如Docker)進(jìn)行交互,對(duì)容器生命周期進(jìn)行維護(hù)。其中CRI接口會(huì)定義了容器運(yùn)行時(shí)的各項(xiàng)核心操作,例如啟動(dòng)容器所需的命令及參數(shù)等。
- 通過GRPC協(xié)議同Device Plugin插件交互,實(shí)現(xiàn)Kubernetes對(duì)宿主機(jī)物理設(shè)備的管理。
- 此外kubelet另一個(gè)重要的功能則是通過CNI(Container Networking Interface)來調(diào)用網(wǎng)絡(luò)插件為容器配置網(wǎng)絡(luò),以及通過CSI(Container Storage Interface)和存儲(chǔ)插件交互為容器配置持久化存儲(chǔ)。
在Kubernetes中kubelet會(huì)通過CRI接口同容器運(yùn)行時(shí)進(jìn)行交互,而容器運(yùn)行時(shí)則通過叫做OCI容器運(yùn)行時(shí)規(guī)范與底層Linux操作系統(tǒng)進(jìn)行交互(涉及對(duì)Namespace、Cgroups等資源的操作,具體可以了解下Docker的技術(shù)原理)。需要強(qiáng)調(diào)的是,這里所說的容器運(yùn)行時(shí)并不僅僅指Docker,而是所有實(shí)現(xiàn)了CRI接口規(guī)范的容器項(xiàng)目都可以作為Kubernetes的容器運(yùn)行時(shí)存在。這是因?yàn)镵ubernetes從設(shè)計(jì)之初就沒有把Docker作為整個(gè)架構(gòu)的核心,而只是將其作為最底層的一個(gè)容器運(yùn)行時(shí)來實(shí)現(xiàn)。
但這并不是說Kubernetes就完全拋棄Docker了,要知道Docker最大的成功并不是它的容器運(yùn)行時(shí)技術(shù),而是它定義的“容器鏡像”開創(chuàng)性地解決了困擾業(yè)界多年的應(yīng)用打包難題,所以雖然Kubernetes并不完全依賴于Docker的容器運(yùn)行時(shí)技術(shù),但容器鏡像的定義標(biāo)準(zhǔn)卻是所有容器技術(shù)都繞不開的存在。
況且從Kubernetes架構(gòu)設(shè)計(jì)上看,Kubernetes并沒有打算重復(fù)造輪子而對(duì)已有的容器技術(shù)進(jìn)行替代,它更關(guān)注的是對(duì)運(yùn)行在大規(guī)模集群中的各種任務(wù)根據(jù)其關(guān)系進(jìn)行作業(yè)編排及管理,所以任何實(shí)現(xiàn)了CRI、CNI、CSI等協(xié)議標(biāo)準(zhǔn)的容器技術(shù)都可以無縫地與Kubernetes集成。從這個(gè)角度看,Docker與Kubernetes的關(guān)系并不是替代的關(guān)系,而是平臺(tái)與組件的關(guān)系,Kubernetes可以利用現(xiàn)有的Docker容器運(yùn)行時(shí)技術(shù),但卻并不完全依賴Docker。而這也正是Kubernetes為什么被稱作容器編排技術(shù)而不僅僅只是容器技術(shù)的原因。
Kubernetes容器編排概述
我們說處理任務(wù)之間的各種關(guān)系,實(shí)現(xiàn)容器編排是Kubernetes的核心技術(shù)能力,也是其大規(guī)模流行的關(guān)鍵原因。那么容器編排到底是個(gè)什么概念?在Kubernetes中是如何實(shí)現(xiàn)容器編排的呢?
其實(shí)所謂容器編排,通俗點(diǎn)舉例就是如果兩個(gè)應(yīng)用調(diào)用關(guān)系比較緊密,那么我們希望運(yùn)行時(shí)將它們部署在同一臺(tái)機(jī)器上,從而提升服務(wù)之間的通信效率。而能夠支持自動(dòng)將具有此類關(guān)系的應(yīng)用,以容器的方式部署在同一臺(tái)機(jī)器上的技術(shù)就是容器編排。
當(dāng)然,這里所說的緊密關(guān)系只是一種形象的說法,實(shí)際的技術(shù)場(chǎng)景中這種緊密關(guān)系可以被劃分為很多類型,例如Web應(yīng)用與數(shù)據(jù)庫(kù)之間的訪問關(guān)系、負(fù)載均衡和它后端服務(wù)之間的代理關(guān)系、門戶應(yīng)用與授權(quán)組件之間的調(diào)用關(guān)系等。
而對(duì)于Kubernetes來說,這樣的關(guān)系描述顯然還是過于具體,因?yàn)镵ubernetes的設(shè)計(jì)目標(biāo)不僅僅是能夠處理前面提到的所有類型的關(guān)系,還要能夠支持未來可能出現(xiàn)的更多種類的關(guān)系。這就要求Kubernetes要從更宏觀地角度來定義任務(wù)之間的各種關(guān)系,并且能為將來支持更多種類的關(guān)系留有余地。
具體來說,Kubernetes是對(duì)容器間的訪問進(jìn)行了分類,如果這些應(yīng)用之間需要非常頻繁的交互和訪問,或者它們之間存在直接通過本地文件進(jìn)行信息交換的情況,那么在Kubernetes中可以將這些容器劃分為一個(gè)“Pod”,而Pod中的容器將共享同一個(gè)Network Namespace、同一組數(shù)據(jù)卷,從而實(shí)現(xiàn)高效率通信。
Pod是Kubernetes中最基礎(chǔ)的編排對(duì)象,是Kubernetes最小的調(diào)度單元,也是Kubernetes實(shí)現(xiàn)容器編排的載體,其本質(zhì)上是一組共享了某些系統(tǒng)資源的容器集合。在Kubernetes中圍繞Pod可以延伸出其他核心概念,具體如下圖所示:
如上圖所示,在Kubernetes中Pod解決了容器間緊密協(xié)作(即編排)的問題,而Pod要實(shí)現(xiàn)一次啟動(dòng)多個(gè)Pod副本就需要Deployment這個(gè)Pod多實(shí)例管理器;而有了這樣一組Pod后,我們又需要通過一個(gè)固定網(wǎng)絡(luò)地址以負(fù)載均衡的方式訪問它,于是又有了Service。
而根據(jù)不同的編排場(chǎng)景Pod又衍生出描述一次性運(yùn)行任務(wù)的Job編排對(duì)象、描述每個(gè)宿主機(jī)上必須且只能運(yùn)行一個(gè)副本的守護(hù)進(jìn)程服務(wù)DaemonSet、描述定義任務(wù)的CronJob編排對(duì)象、以及針對(duì)有狀態(tài)應(yīng)用的StatefulSet等多種編排對(duì)象。而這些編排對(duì)象正是Kubernetes定義容器間關(guān)系和形態(tài)的主要方法。