轉(zhuǎn)載請(qǐng)注明出處即可
文章原文
用最后提交時(shí)間為20年04月02號(hào) 85e7b63ddbb86107b2850ac4b0bacc7aed194fd5的版本進(jìn)行翻譯
注意: 本文并非是直譯,部分譯文攜帶了筆者自己的理解,因?yàn)楣P者水平有限,可能或曲解作者的原意。
概述
Kubernetes的源自于Google 15 年生產(chǎn)環(huán)境的運(yùn)維經(jīng)驗(yàn),同時(shí)凝聚了社區(qū)的最佳創(chuàng)意和實(shí)踐。它是一個(gè)生產(chǎn)級(jí)別的開(kāi)源基礎(chǔ)設(shè)施,可以做到在跨主機(jī)集群的環(huán)境下,對(duì)應(yīng)用容器進(jìn)行部署、擴(kuò)展、管理和組合。Kubernetes存在的意義不僅僅是提供了"容器編排"。它方便運(yùn)維人員和開(kāi)發(fā)者專注于以容器為中心的自助操作[1],比如幫助開(kāi)發(fā)者聚焦核心應(yīng)用功能,幫助運(yùn)維團(tuán)隊(duì)獲取更高的資源利用率等。它通過(guò)對(duì)開(kāi)發(fā)者屏蔽了物理/虛擬計(jì)算、網(wǎng)絡(luò)和存儲(chǔ),因此開(kāi)發(fā)者可以專注于應(yīng)用實(shí)現(xiàn),而不是花費(fèi)時(shí)間去思考與基礎(chǔ)設(shè)施的集成,運(yùn)維人員也不用考慮在上面部署的是什么樣的應(yīng)用。Kubernetes還是一個(gè)穩(wěn)定的,可移植的基礎(chǔ)平臺(tái),可以自定義的工作流和其他在更高級(jí)別的自動(dòng)化,或者說(shuō)Kubernetes抽象了底層的基礎(chǔ)設(shè)施,簡(jiǎn)化了應(yīng)用開(kāi)發(fā)、部署等過(guò)程。
[1] (譯注: 做到了關(guān)注點(diǎn)隔離,方便兩種不同的角色專注于各自不同的領(lǐng)域,當(dāng)某個(gè)機(jī)器出現(xiàn)問(wèn)題時(shí),只需要調(diào)度到其他的機(jī)器,而無(wú)需運(yùn)維人員在半夜加班處理問(wèn)題,可以在第二天在處理出現(xiàn)問(wèn)題的機(jī)器。)
Kubernetes主要用于由多個(gè)容器(Docker等)組成的應(yīng)用程序(或系統(tǒng)、服務(wù))。為了方便管理容器和發(fā)現(xiàn)容器,它通過(guò)使用pods和labels(標(biāo)簽)來(lái)形成了一種緊耦合或松耦合的結(jié)構(gòu)[2]。
[2] (譯注: 這里的緊耦合和松耦合可以理解為在部署pod時(shí),對(duì)label的使用??梢詮?qiáng)制將pod部署到某個(gè)或者某幾個(gè)節(jié)點(diǎn),也可以通過(guò)對(duì)節(jié)點(diǎn)資源的篩選(比如需要GPU資源)等去進(jìn)行選擇節(jié)點(diǎn)(調(diào)度)部署。當(dāng)然緊耦合在生產(chǎn)環(huán)境一般是不推薦的。)
范圍
Kubernetes是一個(gè)用于部署和管理容器的平臺(tái)。Kubernetes提供了容器引擎,容器編排,以容器為中心的基礎(chǔ)設(shè)施編排、運(yùn)行時(shí)狀態(tài)檢查和重新調(diào)度等自我修復(fù)機(jī)制、并且還提供了服務(wù)發(fā)現(xiàn)和負(fù)載均衡。
Kubernetes期望能成為一個(gè)可擴(kuò)展,插件化的工具集。因此,在架構(gòu)上,我們希望將Kubernetes構(gòu)建的組件都是可插拔的,并且可以自行選擇調(diào)度器、控制器、存儲(chǔ)系統(tǒng)和分發(fā)機(jī)制,我們根據(jù)這個(gè)愿景來(lái)發(fā)展這個(gè)項(xiàng)目。此外,我們希望大家能夠擴(kuò)展Kubernetes的能力,比如在無(wú)需修Kubernetes核心源代碼的情況下,使用更高級(jí)的PaaS功能等,因此Kubernetes所提供的API不僅僅針對(duì)使用它的終端用戶,而是針對(duì)工具和擴(kuò)展Kubernetes能力的開(kāi)發(fā)人員。它的API旨在作為工具、自動(dòng)化系統(tǒng)和高級(jí)API層的開(kāi)發(fā)生態(tài)系統(tǒng)的基礎(chǔ)。因?yàn)椋鼪](méi)有“內(nèi)部的”組件間的API。所有的API都是可見(jiàn)和可用的,包括調(diào)度器,節(jié)點(diǎn)控制器,復(fù)制控制器,Kubelet的API等。為了處理在不同生產(chǎn)環(huán)境下的獨(dú)特需求,大家可以直接訪問(wèn)底層API。
目標(biāo)
本項(xiàng)目有以下的設(shè)計(jì)理論和目標(biāo):
- 方便: Kubernetes可以運(yùn)行在公有云,私有云,裸機(jī)和筆記本電腦。并且無(wú)論在哪個(gè)環(huán)境下對(duì)它做的任何操作都是一致的。換句話說(shuō)就是它可以到處運(yùn)行,而無(wú)需考慮底層具體基礎(chǔ)設(shè)施的差異。因此應(yīng)用程序和工具可以在整個(gè)生態(tài)系統(tǒng)以及開(kāi)發(fā)和生產(chǎn)環(huán)境之間進(jìn)行移植。
- 通用: Kubernetes應(yīng)該運(yùn)行所有的系統(tǒng)類別。無(wú)論是有狀態(tài)的、無(wú)狀態(tài)的、微服務(wù)、單體應(yīng)用、服務(wù)、批處理、遺留系統(tǒng)等,這樣只需要在Kubernetes單個(gè)基礎(chǔ)設(shè)施運(yùn)行以上所有類型,來(lái)應(yīng)對(duì)實(shí)際的負(fù)載。
- 滿足一部分用戶需求: 雖然Kubernetes不只滿足于純粹的云原生應(yīng)用,但是也不會(huì)滿足用戶的所有需求。它主要專注于微服務(wù)和云原生應(yīng)用的部署和管理,但是提供了一些機(jī)制來(lái)促進(jìn)整體和遺留應(yīng)用到Kubernetes的遷移。
- 靈活: Kubernetes功能可以按需使用,并且可以通過(guò)自己的解決方案來(lái)替代內(nèi)置的功能。
- 可擴(kuò)展的: Kubernetes通過(guò)內(nèi)置功能所使用的相同公開(kāi)接口來(lái)添加額外的功能。
- 易自動(dòng)化: Kubernetes的目標(biāo)是大幅減少手工操作。它通過(guò)聲明式API指定用戶期望,聲明后則通過(guò)它的內(nèi)部機(jī)制來(lái)進(jìn)行具體的命令式的控制執(zhí)行。聲明式API是系統(tǒng)自愈等相關(guān)能力的關(guān)鍵。當(dāng)然, 它也支持定義更高級(jí)別的編排和自動(dòng)化的命令式控制。
- 推薦先進(jìn)技術(shù): 雖然Kubernetes可以支持非云原生應(yīng)用,但是它也希望可以推進(jìn)云原生和DevOps的技術(shù)發(fā)展,比如讓?xiě)?yīng)用參也參與到對(duì)自己的管理之中。但是它不會(huì)強(qiáng)迫程序鎖死在Kubernetes API,這也是Kubernetes的API更喜歡配置而不是約定的原因。此外,Kubernetes不受它所依賴系統(tǒng)的限制,無(wú)論是容器引擎還是云廠商。例如,可以根據(jù)需要來(lái)選擇不同的Pod的網(wǎng)絡(luò)模型。
架構(gòu)
Kubernetes在運(yùn)行時(shí),包含節(jié)點(diǎn)代理(kubelet)和集群控制平面(AKA Master),集群狀態(tài)存儲(chǔ)在分布式存儲(chǔ)系統(tǒng)(etcd)中。
集群控制平面
Kubernetes的控制平面由多個(gè)組件組成,這些組件既可以單節(jié)點(diǎn)運(yùn)行,或通過(guò)多節(jié)點(diǎn)來(lái)支持高可用的集群,或者將組件直接運(yùn)行在Kubernetes上,進(jìn)行自托管。
在Kubernetes中,資源作為控制平面的樞紐,Kubernetes提供的Rest API,主要是支持在這些資源(持久化)上進(jìn)行CRUD操作。Kubernetes提供的API,比如Pods,Services和Ingress,以及生命周期的API等,都是以容器為中心的操作。通過(guò)這些API來(lái)支持業(yè)務(wù)流程(自愈、擴(kuò)展、更新、終止)和常見(jiàn)的工作負(fù)載。比如ReplicaSet(簡(jiǎn)單的、無(wú)狀態(tài)(可替換)的應(yīng)用程序管理器),Deployment(部署與更新無(wú)狀態(tài)應(yīng)用),Job(批處理), CronJob(cron), DaemonSet(集群服務(wù))和StateFullSet(有狀態(tài)應(yīng)用管理)。并且我們特意將服務(wù)注冊(cè)于服務(wù)發(fā)現(xiàn)和負(fù)載均衡的實(shí)現(xiàn)分離,因?yàn)樨?fù)載均衡是開(kāi)放的,并且種類繁多。
用戶客戶端(kubectl或直接使用的k8s client)和包含異步處理的控制器(conttollers)都使用了相同的API資源、這些資源會(huì)協(xié)調(diào)中間數(shù)據(jù)狀態(tài),以及共享狀態(tài)。大多數(shù)資源都包含元數(shù)據(jù),元數(shù)據(jù)中又包含labels和annotations,資源所需的詳細(xì)狀態(tài)(spec),默認(rèn)值和可觀測(cè)到的狀態(tài)。
控制器會(huì)不斷檢查觀測(cè)狀態(tài),當(dāng)期望(配置)狀態(tài)與觀測(cè)狀態(tài)不一致時(shí),則驅(qū)動(dòng)Kubernetes達(dá)到期望的狀態(tài)(自愈),同時(shí)也會(huì)為用戶和其他控制器報(bào)告觀測(cè)到的狀態(tài)。
雖然控制器是基于聲明式API已最大程序的提高容錯(cuò)性,但它們?yōu)榱俗畲笙薅鹊臏p少延遲和冗余工作,通常會(huì)watch(監(jiān)視)相關(guān)的資源更改。這樣就可以在沒(méi)有消息總線的情況下實(shí)現(xiàn)服務(wù)編排的解耦。
API Server
API Server提供Kubernetes API,它是一個(gè)相對(duì)簡(jiǎn)單的服務(wù)器,其他的組件或插件會(huì)實(shí)現(xiàn)大部分業(yè)務(wù)邏輯。它主要處理REST操作,并進(jìn)行驗(yàn)證,然后更新Etcd中相應(yīng)的對(duì)象(可能最終會(huì)更新其他存儲(chǔ))。這里請(qǐng)注意,Kubernetes不支持跨多個(gè)資源的原子事務(wù)。
這個(gè)基本的API機(jī)制,是Kubernetes可以運(yùn)行的根本,其中包括
- REST語(yǔ)義,watch(監(jiān)聽(tīng)),持久性和保證一致性, API版本控制、默認(rèn)值和校驗(yàn)
- 內(nèi)置控制語(yǔ)義,同步控制hooks和異步資源初始化
- API的注冊(cè)和發(fā)現(xiàn)
此外,API服務(wù)器充當(dāng)集群的網(wǎng)關(guān)。根據(jù)定義,Kubernetes Client能夠從集群外部訪問(wèn)API服務(wù)器,而節(jié)點(diǎn)和容器則不能直接在集群外部訪問(wèn)。API服務(wù)器會(huì)對(duì)客戶端進(jìn)行驗(yàn)證,并且用于連接節(jié)點(diǎn)和Pods(Services等)的代理和通道。
Cluster state store 集群狀態(tài)存儲(chǔ)
所有持久化的集群狀態(tài)都存儲(chǔ)在Etcd中。通過(guò)對(duì)wahch的支持,可以非常迅速的通知和協(xié)調(diào)組件進(jìn)行更改。
Controller-Manager Server 控制器管理服務(wù)
大多數(shù)集群級(jí)別的功能都是通過(guò)Controller-Manager來(lái)執(zhí)行的。他處理生命周期的功能(例如,命名空間創(chuàng)建和生命周期、事件垃圾收集、終止pod垃圾收集、級(jí)聯(lián)刪除垃圾收集、節(jié)點(diǎn)垃圾收集)和API的業(yè)務(wù)邏輯(例如,由復(fù)制集控制的pod擴(kuò)展)。
應(yīng)用程序管理和組合層,提供自修復(fù)、伸縮、應(yīng)用程序生命周期管理、服務(wù)發(fā)現(xiàn)、路由以及服務(wù)綁定和供應(yīng)。這些功能最終可能會(huì)被分解成單獨(dú)的組件,以便更容易地?cái)U(kuò)展或替換。
Scheduler 調(diào)度器
Kubernetes允許用戶請(qǐng)求集群運(yùn)行一組容器。調(diào)度器會(huì)為容器自動(dòng)選擇要運(yùn)行的主機(jī)。
調(diào)度器監(jiān)視未調(diào)度的Pods,并根據(jù)所請(qǐng)求資源的可用性、服務(wù)質(zhì)量(QoS)要求、親和性和反親和性以及其他的約束選擇節(jié)點(diǎn),然后通過(guò)Binding Pod子資源API將它們綁定到節(jié)點(diǎn)上。
The Kubernetes Node 節(jié)點(diǎn)
Kubernetes節(jié)點(diǎn)有運(yùn)行應(yīng)用容器所需的組件。
Kubelet
Kubernetes中最重要的就是Kubelet組件,它是容器執(zhí)行層的Pod和Node API的主要實(shí)現(xiàn)者。如果沒(méi)有這些API, Kubernetes就只是一個(gè)CRUD的REST應(yīng)用程序框架(這些API機(jī)制可能最終會(huì)發(fā)展成為一個(gè)獨(dú)立的項(xiàng)目)。
Kubernetes將隔離的應(yīng)用容器作為默認(rèn)的執(zhí)行模式。應(yīng)用容器不僅僅彼此隔離,而且還與它們執(zhí)行的主機(jī)隔離,這對(duì)于各個(gè)應(yīng)用程序管理與基礎(chǔ)設(shè)施的管理(底層物理集群或虛擬集群)分離來(lái)說(shuō)至關(guān)重要。
Kubernetes通過(guò)Pods來(lái)承載多容器和存儲(chǔ)卷,方便每個(gè)容器只打包單個(gè)應(yīng)用程序(譯注: 在k8s中,一個(gè)Pod可以運(yùn)行多個(gè)容器,但在實(shí)踐中盡量不要在一個(gè)容器中跑多個(gè)應(yīng)用)。通過(guò)Pod可以將部署和構(gòu)建分離開(kāi),以及方便從物理機(jī)和虛擬機(jī)遷移。Pod的設(shè)計(jì)是現(xiàn)代云平臺(tái)(如Kubernetes)上部署的關(guān)鍵。
API管理控制可能拒絕Pods或向它們添加額外的調(diào)度約束。但是Kubelet是決定Pods在指定節(jié)點(diǎn)(node)上是否可以運(yùn)行的最終角色這,而不是調(diào)度器或其他組件。
Kubelet還鏈接在cAdvisor(譯注: Google開(kāi)源的容器資源監(jiān)控項(xiàng)目)資源代理的監(jiān)控中。
容器引擎
每個(gè)節(jié)點(diǎn)運(yùn)行一個(gè)容器時(shí),容器引擎負(fù)責(zé)下載鏡像(images)和運(yùn)行容器。
Kubelet沒(méi)有關(guān)聯(lián)任何的基礎(chǔ)容器引擎。相反,我們定義了一個(gè)容器引擎的接口來(lái)控制底層引擎在該層的可插拔性。為了組件邊界、方便測(cè)試和可插拔性,需要這種與某個(gè)具體容器引擎的解耦。目前至少支持了Docker、rkt、crio和frakti這些容器引擎。
Kube Proxy
Kubernetes中service提供了公共訪問(wèn)策略,可以為Pods進(jìn)行分組(譯注: 可以通過(guò)label來(lái)實(shí)現(xiàn))后提供負(fù)載均衡。它實(shí)現(xiàn)了一個(gè)虛擬IP,客戶端可以通過(guò)訪問(wèn)這個(gè)虛擬IP,來(lái)透明的代理到服務(wù)后的Pods中。每個(gè)節(jié)點(diǎn)都運(yùn)行了一個(gè)kube-proxy進(jìn)程,該進(jìn)程通過(guò)改寫(xiě)iptables規(guī)則來(lái)捕獲IP的訪問(wèn),并將其重定向到具體的后端。這是一個(gè)高可用的負(fù)載均衡解決方案,通過(guò)平衡單個(gè)節(jié)點(diǎn)客戶端流量,到相同的節(jié)點(diǎn)上,降低了單個(gè)節(jié)點(diǎn)的性能開(kāi)銷。
服務(wù)endpoints還可以通過(guò)DNS(內(nèi)置的core-dns)來(lái)找到。
其他組件和其他依賴項(xiàng)
Kubernetes除了以上組件外,還依賴其他組件,通常運(yùn)行在Kubernetes內(nèi)部:
- DNS
- Ingress controller
- Heapster (resource monitoring)
- Dashboard (GUI)
聯(lián)合
一個(gè)Kubernetes可以跨多個(gè)可用區(qū)(Zone)部署。
但為了更高的可用性,我們建議使用集群聯(lián)合。
(譯注: 集群聯(lián)合或者叫做集群聯(lián)邦,是新版本提供的功能,可以跨集群資源同步和跨集群發(fā)現(xiàn))