?1.pod的相關(guān)知識
1.1 pod的基礎(chǔ)概念?
pod是kubernetes中最小的資源管理組件,Pod也是最小化運(yùn)行容器化應(yīng)用的資源對象。一個(gè)Pod代表著集群中運(yùn)行的一個(gè)進(jìn)程。kubernetes中其他大多數(shù)組件都是用繞著Pod來進(jìn)行支撐和擴(kuò)展Pod功能的,例如,用于管理pod運(yùn)行的StatefulSet和Deploment等控制器對象,用于暴露pod應(yīng)用的service和Ingress對象,為pod提供存儲(chǔ)的persistentVolme存儲(chǔ)資源對象等。
?
1.2 k8s中pod的兩種使用方式?
?(1)一個(gè)pod中運(yùn)行一個(gè)容器。"每個(gè)po中一個(gè)容器"的模式是最常見的用法:在這種使用方式中,你可以把pod想象成是單個(gè)容器的封裝,kterentes管理的是Pod而不是直接管理容器。
(2)在一個(gè)Pod中同時(shí)運(yùn)行多個(gè)容器。一個(gè)Pod中也可以同時(shí)封裝幾個(gè)需要緊密耦合互相協(xié)作的容器,它們之間共享資源。這些在同一個(gè)Pod中的容器可以互相協(xié)作成為一個(gè)servie單位,比如一個(gè)容器共享文件,另一個(gè)"sidecar"容器(邊車容器)來更新這些文件。Pod將這些突器的存儲(chǔ)資源作為一個(gè)實(shí)體來管理?
?
?1.3 pod 容器的常規(guī)使用流程?
一個(gè)Pod下的容器必須運(yùn)行于同一節(jié)點(diǎn)上?,F(xiàn)代容器技術(shù)建議一個(gè)容器只運(yùn)行一個(gè)進(jìn)程,該進(jìn)程在容器中PID命名空間中的進(jìn)程號為1,可直接接收并處理信號,進(jìn)程終止時(shí)容器生命周期也就結(jié)束了。若想在容器內(nèi)運(yùn)行多個(gè)進(jìn)程,需要有一個(gè)類似Linux操作系統(tǒng)init進(jìn)程的管控類進(jìn)程,以樹狀結(jié)構(gòu)完成多進(jìn)程的生命周期管理。運(yùn)行于各自容器內(nèi)的進(jìn)程無法直接完成網(wǎng)絡(luò)通信,這是由于容器間的隔離機(jī)制導(dǎo)致,k8s中的Pod資源抽象正是解決此類問題,Pod對象是一組容器的集合,這些容器共享NET、MNT、UTS及IPC命名空間,因此具有相同的域名、主機(jī)名和網(wǎng)絡(luò)接口,并可通過IPC直接通信。
?
Pod資源中針對各容器提供網(wǎng)絡(luò)命名空間等共享機(jī)制的是底層基礎(chǔ)容器pause,基礎(chǔ)容器(也可稱為父容器)pause就是為了管理Pod容器間的共享操作,這個(gè)父容器需要能夠準(zhǔn)確地知道如何去創(chuàng)建共享運(yùn)行環(huán)境的容器,還能管理這些容器的生命周期。為了實(shí)現(xiàn)這個(gè)父容器的構(gòu)想,kubernetes中,用pause容器來作為一個(gè)Pod中所有容器的父容器。這個(gè)pause容器有兩個(gè)核心的功能,一是它提供整個(gè)Pod的Linux命名空間的基礎(chǔ)。二來啟用PID命名空間,它在每個(gè)Pod中都作為PID為1進(jìn)程(init進(jìn)程),并回收僵尸進(jìn)程。
?
?
1.4 k8s中pod結(jié)構(gòu)設(shè)計(jì)的巧妙用意
(1)在一組容器作為一個(gè)單元的情況下,難以對整體的容器簡單地進(jìn)行判斷及有效地進(jìn)行行動(dòng)。比如,一個(gè)容器死亡了,此時(shí)是算整體掛了么?那么引入與業(yè)務(wù)無關(guān)的Pause容器作為Pod的基礎(chǔ)容器,以它的狀態(tài)代表著整個(gè)容器組的狀態(tài),這樣就可以解決該問題。
(2)Pod里的多個(gè)應(yīng)用容器共享Pause容器的IP,共享Pause容器掛載的Volume,這樣簡化了應(yīng)用容器之間的通信問題,也解決了容器之間的文件共享問題。
?
?文章來源:http://www.zghlxwxcb.cn/news/detail-510600.html
通常把Pod分為兩類
●自主式Pod
這種Pod本身是不能自我修復(fù)的,當(dāng)Pod被創(chuàng)建后 (不論是你直接創(chuàng)建還是被其他的Controller),都會(huì)kuberentes調(diào)度到集群的node上。直到node的進(jìn)程終止、被刪掉、因?yàn)槿鄙儋Y源而被驅(qū)逐、或者node節(jié)點(diǎn)故障之前都會(huì)一直保持在那個(gè)node上。pod不會(huì)自愈。如果pod運(yùn)行時(shí),所在的node節(jié)點(diǎn) 故障,或者是調(diào)度器本身故障,這個(gè)pod就會(huì)被刪除。同樣的,如果Pod所在Node缺少資源或者Pod處于維護(hù)狀態(tài),Pod也會(huì)被驅(qū)逐。
●控制器管理的Pod?
Kubernetes使用更高級的概為controller的抽象層,來管理pod實(shí)例。controller可以創(chuàng)建和管理多個(gè)pod,提供副本管理、滾動(dòng)升級和集群級別的自愈能力。例如,如果一個(gè)Node故障,Controller就能自動(dòng)將該節(jié)點(diǎn)上的Pod調(diào)度到其他健康的node上。雖然可以直接使用Pod,但是在Kubernetes中通常是使用controller來管理Pod的。
?
●靜態(tài)Pod
靜態(tài) Pod 直接由特定節(jié)點(diǎn)上的 kubelet 進(jìn)程來管理,不通過 master 節(jié)點(diǎn)上的 apiserver 。無法與控制器 Deployment 或者 DaemonSet 進(jìn)行關(guān)聯(lián),它由 kubelet 進(jìn)程自己來監(jiān)控,當(dāng) pod 崩潰時(shí)重啟該 pod , kubelet也無法對他們進(jìn)行健康檢查。靜態(tài) pod 始終綁定在某一個(gè) kubelet ,并且始終運(yùn)行在同一個(gè)節(jié)點(diǎn)上。 kubelet 會(huì)自動(dòng)為每一個(gè)靜態(tài) pod 在 Kubernetes 的 apiserver 上創(chuàng)建一個(gè)鏡像 Pod(Mirror Pod),因此我們可以在 apiserver 中查詢到該 pod,但是不能通過 apiserver 進(jìn)行控制(例如不能刪除)。
?
靜態(tài)POD配置文件存放位置設(shè)置
/var/lib/kubelet/config.yaml
?
systemctl status kubelet
/usr/lib/systemd/system/kubelet.service.d
? ? ?└─10-kubeadm.confvim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allowprivileged=true"systemctl daemon-reload
systemctl restart kubelet
?
?
#在靜態(tài)Pod文件的管理目錄下準(zhǔn)備 Pod 的 Json 或者 Yaml 文件
vim /etc/kubernetes/manifests/static-web.yaml
?
運(yùn)行中的 kubelet 周期掃描配置的目錄下文件的變化,當(dāng)這個(gè)目錄中有文件出現(xiàn)或消失時(shí)創(chuàng)建或刪除 pods。
在 Master 節(jié)點(diǎn)同樣也可以看到該 Pod,如果執(zhí)行 kubectl delete pod static-web-node01 命令刪除該 Pod 發(fā)現(xiàn),并不能刪除。
?
?
2. 容器的分類
2.1 ?pause基礎(chǔ)容器(infrastructure?container)
- 維護(hù)整個(gè)Pod網(wǎng)絡(luò)和存儲(chǔ)空間
- 啟動(dòng)一個(gè)容器時(shí),k8s會(huì)自動(dòng)啟動(dòng)一個(gè)基礎(chǔ)容器
pause容器的作用?
- 在pod中擔(dān)任Linux命名空間( 如網(wǎng)絡(luò)命令空間)共享的基礎(chǔ)
- 啟用PID命名空間,開啟init進(jìn)程。
網(wǎng)絡(luò):
每個(gè)Pod都會(huì)被分配一個(gè)唯一的IP地址。Pod中的所 有容器共享網(wǎng)絡(luò)空間,包括IP地址和端口。Pod內(nèi) 部的容器可以使用localhost互相通信。Pod中的容器與外界通信時(shí),必須分配共享網(wǎng)絡(luò)資源(例如使用宿主機(jī)的端口映射)
存儲(chǔ):
可以Pod指定多個(gè)共享的Volume. Pod中 的所有容器都可以訪問共享的Volume,Volume 也可以用來持久化Pod中的存儲(chǔ)資源,以防容器重啟后文件丟失。
?
?
總結(jié):
每個(gè)Pod都有一個(gè)特殊的被稱為“基礎(chǔ)容器"的Pause容器。Pause 容器對應(yīng)的鏡像屬于Kubernetes平臺(tái)的- - 部分,除了Pause容器,每個(gè)Pod還包含一個(gè)或者多個(gè)緊密相關(guān)的用戶應(yīng)用容器。?
2.2 init初始化容器
每個(gè)?pod中可以包含多個(gè)容器, 應(yīng)用運(yùn)行在這些容器里面,同時(shí) Pod 也可以有一個(gè)或多個(gè)先于應(yīng)用容器啟動(dòng)的 Init 容器。
Init 容器與普通的容器非常像,除了如下兩點(diǎn):
- 它們總是運(yùn)行到完成。
- 每個(gè)都必須在下一個(gè)啟動(dòng)之前成功完成。
如果 Pod 的 Init 容器失敗,kubelet 會(huì)不斷地重啟該 Init 容器直到該容器成功為止。 然而,如果 Pod 對應(yīng)的 restartPolicy 值為 "Never",并且 Pod 的 Init 容器失敗, 則 Kubernetes 會(huì)將整個(gè) Pod 狀態(tài)設(shè)置為失敗。
為 Pod 設(shè)置 Init 容器需要在pod規(guī)則中添加 initContainers 字段, 該字段以 container類型對象數(shù)組的形式組織,和應(yīng)用的 containers 數(shù)組同級相鄰。 參閱 API 參考的容器章節(jié)了解詳情。
Init 容器的狀態(tài)在 status.initContainerStatuses 字段中以容器狀態(tài)數(shù)組的格式返回 (類似 status.containerStatuses 字段)。
?
2.3?init容器和普通容器的區(qū)別?
Init 容器支持應(yīng)用容器的全部字段和特性,包括資源限制、數(shù)據(jù)卷和安全設(shè)置。 然而,Init 容器對資源請求和限制的處理稍有不同,在下面資源節(jié)有說明。
同時(shí) Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe, 因?yàn)樗鼈儽仨氃?Pod 就緒之前運(yùn)行完成。
如果為一個(gè) Pod 指定了多個(gè) Init 容器,這些容器會(huì)按順序逐個(gè)運(yùn)行。 每個(gè) Init 容器必須運(yùn)行成功,下一個(gè)才能夠運(yùn)行。當(dāng)所有的 Init 容器運(yùn)行完成時(shí), Kubernetes 才會(huì)為 Pod 初始化應(yīng)用容器并像平常一樣運(yùn)行。
?
2.3 Init 容器的使用?
因?yàn)?Init 容器具有與應(yīng)用容器分離的單獨(dú)鏡像,其啟動(dòng)相關(guān)代碼具有如下優(yōu)勢:
Init 容器可以包含一些安裝過程中應(yīng)用容器中不存在的實(shí)用工具或個(gè)性化代碼。 例如,沒有必要僅為了在安裝過程中使用類似 sed、awk、python 或 dig 這樣的工具而去 FROM 一個(gè)鏡像來生成一個(gè)新的鏡像。
應(yīng)用鏡像的創(chuàng)建者和部署者可以各自獨(dú)立工作,而沒有必要聯(lián)合構(gòu)建一個(gè)單獨(dú)的應(yīng)用鏡像。
與同一 Pod 中的多個(gè)應(yīng)用容器相比,Init 容器能以不同的文件系統(tǒng)視圖運(yùn)行。因此,Init 容器可以被賦予訪問應(yīng)用容器不能訪問的 Secret的權(quán)限。
由于 Init 容器必須在應(yīng)用容器啟動(dòng)之前運(yùn)行完成,因此 Init 容器提供了一種機(jī)制來阻塞或延遲應(yīng)用容器的啟動(dòng),直到滿足了一組先決條件。 一旦前置條件滿足,Pod 內(nèi)的所有的應(yīng)用容器會(huì)并行啟動(dòng)。
Init 容器可以安全地運(yùn)行實(shí)用程序或自定義代碼,而在其他方式下運(yùn)行這些實(shí)用程序或自定義代碼可能會(huì)降低應(yīng)用容器鏡像的安全性。 通過將不必要的工具分開,你可以限制應(yīng)用容器鏡像的被攻擊范圍
?
運(yùn)行特例
在Pod啟動(dòng)過程中,Init容器會(huì)按順序在網(wǎng)絡(luò)和數(shù)據(jù)卷初始化之后啟動(dòng)。每個(gè)容器必須在下一個(gè)容器啟動(dòng)之前成功退出。
如果由于運(yùn)行時(shí)或失敗退出,將導(dǎo)致容器啟動(dòng)失敗,它會(huì)根據(jù)Podl的restartPolicy指定的策略(該策略又分為 Always , Never ,OnFailure)進(jìn)行重試。然而,如果Pod的restartPolicy設(shè)置為Always,Init容器失敗時(shí)會(huì)使用RestartPolicy策略。
在所有的Init容器沒有成功之前,Pod將不會(huì)變成Ready狀態(tài)。Init容器的端口將不會(huì)在service中進(jìn)行聚集。正在初始化中的Pod處于Pending狀態(tài),但應(yīng)該會(huì)將Initializing狀態(tài)設(shè)置為true。
如果Pod重啟,所有Init容器必須重新執(zhí)行。
對Init容器spec的修改被限制在容器image字段,修改其他字段都不會(huì)生效。更改Init容器的image字段,等價(jià)于重啟該P(yáng)od。
Init容器具有應(yīng)用容器的所有字段。除了readinessProbe,因?yàn)門nit容器無法定義不同于完成(completion)的就緒(readiness)之外的其他狀態(tài)。這會(huì)在驗(yàn)證過程中強(qiáng)制執(zhí)行。
在Pod中的每個(gè)app和Init容器的名稱必須唯一;與任何其它容器共享同一個(gè)名稱,會(huì)在驗(yàn)證時(shí)拋出錯(cuò)誤.
?
2.4 應(yīng)用容器(業(yè)務(wù)容器,Maincontainer)?
?提供業(yè)務(wù)服務(wù),它是并行啟動(dòng),要在所以Init容器成功的完成啟動(dòng)、運(yùn)行和退出后才會(huì)啟動(dòng)應(yīng)用容器
?
3. 模擬演練
官網(wǎng)示例:
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
編寫yaml文件
vim myapp-pod.yaml
apiVersion: v1
kind: Pod
metadata:
? name: myapp-pod
? labels:
? ? app: myapp
spec:
? containers:
? - name: myapp-container
? ? image: busybox:1.28
? ? command: ['sh', '-c', 'echo The app is running! && sleep 3600']
? initContainers:
? - name: init-myservice
? ? image: busybox:1.28
? ? command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
? - name: init-mydb
? ? image: busybox:1.28
? ? command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
###這個(gè)例子是定義了一個(gè)具有 2 個(gè) Init 容器的簡單 Pod。 第一個(gè)等待 myservice 啟動(dòng), 第二個(gè)等待 mydb 啟動(dòng)。 一旦這兩個(gè) Init容器都啟動(dòng)完成,Pod 將啟動(dòng) spec 中的應(yīng)用容器
kubectl apply -f? ?myapp-pod.yaml
?
kubectl describe pod myapp-podkubectl logs myapp-pod -c init-myservice
?
vim myservice.yaml
apiVersion: v1
kind: Service
metadata:
? name: myservice
spec:
? ports:
? - protocol: TCP
? ? port: 80
? ? targetPort: 9376
?? ?
kubectl create -f myservice.yaml
kubectl get svc
kubectl get pods -n kube-system
kubectl get pods
vim mydb.yaml
apiVersion: v1
kind: Service
metadata:
? name: mydb
spec:
? ports:
? - protocol: TCP
? ? port: 80
? ? targetPort: 9377
?? ?
kubectl create -f mydb.yamlkubectl get pods
?
//特別說明:
●在Pod啟動(dòng)過程中,Init容器會(huì)按順序在網(wǎng)絡(luò)和數(shù)據(jù)卷初始化之后啟動(dòng)。每個(gè)容器必須在下一個(gè)容器啟動(dòng)之前成功退出。
●如果由于運(yùn)行時(shí)或失敗退出,將導(dǎo)致容器啟動(dòng)失敗,它會(huì)根據(jù)Pod的restartPolicy指定的策略進(jìn)行重試。然而,如果Pod的restartPolicy設(shè)置為Always,Init容器失敗時(shí)會(huì)使用RestartPolicy策略。
●在所有的Init容器沒有成功之前,Pod將不會(huì)變成Ready狀態(tài)。Init容器的端口將不會(huì)在Service中進(jìn)行聚集。正在初始化中的Pod處于Pending狀態(tài),但應(yīng)該會(huì)將Initializing狀態(tài)設(shè)置為true。
●如果Pod重啟,所有Init容器必須重新執(zhí)行。
●對Init容器spec的修改被限制在容器image字段,修改其他字段都不會(huì)生效。更改Init容器的image字段,等價(jià)于重啟該P(yáng)od。
●Init容器具有應(yīng)用容器的所有字段。除了readinessProbe,因?yàn)镮nit容器無法定義不同于完成(completion)的就緒(readiness)之外的其他狀態(tài)。這會(huì)在驗(yàn)證過程中強(qiáng)制執(zhí)行。
●在Pod中的每個(gè)app和Init容器的名稱必須唯一;與任何其它容器共享同一個(gè)名稱,會(huì)在驗(yàn)證時(shí)拋出錯(cuò)誤。文章來源地址http://www.zghlxwxcb.cn/news/detail-510600.html
到了這里,關(guān)于【云原生】k8s的pod基礎(chǔ)(上)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!