前言
大家好,我是秋意零。
上一篇結(jié)束了 Pod 對象的內(nèi)容。
今天要探討的內(nèi)容是 “控制器”,它是 Kubernetes 編排最核心的功能。理解了 “控制器”,你就能理解 Deployment、StatefulSet、DaemontSet、Job、CroJob 控制器對象。
最近搞了一個扣扣群,旨在技術(shù)交流、博客互助,希望各位大佬多多支持!
獲取方式:
- 1.在我主頁推廣區(qū)域,如圖:
- 2.文章底部推廣區(qū)域,如圖:
?? 簡介
- ?? 個人主頁: 秋意零
- ?? 個人介紹:在校期間參與眾多云計算相關(guān)比賽,如:?? “省賽”、“國賽”,并斬獲多項獎項榮譽證書
- ?? 目前狀況:24 屆畢業(yè)生,拿到一家私有云(IAAS)公司 offer,暑假開始實習(xí)
- ?? 賬號:各個平臺, 秋意零 賬號創(chuàng)作者、 云社區(qū) 創(chuàng)建者
- ??歡迎大家:歡迎大家一起學(xué)習(xí)云計算,走向年薪 30 萬
系列文章目錄
【云原生|探索 Kubernetes-1】容器的本質(zhì)是進(jìn)程
【云原生|探索 Kubernetes-2】容器 Linux Cgroups 限制
【云原生|探索 Kubernetes 系列 3】深入理解容器進(jìn)程的文件系統(tǒng)
【云原生|探索 Kubernetes 系列 4】現(xiàn)代云原生時代的引擎
【云原生|探索 Kubernetes 系列 5】簡化 Kubernetes 的部署,深入解析其工作流程
更多點擊專欄查看:深入探索 Kubernetes
正文開始:
- 快速上船,馬上開始掌舵了(Kubernetes),距離開船還有 3s,2s,1s…
一、控制器模型
在 Kubernetes中,控制器模式是一種用于管理和維護(hù)資源對象的模式??刂破髂J交?Kubernetes 的聲明式配置和自動化管理原則,通過監(jiān)視資源對象的狀態(tài)和變化,以及根據(jù)期望狀態(tài)進(jìn)行調(diào)諧和調(diào)整,實現(xiàn)對應(yīng)用程序的自動化部署、擴展、修復(fù)和管理。
Pod 這個看似復(fù)雜的 API 對象,實際上就是對容器的進(jìn)一步抽象和封裝而已。
更形象說明就是,“容器鏡像” 雖然好用,但是容器這樣一個 “沙盒” 的概念,對應(yīng)用描述關(guān)聯(lián)性來說,還是太簡單了。好比,碼頭的集裝箱好用,但是它四面都是光禿禿的,吊車怎么把它這個集裝箱吊起來擺放好呢?(這個擺放過程可以看作編排)
因為,一個容器通常是一個應(yīng)用 APP,但是現(xiàn)實中基本上不存在一個 APP 就能提供所有服務(wù),必然要使用一些輔助程序,如:Redis、RabbitMQ、MySQL等等中間件;所以,對比到 “一個容器” ,它是不能滿足現(xiàn)實中的情況的,因為需要輔助程序,這種情況下 Kubernetes 使用了 Pod。
Pod 對象,其實就是容器的升級版。它對容器進(jìn)行了組合,添加了更多的屬性和字段。這就好比給集裝箱四面安裝了吊環(huán),使得 Kubernetes 這架 “吊車”,可以更輕松地操作它。
而 Kubernetes 操作這些 “集裝箱“ 的邏輯,都是控制器(Controller)負(fù)責(zé)完成。
現(xiàn)在,我們看一個 Deployment 控制器的栗子:
- Deployment 通過
spec.selector.matchLabels
攜帶了app=myapp
標(biāo)簽與 Pod 綁定,這樣 Deployment 就能控制于它具有相同標(biāo)簽的 Pod 了;通過spec.replicas
指定 Pod 期望個數(shù),Deployment 控制器會將 Pod 一直保持在 3 個,少了會創(chuàng)建,多了會刪除。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 3 # 指定副本數(shù)量
selector:
matchLabels:
app: myapp # 選擇標(biāo)簽為`app: myapp`的Pod進(jìn)行管理
template:
metadata:
labels:
app: myapp # Pod的標(biāo)簽
spec:
containers:
- name: myapp-web
image: nginx # 指定應(yīng)用程序的鏡像
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 # 應(yīng)用程序監(jiān)聽的端口號
驗證
[root@master01 yaml]# kubectl apply -f deploy-web.yaml
deployment.apps/myapp-deployment created
[root@master01 yaml]# kubectl get -f deploy-web.yaml
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deployment 3/3 3 3 6s
[root@master01 yaml]#
[root@master01 yaml]# kubectl get pod |grep deploy
myapp-deployment-764dfc58c9-dbfrm 1/1 Running 0 16s
myapp-deployment-764dfc58c9-jwghb 1/1 Running 0 16s
myapp-deployment-764dfc58c9-z2n7t 1/1 Running 0 16s
二、控制循環(huán)
上述的控制操作,是 kube-controller-manager 組件負(fù)責(zé)的,而所有的控制器都在 kubernetes/pkg/controller 中,如圖:
源碼的 kubernetes/pkg/controller
目錄下,保存的都是控制器。它們都遵循 Kubernetes 項目中的一個通用編排模式,即:控制循環(huán)(control loop)。
Go 語言偽代碼表示控制循環(huán):
- 獲取對象的兩種狀態(tài)的值,從而對兩種狀態(tài)的值做比較,等于什么都不做,不等于就讓 Pod 保持到期望狀態(tài)的個數(shù)。
for {
實際狀態(tài)個數(shù) := 獲取集群中對象X的實際狀態(tài)(Actual State)
期望狀態(tài)個數(shù) := 獲取集群中對象X的期望狀態(tài)(Desired State)
if 實際狀態(tài)個數(shù) == 期望狀態(tài)個數(shù){
什么都不做
} else {
執(zhí)行編排動作,將實際狀態(tài)調(diào)整為期望狀態(tài)
}
}
1.實際狀態(tài):
- 實際狀態(tài)個數(shù),就是 Kubernetes 集群中,真實運行的受 Deployment 控制器管理的 Pod 的個數(shù)。這個值可以通過 kubelet 通過心跳匯報的容器狀態(tài)和節(jié)點狀態(tài),或者監(jiān)控系統(tǒng)中保存的應(yīng)用監(jiān)控數(shù)據(jù),來獲取。
2.期望狀態(tài):
- 期望狀態(tài),來自于用戶提交的 YAML 文件中的
spec.replicas
字段的值。
現(xiàn)在,我們還是以 Deployment 為例,看看控制器實現(xiàn)過程:
- 1.Deployment 控制器從 Etcd 中獲取所有攜帶 “app: myapp” 標(biāo)簽的 Pod,統(tǒng)計它們的數(shù)量,這就是實際狀態(tài)個數(shù)。
- 2.獲取 Deployment 對象的
spec.replicas
字段的值,這就是期望狀態(tài)個數(shù)。 - 3.Deployment 控制器將這兩個狀態(tài)的值做比較,根據(jù)是否相等來判斷實際狀態(tài)個數(shù)是否達(dá)到期望狀態(tài)的個數(shù),如果沒有就判斷是增加 Pod 還是刪減 Pod。
可以看到,一個 Kubernetes 對象的主要編排邏輯,實際上是在第三步的 “對比” 階段完成的。
這個操作,通常被叫作調(diào)諧(Reconcile)。這個調(diào)諧的過程,則被稱作“Reconcile Loop”(調(diào)諧循環(huán))或者“Sync Loop”(同步循環(huán))。它們其實指的都是同一個東西:控制循環(huán)。
被這個循環(huán)控制的部分,是 Deployment 中的 spec.template
字段,template 字段這個在 Deployment 中是 PodTemplate(Pod 模板)。如下圖所示,類似 Deployment 這樣的一個控制器,實際上都是由上半部分的控制器定義(包括期望狀態(tài)),加上下半部分的被控制對象的模板組成的。
下圖中,Deployment (nginx-deployment)是直接控制 Pod(nginx)的嗎?其實不是 Deployment 直接控制 ReplicaSet,ReplicaSet 再次控制 Pod 對象。
通過這種被誰是誰的控制對象的概念,其實是通過 API 對象的 Metadata 里,都有一個字段叫作 ownerReference, 用于保存擁有者 API 對象(Owner)的信息來分辨的。
- 圖中,我們查看了,通過 Deployment 控制器所創(chuàng)建的 Pod 的信息,可以看到框出的部分 ownerReference 的 API 對象是 ReplicaSet。
- 我們再來驗證查看 RplicaSet 的 ownerReference 是不是 Deployment,如圖:
總結(jié)
今天,說明了 ”控制器模式“ 的方法。
如:Deployment 它的控制循環(huán)是如何工作的,這個部分我們介紹了一個 Go 語言的偽代碼。
接著,簡單介紹了,Kubernetes 是如何來區(qū)分誰是誰的控制對象的,答案是:使用 ownerReference 用于保存擁有者 API 對象(Owner)的信息來分辨的。
最后:技術(shù)交流、博客互助,點擊下方或主頁推廣加入哦??!文章來源:http://www.zghlxwxcb.cn/news/detail-500279.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-500279.html
到了這里,關(guān)于【探索 Kubernetes|作業(yè)管理篇 系列 11】控制器的核心功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!