Kubernetes核心概念與組件
Kubernetes是一個(gè)開源的容器編排引擎,用來(lái)對(duì)容器化應(yīng)用進(jìn)行自動(dòng)化部署、 擴(kuò)縮和管理。然而并非所有項(xiàng)目都需要微服務(wù)化,也并非所有項(xiàng)目需要Kubernetes,例如管理后臺(tái)、定時(shí)任務(wù)服務(wù)、非分布式數(shù)據(jù)庫(kù)等就沒有必要容器化部署,Kubernetes更適合部署分布式微服務(wù)應(yīng)用。
這兩天筆者看完了《Kubernetes源碼剖析》這本書,由于Kubernetes是用go語(yǔ)言編寫,很多Java程序員可能沒學(xué)過go語(yǔ)言,為了分享這本書,筆者摘錄了書中的一些關(guān)鍵知識(shí)點(diǎn)整理成這篇文章,也希望通過這篇文章幫助大家理解Kubernetes。
(之前公司內(nèi)部技術(shù)分享畫的學(xué)習(xí)路線思維導(dǎo)圖)
Kubernetes架構(gòu)
圖片 (圖片來(lái)源:《Kubernetes源碼剖析》.Kubernetes架構(gòu)圖)
Kubernetes系統(tǒng)采用C/S架構(gòu)設(shè)計(jì),系統(tǒng)架構(gòu)分為Master、Node兩部分,Master為Server端(主控節(jié)點(diǎn)),Node為Client端(工作節(jié)點(diǎn))。
Master主控節(jié)點(diǎn)作為集群的大腦負(fù)責(zé)管理所有工作節(jié)點(diǎn)(Node)、負(fù)責(zé)調(diào)度Pod運(yùn)行在哪些工作節(jié)點(diǎn)上、負(fù)責(zé)控制集群運(yùn)行過程中的所有狀態(tài),其中節(jié)點(diǎn)表示云虛擬服務(wù)器。
Node工作節(jié)點(diǎn)負(fù)責(zé)管理容器、監(jiān)控和上報(bào)運(yùn)行在本節(jié)點(diǎn)上的所有Pod的運(yùn)行狀態(tài)。
運(yùn)行在Master主控節(jié)點(diǎn)上的組件有kube-apiserver、kube-controller-manager、kube-scheduler組件。
kube-apiserver負(fù)責(zé)將Kubernetes“資源組/資源版本/資源”以RESTful風(fēng)格的形式對(duì)外暴露并提供服務(wù)。集群中的所有組件都通過kube-apiserver組件操作資源對(duì)象。kube-apiserver組件也是集群中唯一與Etcd集群進(jìn)行交互的核心組件。
kube-controller-manager管理Kubernetes集群中的節(jié)點(diǎn)(Node)、Pod副本、服務(wù)、端點(diǎn)(Endpoint)、命名空間(Namespace)、服務(wù)賬戶(ServiceAccount)等。負(fù)責(zé)確保Kubernetes系統(tǒng)的實(shí)際狀態(tài)收斂到所需狀態(tài),其默認(rèn)提供了一些控制器(Controller),例如DeploymentControllers控制器、StatefulSet控制器、Namespace控制器及PersistentVolume控制器等,每個(gè)控制器通過kube-apiserver組件提供的接口實(shí)時(shí)監(jiān)控整個(gè)集群每個(gè)資源對(duì)象的當(dāng)前狀態(tài),當(dāng)發(fā)生故障而導(dǎo)致系統(tǒng)狀態(tài)出現(xiàn)變化時(shí),嘗試將系統(tǒng)狀態(tài)修復(fù)到期望狀態(tài)。
kube-scheduler調(diào)度器組件負(fù)責(zé)在Kubernetes集群中為一個(gè)Pod資源對(duì)象找到合適的節(jié)點(diǎn)并在該節(jié)點(diǎn)上運(yùn)行。調(diào)度器每次只調(diào)度一個(gè)Pod資源對(duì)象,為每一個(gè)Pod資源對(duì)象尋找合適節(jié)點(diǎn)的過程是一個(gè)調(diào)度周期。調(diào)度器組件監(jiān)控整個(gè)集群的Pod資源對(duì)象和Node資源對(duì)象,在監(jiān)控到新的Pod資源對(duì)象時(shí)通過調(diào)度算法為其選擇最優(yōu)節(jié)點(diǎn)。
運(yùn)行在Node工作節(jié)點(diǎn)上的組件有kubelet、kube-proxy、container組件。
kubelet負(fù)責(zé)接收、處理、上報(bào)kube-apiserver組件下發(fā)的任務(wù)。kubelet進(jìn)程啟動(dòng)時(shí)會(huì)向kube-apiserver注冊(cè)節(jié)點(diǎn)(Node)自身信息。它主要負(fù)責(zé)所在節(jié)點(diǎn)(Node)上的Pod資源對(duì)象的創(chuàng)建、修改、監(jiān)控、刪除、驅(qū)逐及Pod生命周期管理等。kubelet組件實(shí)現(xiàn)了3種開放接口,分別是CRI(容器運(yùn)行時(shí)接口)、CNI(容器網(wǎng)絡(luò)接口)和CSI(容器存儲(chǔ)接口)。
kube-proxy作為節(jié)點(diǎn)上的網(wǎng)絡(luò)代理,運(yùn)行在每個(gè)Kubernetes節(jié)點(diǎn)上。它監(jiān)控kube-apiserver的服務(wù)和端點(diǎn)資源變化,并通過iptables/ipvs等配置負(fù)載均衡器,為一組Pod提供統(tǒng)一的TCP/UDP流量轉(zhuǎn)發(fā)和負(fù)載均衡功能,但只會(huì)向Kubernetes服務(wù)及其后端Pod發(fā)出請(qǐng)求。
資源概念
在kubernetes中,資源是最核心的概念,整個(gè)生態(tài)系統(tǒng)都圍繞資源運(yùn)作。Kubernetes本質(zhì)上是一個(gè)資源控制系統(tǒng),負(fù)責(zé)注冊(cè)、管理、調(diào)度資源并維護(hù)資源的狀態(tài)。
Kubernetes將資源分組和版本化:
- Group:資源組
- Version:資源版本
- Resource:資源
- Kind:資源種類(分類)
資源對(duì)象與資源操作方法:
- 資源對(duì)象(Resource Object):一個(gè)資源對(duì)象包含的字段有資源組、資源版本、資源種類;
- 資源操作方法(Verbs):每一個(gè)資源都擁有資源操作方法,實(shí)現(xiàn)對(duì)Etcd的CURD操作,kubernetes支持的8種資源操作方法是create、delete、deletecollection、get、list、patch、update、watch。
Kubernetes支持兩類資源組,分別是擁有組名的資源組和沒有組名的資源組:
擁有組名的資源組:其表現(xiàn)形式為
沒有組名的資源組:核心資源組,其表現(xiàn)形式為
Kubernetes提供的Restful API使用GVR(資源分組/資源版本/資源)生成path,如下表格示例:
PATH | 資源 | 資源操作方法 |
---|---|---|
/api/v1/configmaps | ConfigMap | create,delete,deletecollection,get,list,patch,update,watch |
/api/v1/pods | Pod | create,delete,deletecollection,get,list,patch,update,watch |
/api/v1/services | Service | create,delete,deletecollection,get,list,patch,update,watch |
擁有組名的資源組的path以/apis為前綴,沒有組名的資源組的path以/api為前綴。以/api/v1/configmaps為例,v1為資源版本號(hào)、configmaps為資源名稱。
資源還可以擁有子資源,例如pods有l(wèi)ogs子資源。用kubectl查詢?nèi)沼泟t命令為kubectl logs [pod],對(duì)應(yīng)API的path為:/api/v1/pods/logs。
kubernetes支持8種資源操作方法,但并非每種資源都需要支持8種資源操作方法。如pods/logs子資源就只擁有g(shù)et操作方法,因?yàn)槿罩局恍枰獔?zhí)行查看操作。
Kubernetes系統(tǒng)支持命名空間(Namespace),每個(gè)命名空間相當(dāng)于一個(gè)“虛擬集群”,不同命名空間之間可以進(jìn)行隔離。命名空間常用于劃分不同的環(huán)境,例如生產(chǎn)環(huán)境、測(cè)試環(huán)境、開發(fā)環(huán)境等使用不同的命名空間進(jìn)行劃分,也可用于劃分無(wú)關(guān)聯(lián)的項(xiàng)目,如用于劃分項(xiàng)目A、項(xiàng)目B。
資源對(duì)象描述文件定義
Kubernetes資源可分為內(nèi)置資源和自定義資源,它們都通過資源對(duì)象描述文件進(jìn)行定義。一個(gè)資源對(duì)象需要用5個(gè)字段來(lái)描述,分別是Group/Version、Kind、MetaData、Spec、Status。
以Service資源描述文件為例,配置如下:
- apiVersion: v1
- kind: Service
- metadata:
- name: test-service
- namespace: default
- spec:
- ....
- apiVersion:即Group/Version,Service在核心資源組,所以沒有資源組名,v1為資源版本;
- Kind:資源種類;
- MetaData:定義元數(shù)據(jù)信息,如資源名稱、命名空間;
- Spec:描述Service的期望狀態(tài);
- Status:描述資源對(duì)象的實(shí)際狀態(tài),隱藏的,不需要配置,由Kubernetes系統(tǒng)提供和更新。
Pod調(diào)度
Pod資源對(duì)象支持優(yōu)先級(jí)與搶占機(jī)制。當(dāng)kube-scheduler調(diào)度器運(yùn)行時(shí),根據(jù)Pod資源對(duì)象的優(yōu)先級(jí)進(jìn)行調(diào)度,高優(yōu)先級(jí)的Pod資源對(duì)象排在調(diào)度隊(duì)列的前面,優(yōu)先獲得合適的節(jié)點(diǎn)(Node),再為低優(yōu)先級(jí)的Pod資源對(duì)象選擇合適的節(jié)點(diǎn)。
當(dāng)高優(yōu)先級(jí)的Pod資源對(duì)象沒有找到合適的節(jié)點(diǎn)時(shí),調(diào)度器會(huì)嘗試搶占低優(yōu)先級(jí)的Pod資源對(duì)象的節(jié)點(diǎn),搶占過程是將低優(yōu)先級(jí)的Pod資源對(duì)象從所在的節(jié)點(diǎn)上驅(qū)逐走,使高優(yōu)先級(jí)的Pod資源對(duì)象運(yùn)行在該節(jié)點(diǎn)上,被驅(qū)逐走的低優(yōu)先級(jí)的Pod資源對(duì)象會(huì)重新進(jìn)入調(diào)度隊(duì)列并等待再次選擇合適的節(jié)點(diǎn)。
在默認(rèn)的情況下,若不啟用優(yōu)先級(jí)功能,則現(xiàn)有Pod資源對(duì)象的優(yōu)先級(jí)都為0。為Pod資源配置優(yōu)先級(jí)的步驟如下:
1、通過PriorityClass資源對(duì)象描述文件創(chuàng)建PriorityClass資源對(duì)象,配置文件如下:
- apiVersion: scheduling.k8s.io/v1
- kind: PriorityClass
- metadata:
- name: MainResourceHighPriority
- value: 10000
- globalDefault: false
- description: "highest priority"
- value:表示優(yōu)先級(jí),值越高優(yōu)先級(jí)越高;
- globalDefault:是否為全局默認(rèn),當(dāng)Pod沒有指定使用的優(yōu)先級(jí)時(shí)默認(rèn)使用此優(yōu)先級(jí)。
- 2、修改Pod資源對(duì)象描述文件,為Pod指定優(yōu)先級(jí)
通過Deployment配置Pod資源時(shí),只需要在Deployment描述文件的Spec下的Spec添加一項(xiàng)名為priorityClassName的配置,如下:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: test-server
- namespace: default
- spec:
- replicas: 1
- # 配置pod
- spec:
- containers:
- - name: test-server-pod
- image: test-server:latest
- imagePullPolicy: IfNotPresent
- ports:
- - name: http-port
- containerPort: 8080
- envFrom:
- - configMapRef:
- name: common-config
- serviceAccountName: admin-sa
- priorityClassName: MainResourceHighPriority
親和性調(diào)度
與調(diào)度相關(guān)的還有親和性調(diào)度。kube-scheduler調(diào)度器自動(dòng)為Pod資源對(duì)象選擇全局最優(yōu)或局部最優(yōu)節(jié)點(diǎn)(即節(jié)點(diǎn)的硬件資源足夠多、節(jié)點(diǎn)負(fù)載足夠小等)。在生產(chǎn)環(huán)境中,一般希望能夠更多地干預(yù)Pod資源對(duì)象的調(diào)度,例如,將不需要依賴GPU硬件資源的Pod資源對(duì)象分配給沒有GPU硬件資源的節(jié)點(diǎn),將需要依賴GPU硬件資源的Pod資源對(duì)象分配給具有GPU硬件資源的節(jié)點(diǎn)。開發(fā)者只需要在這些節(jié)點(diǎn)上打上相應(yīng)的標(biāo)簽,然后調(diào)度器就可以通過標(biāo)簽進(jìn)行Pod資源對(duì)象的調(diào)度,這種調(diào)度策略被稱為親和性和反親和性調(diào)度。
- 親和性(Affinity):用于多業(yè)務(wù)就近部署,例如允許將兩個(gè)業(yè)務(wù)(如廣告點(diǎn)擊服務(wù)與IP查詢服務(wù))的Pod資源對(duì)象盡可能地調(diào)度到同一個(gè)節(jié)點(diǎn)上,減少網(wǎng)絡(luò)開銷;
- 反親和性(Anti-Affinity):允許將一個(gè)業(yè)務(wù)的Pod資源對(duì)象的多副本實(shí)例調(diào)度到不同的節(jié)點(diǎn)上,以實(shí)現(xiàn)高可用性,例如訂單服務(wù)的POD期望有三個(gè)副本,將三個(gè)副本部署在不同的節(jié)點(diǎn)上。
Pod資源對(duì)象目前支持兩種親和性和一種反親和性:
- NodeAffinity:節(jié)點(diǎn)親和性,將某個(gè)Pod資源對(duì)象調(diào)度到特定的節(jié)點(diǎn)上,如需要GPU的POD調(diào)度到有GPU的節(jié)點(diǎn)上;
- PodAffinity:Pod資源對(duì)象親和性,將某個(gè)Pod資源對(duì)象調(diào)度到與另一個(gè)Pod資源對(duì)象相鄰的位置,例如調(diào)度到同一主機(jī),調(diào)度到同一硬件集群,調(diào)度到同一機(jī)房,以縮短網(wǎng)絡(luò)傳輸延時(shí);
- PodAntiAffinity:Pod資源對(duì)象反親和性,將一個(gè)Pod資源對(duì)象的多副本實(shí)例調(diào)度到不同的節(jié)點(diǎn)上,調(diào)度到不同的硬件集群上等,這樣可以降低風(fēng)險(xiǎn)并提升Pod資源對(duì)象的可用性。
內(nèi)置調(diào)度算法
kube-scheduler調(diào)度器默認(rèn)提供了兩類調(diào)度算法,分別是預(yù)選調(diào)度算法和優(yōu)選調(diào)度算法。
- 預(yù)選調(diào)度算法:檢查節(jié)點(diǎn)是否符合運(yùn)行“待調(diào)度Pod資源對(duì)象”的條件,如果符合條件,則將其加入可用節(jié)點(diǎn)列表;
- 優(yōu)選調(diào)度算法:為每一個(gè)可用節(jié)點(diǎn)計(jì)算出一個(gè)最終分?jǐn)?shù),kube-scheduler調(diào)度器會(huì)將分?jǐn)?shù)最高的節(jié)點(diǎn)作為最優(yōu)運(yùn)行“待調(diào)度Pod資源對(duì)象”的節(jié)點(diǎn)。
本文轉(zhuǎn)載自微信公眾號(hào)「Java藝術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java藝術(shù)公眾號(hào)。