1 什么是 Pod
摘取官網(wǎng): https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/#working-with-pods
1.1 簡介
Pod 是可以在 Kubernetes 中創(chuàng)建和管理的、最小的可部署的計算單元。Pod(就像在鯨魚莢或者豌豆莢中)是一組(一個或多個)容器; 這些容器共享存儲、網(wǎng)絡(luò)、以及怎樣運行這些容器的聲明。 Pod 中的內(nèi)容總是并置(colocated)的并且一同調(diào)度,在共享的上下文中運行。簡言之如果用 Docker 的術(shù)語來描述,Pod 類似于共享名字空間并共享文件系統(tǒng)卷的一組容器。
定義: Pod 就是用來管理一組(一個|多個)容器的集合 特點: 共享網(wǎng)絡(luò) 共享存儲 共享上下文環(huán)境
1.2 Pod 怎樣管理多個容器?
一般將多個緊密協(xié)作
的容器放入到一個Pod中,當一個Pod包含多個容器時,這些容器總是運行于同一個工作節(jié)點上,一個pod絕不會跨多個工作節(jié)點。
Pod 中的容器被自動安排到集群中的同一物理機或虛擬機上,并可以一起進行調(diào)度。 容器之間可以共享資源和依賴、彼此通信、協(xié)調(diào)何時以及何種方式終止自身。例如,你可能有一個容器,為共享卷中的文件提供 Web 服務(wù)器支持,以及一個單獨的 “邊車 (sidercar)” 容器負責從遠端更新這些文件。Pod多容器的使用常見場景
- 日志收集,通過log agent來上報日志信息
- sidecar模式,接管限流、降級等基礎(chǔ)功能
- 功能輔助,本地調(diào)用等場景
pod內(nèi)多個容器之間共享的部分:
- 網(wǎng)絡(luò)命名空間: IP地址、端口范圍、路由表…,同一Pod下容器不能綁定相同端口
- UTS命名空間: 主機名,同一Pod下容器擁有相同hostname
- IPC命名空間:UNIX域socket
由于共享端口空間,在同一pod的容器中運行的進程不能綁定到相同的端口號,而其他pod中的進程有自己的網(wǎng)絡(luò)接口和端口空間,從而消除了不同pod之間的端口沖突。
pod內(nèi)多個容器之間不共享的部分:
- 容器的文件系統(tǒng)(Mount Namespace)與其他容器完全隔離,但我們可以使用名為volume的Kubernetes資源來共享文件目錄
- 容器的進程空間(PID Namespace)默認與其他容器完全隔離,不過可以設(shè)置POD的shareProcessNamespace這個值為true來進行共享
從圖上我們可以看出 - Pod內(nèi)的兩個容器不能綁定同一端口
- 兩容器共享同一網(wǎng)絡(luò)空間
- 容器之間可以通過回環(huán)地址通信127.0.0.1
1.3 為什么"多容器的pod"要強于"單容器多進程"
- 容器只能管理PID=1的進程,這個進程是容器內(nèi)(通過與PID Namespace隔離)所有進程的父進程
- 如果單容器運行多個進程,那么保持所有進程運行,管理它們的日志,就落到集群的肩上,比如需要包含一個進程崩潰時能自動重啟的機制,因為容器只在根進程死亡時才會重啟容器,而不在乎它創(chuàng)建哪些子進程
- 同時這些進程都將記錄到相同的標準輸出中,而因此我們將很難確定每個進程分別記錄了什么
1.4 如何使用 Pod?
通常不需要直接創(chuàng)建 Pod,甚至單實例 Pod。 相反,一般會使用諸如 Deployment 或 Job 這類工作負載資源來創(chuàng)建 Pod。 如果 Pod 需要跟蹤狀態(tài),可以考慮 StatefulSet 資源,將在之后學習這些資源。
Kubernetes 集群中的 Pod 主要有兩種用法:
- 運行單個容器的 Pod?!懊總€ Pod 一個容器” 模型是最常見的 Kubernetes 用例; 在這種情況下,可以將 Pod 看作單個容器的包裝器,并且 Kubernetes 直接管理 Pod,而不是容器。
- 運行多個協(xié)同工作的容器 的 Pod。 Pod 可能封裝由多個緊密耦合且需要共享資源的共處容器組成的應(yīng)用程序。 這些位于同一位置的容器可能形成單個內(nèi)聚的服務(wù)單元 —— 一個容器將文件從共享卷提供給公眾, 而另一個單獨的 “邊車”(sidecar)容器則刷新或更新這些文件。 Pod 將這些容器和存儲資源打包為一個可管理的實體。
說明:
- 將多個并置、同管的容器組織到一個 Pod 中是一種相對高級的使用場景。 只有在一些場景中,容器之間緊密關(guān)聯(lián)時你才應(yīng)該使用這種模式。
- 每個 Pod 都旨在運行給定應(yīng)用程序的單個實例。如果希望橫向擴展應(yīng)用程序 (例如,運行多個實例以提供更多的資源),則應(yīng)該使用多個 Pod,每個實例使用一個 Pod。 在 Kubernetes 中,這通常被稱為副本(Replication)。 通常使用一種工作負載資源及其控制器來創(chuàng)建和管理一組 Pod 副本。
2 Pod 基本操作
2.1 查看 pod
# 查看默認命名空間的 pod
$ kubectl get pods|pod|po
# 查看所有命名空間的 pod
$ kubectl get pods|pod -A
$ kubectl get pods|pod|po -n 命名空間名稱
# 查看默認命名空間下 pod 的詳細信息
$ kubectl get pods -o wide
# 查看所有命名空間下 pod 的詳細信息
$ kubectl get pods -o wide -A
# 實時監(jiān)控 pod 的狀態(tài)
$ kubectl get pod -w
2.2 創(chuàng)建 pod
pod : kubectl run nginx(pod名稱) --image=nginx:1.19
container: docker run --name nginx nginx:1.19
官網(wǎng)參考地址: https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/pod-v1/
# nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# 使用 kubectl apply/create -f 創(chuàng)建 pod
$ kubectl create -f nginx-pod.yml
$ kubectl apply -f nginx-pod.yml
注意: create 僅僅是不存在時創(chuàng)建,如果已經(jīng)存在則報錯!apply 不存在創(chuàng)建,存在更新配置。推薦使用 apply!
2.3 刪除 pod
$ kubectl delete pod pod名稱
$ kubectl delete -f pod.yml
2.4 進入 pod 中容器
# 注意: 這種方式進入容器默認只會進入 pod 中第一個容器
$ kubectl exec -it nginx(pod名稱) --(固定寫死) bash(執(zhí)行命令)
# 注意: 進入指定 pod 中指定容器
$ kubectl exec -it pod名稱 -c 容器名稱 --(固定寫死) bash(執(zhí)行命令)
2.5 查看 pod 日志
# 注意: 查看 pod 中第一個容器日志
$ kubectl logs -f(可選,實時) nginx(pod 名稱)
# 注意: 查看 pod 中指定容器的日志
$ kubect logs -f pod名稱 -c 容器名稱
2.6 查看 pod 描述信息
$ kubectl describe pod nginx(pod名稱)
3 Pod 運行多個容器
3.1 創(chuàng)建 pod
# myapp-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
imagePullPolicy: IfNotPresent
- name: redis
image: redis:5.0.10
ports:
- containerPort: 6379
imagePullPolicy: IfNotPresent
$ kubectl apply -f myapp-pod.yml
3.2 查看指定容器日志
# 查看日志 (默認只查看第一個容器日志,這里是展示 nginx 日志)
$ kubectl logs -f myapp
# 查看 pod 中指定容器的日志
$ kubectl logs -f myapp -c nginx(容器名稱)
$ kubectl logs -f myapp -c redis(容器名稱)
3.3 進入容器
# 進入 pod 的容器 (默認進入第一個容器內(nèi)部,這里會進入 nginx 容器內(nèi)部)
$ kubectl exec -it myapp -- sh
# 進入 pod 中指定容器內(nèi)部
$ kubectl exec -it myapp -c nginx -- sh
$ kubectl exec -it myapp -c redis -- sh
4 Pod 的 Labels(標簽)
對于微服務(wù)架構(gòu),部署的微服務(wù)數(shù)量可以超過20個,這些組件可以是副本和多個不同發(fā)布版本,如果沒有有效組織這些組件的機制,將會導(dǎo)致產(chǎn)生巨大混亂,因此Kubernetes 對象可附加標簽屬性。標簽(Labels)
是附加到 Kubernetes 對象(比如 Pod)上的鍵值對。 標簽旨在用于指定對用戶有意義且相關(guān)的對象的標識屬性。標簽可以在創(chuàng)建時附加到對象,隨后可以隨時添加和修改。每個對象都可以定義一組鍵(key)/值(value)標簽,但是每個鍵(key)對于給定對象必須是唯一的。
標簽作用: 用來給 k8s 中對象起別名, 有了別名可以方便過濾和篩選
4.1 語法
標簽由鍵值對組成
,其有效標簽值:
- 必須為 63 個字符或更少(可以為空)
- 除非標簽值為空,必須以字母數(shù)字字符(
[a-z0-9A-Z]
)開頭和結(jié)尾 - 包含破折號(
-
)、下劃線(_
)、點(.
)和字母或數(shù)字
4.2 示例
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
name: myapp #創(chuàng)建時添加
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
- name: redis
image: redis:5.0.10
imagePullPolicy: IfNotPresent
restartPolicy: Always
4.3 標簽基本操作
# 查看標簽
$ kubectl get pods --show-labels
# kubectl label pod pod名稱 標簽鍵值對
$ kubectl label pod myapp env=prod
# 覆蓋標簽 --overwrite
$ kubectl label --overwrite pod myapp env=test
# 刪除標簽 -號代表刪除標簽
$ kubectl label pod myapp env-
# 根據(jù)標簽篩選 env=test/env > = <
$ kubectl get po -l env=test
$ kubectl get po -l env
$ kubectl get po -l '!env' # 不包含的 pod
$ kubectl get po -l 'env in (test,prod)' #選擇含有指定值的 pod
$ kubectl get po -l 'env notin (test,prod)' #選擇含有指定值的 pod
5 Pod 的生命周期
摘自官網(wǎng): https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/
Pod 遵循預(yù)定義的生命周期,起始于 Pending
階段, 如果至少其中有一個主要容器正常啟動,則進入 Running
,之后取決于 Pod 中是否有容器以失敗狀態(tài)結(jié)束而進入 Succeeded
或者 Failed
階段。與此同時Pod 在其生命周期中只會被調(diào)度一次。 一旦 Pod 被調(diào)度(分派)到某個節(jié)點,Pod 會一直在該節(jié)點運行,直到 Pod 停止或者被終止。
5.1 生命周期
和一個個獨立的應(yīng)用容器一樣,Pod 也被認為是相對臨時性(而不是長期存在)的實體。 Pod 會被創(chuàng)建、賦予一個唯一的 ID(UID), 并被調(diào)度到節(jié)點,并在終止(根據(jù)重啟策略)或刪除之前一直運行在該節(jié)點。如果一個節(jié)點死掉了,調(diào)度到該節(jié)點的 Pod 也被計劃在給定超時期限結(jié)束后刪除。
Pod 自身不具有自愈能力。如果 Pod 被調(diào)度到某節(jié)點而該節(jié)點之后失效, Pod 會被刪除;類似地,Pod 無法在因節(jié)點資源耗盡或者節(jié)點維護而被驅(qū)逐期間繼續(xù)存活。 Kubernetes 使用一種高級抽象來管理這些相對而言可隨時丟棄的 Pod 實例, 稱作控制器。
任何給定的 Pod (由 UID 定義)從不會被“重新調(diào)度(rescheduled)”到不同的節(jié)點; 相反,這一 Pod 可以被一個新的、幾乎完全相同的 Pod 替換掉。 如果需要,新 Pod 的名字可以不變,但是其 UID 會不同。
如果某物聲稱其生命期與某 Pod 相同,例如存儲卷, 這就意味著該對象在此 Pod (UID 亦相同)存在期間也一直存在。 如果 Pod 因為任何原因被刪除,甚至完全相同的替代 Pod 被創(chuàng)建時, 這個相關(guān)的對象(例如這里的卷)也會被刪除并重建。
5.2 pod 階段
Pod 階段的數(shù)量和含義是嚴格定義的。 除了本文檔中列舉的內(nèi)容外,不應(yīng)該再假定 Pod 有其他的 phase
值。
取值 | 描述 |
---|---|
Pending (懸決) |
Pod 已被 Kubernetes 系統(tǒng)接受,但有一個或者多個容器尚未創(chuàng)建亦未運行。此階段包括等待 Pod 被調(diào)度的時間和通過網(wǎng)絡(luò)下載鏡像的時間。 |
Running (運行中) |
Pod 已經(jīng)綁定到了某個節(jié)點,Pod 中所有的容器都已被創(chuàng)建。至少有一個容器仍在運行,或者正處于啟動或重啟狀態(tài)。 |
Succeeded (成功) |
Pod 中的所有容器都已成功終止,并且不會再重啟。 |
Failed (失?。?/td>
| Pod 中的所有容器都已終止,并且至少有一個容器是因為失敗終止。也就是說,容器以非 0 狀態(tài)退出或者被系統(tǒng)終止。 |
Unknown (未知) |
因為某些原因無法取得 Pod 的狀態(tài)。這種情況通常是因為與 Pod 所在主機通信失敗。 |
說明:
當一個 Pod 被刪除時,執(zhí)行一些 kubectl 命令會展示這個 Pod 的狀態(tài)為
Terminating
(終止)。 這個Terminating
狀態(tài)并不是 Pod 階段之一。 Pod 被賦予一個可以體面終止的期限,默認為 30 秒。 你可以使用--force
參數(shù)來強制終止 Pod。如果某節(jié)點死掉或者與集群中其他節(jié)點失聯(lián),Kubernetes 會實施一種策略,將失去的節(jié)點上運行的所有 Pod 的
phase
設(shè)置為Failed
。
6 Contrainer 特性
6.1 容器生命周期
Kubernetes 會跟蹤 Pod 中每個容器的狀態(tài),就像它跟蹤 Pod 總體上的階段一樣。 你可以使用容器生命周期回調(diào)來在容器生命周期中的特定時間點觸發(fā)事件。
一旦調(diào)度器將 Pod 分派給某個節(jié)點,kubelet
就通過容器運行時開始為 Pod 創(chuàng)建容器。容器的狀態(tài)有三種:Waiting
(等待)、Running
(運行中)和 Terminated
(已終止)。
要檢查 Pod 中容器的狀態(tài),你可以使用 kubectl describe pod <pod 名稱>
。 其輸出中包含 Pod 中每個容器的狀態(tài)。
每種狀態(tài)都有特定的含義:
-
Waiting
(等待)
如果容器并不處在 Running
或 Terminated
狀態(tài)之一,它就處在 Waiting
狀態(tài)。 處于 Waiting
狀態(tài)的容器仍在運行它完成啟動所需要的操作:例如, 從某個容器鏡像倉庫拉取容器鏡像,或者向容器應(yīng)用 Secret 數(shù)據(jù)等等。 當你使用 kubectl
來查詢包含 Waiting
狀態(tài)的容器的 Pod 時,你也會看到一個 Reason 字段,其中給出了容器處于等待狀態(tài)的原因。
-
Running
(運行中)
Running
狀態(tài)表明容器正在執(zhí)行狀態(tài)并且沒有問題發(fā)生。 如果配置了 postStart
回調(diào),那么該回調(diào)已經(jīng)執(zhí)行且已完成。 如果你使用 kubectl
來查詢包含 Running
狀態(tài)的容器的 Pod 時, 你也會看到關(guān)于容器進入 Running
狀態(tài)的信息。
-
Terminated
(已終止)
處于 Terminated
狀態(tài)的容器已經(jīng)開始執(zhí)行并且或者正常結(jié)束或者因為某些原因失敗。 如果你使用 kubectl
來查詢包含 Terminated
狀態(tài)的容器的 Pod 時, 你會看到容器進入此狀態(tài)的原因、退出代碼以及容器執(zhí)行期間的起止時間。
如果容器配置了 preStop
回調(diào),則該回調(diào)會在容器進入 Terminated
狀態(tài)之前執(zhí)行。
6.2 容器生命周期回調(diào)/事件/鉤子
類似于許多具有生命周期回調(diào)組件的編程語言框架,例如 Angular、Vue、Kubernetes 為容器提供了生命周期回調(diào)。 回調(diào)使容器能夠了解其管理生命周期中的事件,并在執(zhí)行相應(yīng)的生命周期回調(diào)時運行在處理程序中實現(xiàn)的代碼。
有兩個回調(diào)暴露給容器:
-
PostStart
這個回調(diào)在容器被創(chuàng)建之后立即被執(zhí)行。 但是,不能保證回調(diào)會在容器入口點(ENTRYPOINT)之前執(zhí)行。 沒有參數(shù)傳遞給處理程序。 -
PreStop
在容器因 API 請求或者管理事件(諸如存活態(tài)探針、啟動探針失敗、資源搶占、資源競爭等) 而被終止之前,此回調(diào)會被調(diào)用。 如果容器已經(jīng)處于已終止或者已完成狀態(tài),則對 preStop 回調(diào)的調(diào)用將失敗。 在用來停止容器的 TERM 信號被發(fā)出之前,回調(diào)必須執(zhí)行結(jié)束。 Pod 的終止寬限周期在PreStop
回調(diào)被執(zhí)行之前即開始計數(shù), 所以無論回調(diào)函數(shù)的執(zhí)行結(jié)果如何,容器最終都會在 Pod 的終止寬限期內(nèi)被終止。 沒有參數(shù)會被傳遞給處理程序。 -
使用容器生命周期回調(diào)
# nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
lifecycle:
postStart: #容器創(chuàng)建過程中執(zhí)行
exec:
command: ["/bin/sh","-c","echo postStart >> /start.txt"]
preStop: #容器終止之前執(zhí)行
exec:
command: ["/bin/sh","-c","echo postStop >> /stop.txt && sleep 5"]
ports:
- containerPort: 80
6.3 容器重啟策略
Pod 的 spec
中包含一個 restartPolicy
字段,其可能取值包括 Always(總是重啟)、OnFailure(容器異常退出狀態(tài)碼非 0,重啟) 和 Never
。默認值是 Always
。
- Always: 容器進程只要退出就重啟,不管退出狀態(tài)是0還是1
- OnFailure: 容器進程以非0狀態(tài)退出,就重啟
- Never: 永不重啟
restartPolicy
適用于 Pod 中的所有容器。restartPolicy
僅針對同一節(jié)點上 kubelet
的容器重啟動作。當 Pod 中的容器退出時,kubelet
會按指數(shù)回退方式計算重啟的延遲(10s、20s、40s、…),其最長延遲為 5 分鐘。 一旦某容器執(zhí)行了 10 分鐘并且沒有出現(xiàn)問題,kubelet
對該容器的重啟回退計時器執(zhí)行重置操作。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
imagePullPolicy: IfNotPresent
restartPolicy: Always # OnFailure Never
6.4 自定義容器啟動命令
和 Docker 容器一樣,k8s中容器也可以通過command、args 用來修改容器啟動默認執(zhí)行命令以及傳遞相關(guān)參數(shù)。但一般推薦使用 command 修改啟動命令,使用 args 為啟動命令傳遞參數(shù)。
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
app: redis
spec:
containers:
- name: redis
image: redis:5.0.10
command: ["redis-server"] #用來指定啟動命令
args: ["--appendonly yes"] # 用來為啟動命令傳遞參數(shù)
#args: ["redis-server","--appendonly yes"] # 單獨使用修改啟動命令并傳遞參數(shù)
#args: # 另一種語法格式
# - redis-server
# - "--appendonly yes"
imagePullPolicy: IfNotPresent
restartPolicy: Always
6.5 容器探針
probe 是由 kubelet對容器執(zhí)行的定期診斷。 要執(zhí)行診斷,kubelet 既可以在容器內(nèi)執(zhí)行代碼,也可以發(fā)出一個網(wǎng)絡(luò)請求。
定義: 容器探針 就是用來定期對容器進行健康檢查的。
探測類型
針對運行中的容器,kubelet
可以選擇是否執(zhí)行以下三種探針,以及如何針對探測結(jié)果作出反應(yīng):
-
livenessProbe
指示容器是否正在運行。如果存活態(tài)探測失敗,則 kubelet 會殺死容器, 并且容器將根據(jù)其重啟策略決定未來。如果容器不提供存活探針, 則默認狀態(tài)為Success
。 -
readinessProbe
指示容器是否準備好為請求提供服。如果就緒態(tài)探測失敗, 端點控制器將從與 Pod 匹配的所有服務(wù)的端點列表中刪除該 Pod 的 IP 地址。 初始延遲之前的就緒態(tài)的狀態(tài)值默認為Failure
。 如果容器不提供就緒態(tài)探針,則默認狀態(tài)為Success
。 -
startupProbe 1.7+
指示容器中的應(yīng)用是否已經(jīng)啟動。如果提供了啟動探針,則所有其他探針都會被 禁用,直到此探針成功為止。如果啟動探測失敗,kubelet
將殺死容器, 而容器依其重啟策略進行重啟。 如果容器沒有提供啟動探測,則默認狀態(tài)為Success
。
探針機制
使用探針來檢查容器有四種不同的方法。 每個探針都必須準確定義為這四種機制中的一種:
-
exec
在容器內(nèi)執(zhí)行命令并檢查它終止時的退出代碼。如果退出代碼為零,則探測成功。非零退出代碼被視為失敗。
-
grpc
使用 gRPC 執(zhí)行一個遠程過程調(diào)用。 目標應(yīng)該實現(xiàn) gRPC健康檢查。 如果響應(yīng)的狀態(tài)是 “SERVING”,則認為診斷成功。 gRPC 探針是一個 Alpha 特性,只有在你啟用了 “GRPCContainerProbe” 特性門控時才能使用。
-
httpGet
對容器的 IP 地址上指定的網(wǎng)絡(luò)端口和路徑上向容器的 IP 地址發(fā)送 GET 請求。如果探測收到響應(yīng),并且響應(yīng)碼不代表錯誤(換句話說,如果 HTTP 響應(yīng)碼是 2xx 或 3xx),則認為探測成功。否則或者沒有及時響應(yīng),則認為探測失敗。
-
tcpSocket
對容器的 IP 地址上的指定端口執(zhí)行 TCP 檢查。如果端口打開,則診斷被認為是成功的。 如果遠程系統(tǒng)(容器)在打開連接后立即將其關(guān)閉,這算作是健康的。
探針結(jié)果
每次探測都將獲得以下三種結(jié)果之一:
-
Success
(成功)容器通過了診斷。 -
Failure
(失敗)容器未通過診斷。 -
Unknown
(未知)診斷失敗,因此不會采取任何行動。
探針參數(shù)
initialDelaySeconds: 5 #初始化時間5s
periodSeconds: 4 #檢測間隔時間4s
timeoutSeconds: 1 #默認檢測超時時間為1s
failureThreshold: 3 #默認失敗次數(shù)為3次,達到3次后重啟pod
successThreshold: 1 #默認成功次數(shù)為1次,1次監(jiān)測成功代表成功
使用探針
- exec
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
exec: exec
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- sleep 7;nginx -g "daemon off;" #這一步會和初始化同時開始運行,也就是在初始化5s后和7秒之間,會檢測出一次失敗,7秒后啟動后檢測正常,所以pod不會重啟
imagePullPolicy: IfNotPresent
livenessProbe:
exec: #這里使用 exec 執(zhí)行 shell 命令檢測容器狀態(tài)
command:
- ls
- /var/run/nginx.pid #查看是否有pid文件
initialDelaySeconds: 5 #初始化時間5s
periodSeconds: 4 #檢測間隔時間4s
timeoutSeconds: 1 #默認檢測超時時間為1s
failureThreshold: 3 #默認失敗次數(shù)為3次,達到3次后重啟pod
successThreshold: 1 #默認成功次數(shù)為1次,1 次代表成功
說明:
- 如果 sleep 7s,第一次檢測發(fā)現(xiàn)失敗,但是第二次檢測發(fā)現(xiàn)成功后容器就一直處于健康狀態(tài)不會重啟。
- 如果 sleep 30s,第一次檢測失敗,超過 3 次檢測同樣失敗,k8s 就回殺死容器進行重啟,反復(fù)循環(huán)這個過程。
- tcpSocket
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcpsocket
labels:
tcpsocket: tcpsocket
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- sleep 7;nginx -g "daemon off;" #這一步會和初始化同時開始運行,也就是在初始化5s后和7秒之間,會檢測出一次失敗,7秒后啟動后檢測正常,所以pod不會重啟
imagePullPolicy: IfNotPresent
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5 #初始化時間5s
periodSeconds: 4 #檢測間隔時間4s
timeoutSeconds: 1 #默認檢測超時時間為1s
failureThreshold: 3 #默認失敗次數(shù)為3次,達到3次后重啟pod
successThreshold: 1 #默認成功次數(shù)為1次,1 次代表成功
- httpGet
# probe-liveness-httget.yml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
labels:
httpget: httpget
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- sleep 7;nginx -g "daemon off;" #這一步會和初始化同時開始運行,也就是在初始化5s后和7秒之間,會檢測出一次失敗,7秒后啟動后檢測正常,所以pod不會重啟
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet: #httpget
port: 80 #訪問的端口
path: /index.html #訪問的路徑
initialDelaySeconds: 5 #初始化時間5s
periodSeconds: 4 #檢測間隔時間4s
timeoutSeconds: 1 #默認檢測超時時間為1s
failureThreshold: 3 #默認失敗次數(shù)為3次,達到3次后重啟pod
successThreshold: 1 #默認成功次數(shù)為1次,1 次代表成功
-
GRPC 探針
官方參考地址: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
6.6 資源限制
在k8s中對于容器資源限制主要分為以下兩類:
- 內(nèi)存資源限制: 內(nèi)存請求(request)和內(nèi)存限制(limit)分配給一個容器。 我們保障容器擁有它請求數(shù)量的內(nèi)存,但不允許使用超過限制數(shù)量的內(nèi)存。
- 官網(wǎng)參考地址: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/
- CPU 資源限制: 為容器設(shè)置 CPU request(請求) 和 CPU limit(限制)。 容器使用的 CPU 不能超過所配置的限制。 如果系統(tǒng)有空閑的 CPU 時間,則可以保證給容器分配其所請求數(shù)量的 CPU 資源。
- 官網(wǎng)參考地址: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/
請求 request memory cpu :可以使用的基礎(chǔ)資源 100M
限制 limit memory cpu :可以使用的最大資源 200M 超過最大資源之后容器會被 kill , OOM 錯誤
1 metrics-server
官網(wǎng)地址: https://github.com/kubernetes-sigs/metrics-server
Kubernetes Metrics Server (Kubernetes指標服務(wù)器),它是一個可擴展的、高效的容器資源度量源。Metrics Server 用于監(jiān)控每個 Node 和 Pod 的負載(用于Kubernetes內(nèi)置自動擴縮管道)。Metrics Server 從Kubelets 收集資源指標,并通過 Metrics API 在Kubernetes apiserver中公開,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。Metrics API 也可以通過 kubectl top 訪問,使其更容易調(diào)試自動擴縮管道。
- 查看 metrics-server(或者其他資源指標 API
metrics.k8s.io
服務(wù)提供者)是否正在運行, 請鍵入以下命令:
kubectl get apiservices
- 如果資源指標 API 可用,則會輸出將包含一個對
metrics.k8s.io
的引用。
NAME
v1beta1.metrics.k8s.io
- 安裝 metrics-server
# components.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- apiGroups:
- ""
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls #修改去掉證書驗證
image: dyrnq/metrics-server:v0.6.2 #修改官方無法下載
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
hostNetwork: true #必須指定這個才行
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
$ kubectl appply -f components.yaml
2 指定內(nèi)存請求和限制
官網(wǎng): https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/
為容器指定內(nèi)存請求,請在容器資源清單中包含 resources:requests
字段。 同理,要指定內(nèi)存限制,請包含 resources:limits
。
# nginx-memory-demo.yaml
#內(nèi)存資源的基本單位是字節(jié)(byte)。你可以使用這些后綴之一,將內(nèi)存表示為 純整數(shù)或定點整數(shù):E、P、T、G、M、K、Ei、Pi、Ti、Gi、Mi、Ki。 例如,下面是一些近似相同的值:128974848, 129e6, 129M, 123Mi
apiVersion: v1
kind: Pod
metadata:
name: nginx-memory-demo
spec:
containers:
- name: nginx-memory-demo
image: nginx:1.19
resources:
requests:
memory: "100Mi"
limits:
memory: "200Mi"
查看容器內(nèi)存使用情況
$ kubectl get pod nginx-memory-demo --output=yaml
查看容器正在使用內(nèi)存情況
$ kubectl top pod nginx-memory-demo
-
內(nèi)存請求和限制的目的
通過為集群中運行的容器配置內(nèi)存請求和限制,你可以有效利用集群節(jié)點上可用的內(nèi)存資源。 通過將 Pod 的內(nèi)存請求保持在較低水平,你可以更好地安排 Pod 調(diào)度。 通過讓內(nèi)存限制大于內(nèi)存請求,你可以完成兩件事:
- Pod 可以進行一些突發(fā)活動,從而更好的利用可用內(nèi)存。
- Pod 在突發(fā)活動期間,可使用的內(nèi)存被限制為合理的數(shù)量。
-
沒有指定內(nèi)存限制
如果你沒有為一個容器指定內(nèi)存限制,則自動遵循以下情況之一:
- 容器可無限制地使用內(nèi)存。容器可以使用其所在節(jié)點所有的可用內(nèi)存, 進而可能導(dǎo)致該節(jié)點調(diào)用 OOM Killer。 此外,如果發(fā)生 OOM Kill,沒有資源限制的容器將被殺掉的可行性更大。
- 運行的容器所在命名空間有默認的內(nèi)存限制,那么該容器會被自動分配默認限制。
3 指定 CPU 請求和限制
官網(wǎng): https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/
為容器指定 CPU 請求,請在容器資源清單中包含 resources: requests
字段。 要指定 CPU 限制,請包含 resources:limits
。
# nginx-cpu-demo.yaml
#CPU 資源以 CPU 單位度量。小數(shù)值是可以使用的。一個請求 0.5 CPU 的容器保證會獲得請求 1 個 CPU 的容器的 CPU 的一半。 你可以使用后綴 m 表示毫。例如 100m CPU、100 milliCPU 和 0.1 CPU 都相同。 CPU 請求只能使用絕對數(shù)量,而不是相對數(shù)量。0.1 在單核、雙核或 48 核計算機上的 CPU 數(shù)量值是一樣的。
apiVersion: v1
kind: Pod
metadata:
name: nginx-cpu-demo
spec:
containers:
- name: nginx-cpu-demo
image: nginx:1.19
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
- 顯示 pod 詳細信息
$ kubectl get pod nginx-cpu-demo --output=yaml
- 顯示 pod 運行指標
$ kubectl top pod nginx-cpu-demo
-
CPU 請求和限制的初衷
通過配置你的集群中運行的容器的 CPU 請求和限制,你可以有效利用集群上可用的 CPU 資源。 通過將 Pod CPU 請求保持在較低水平,可以使 Pod 更有機會被調(diào)度。 通過使 CPU 限制大于 CPU 請求,你可以完成兩件事:
- Pod 可能會有突發(fā)性的活動,它可以利用碰巧可用的 CPU 資源。
- Pod 在突發(fā)負載期間可以使用的 CPU 資源數(shù)量仍被限制為合理的數(shù)量。
-
如果不指定 CPU 限制
如果你沒有為容器指定 CPU 限制,則會發(fā)生以下情況之一:
-
容器在可以使用的 CPU 資源上沒有上限。因而可以使用所在節(jié)點上所有的可用 CPU 資源。
-
容器在具有默認 CPU 限制的名字空間中運行,系統(tǒng)會自動為容器設(shè)置默認限制。
-
-
如果你設(shè)置了 CPU 限制但未設(shè)置 CPU 請求
?如果你為容器指定了 CPU 限制值但未為其設(shè)置 CPU 請求,Kubernetes 會自動為其 設(shè)置與 CPU 限制相同的 CPU 請求值。類似的,如果容器設(shè)置了內(nèi)存限制值但未設(shè)置 內(nèi)存請求值,Kubernetes 也會為其設(shè)置與內(nèi)存限制值相同的內(nèi)存請求。
7 Pod 中 init 容器
Init 容器是一種特殊容器,在Pod 內(nèi)的應(yīng)用容器啟動之前運行。Init 容器可以包括一些應(yīng)用鏡像中不存在的實用工具和安裝腳本。
- 初始化 pod 主容器使用的卷中的文件。比如證書和私鑰、生成配置文件等,比如Init容器可以訪問應(yīng)用容器不能訪問的Secret權(quán)限
- 初始化Pod的網(wǎng)絡(luò)系統(tǒng),由于 pod 的所有容器共享相同的網(wǎng)絡(luò)命名空間,因此 init 容器對其所做的任何更改也會影響主容器
- 延遲 pod 的主容器的啟動,直到滿足一個先決條件
- 通知外部服務(wù) pod 即將開始運行
7.1 init 容器特點
init 容器與普通的容器非常像,除了如下幾點:
- 它們總是運行到完成。如果 Pod 的 Init 容器失敗,kubelet 會不斷地重啟該 Init 容器直到該容器成功為止。 然而,如果 Pod 對應(yīng)的
restartPolicy
值為 “Never”,并且 Pod 的 Init 容器失敗, 則 Kubernetes 會將整個 Pod 狀態(tài)設(shè)置為失敗。 - 每個都必須在下一個啟動之前成功完成。
- 同時 Init 容器不支持
lifecycle
、livenessProbe
、readinessProbe
和startupProbe
, 因為它們必須在 Pod 就緒之前運行完成。 - 如果為一個 Pod 指定了多個 Init 容器,這些容器會按順序逐個運行。 每個 Init 容器必須運行成功,下一個才能夠運行。當所有的 Init 容器運行完成時, Kubernetes 才會為 Pod 初始化應(yīng)用容器并像平常一樣運行。
- Init 容器支持應(yīng)用容器的全部字段和特性,包括資源限制、數(shù)據(jù)卷和安全設(shè)置。 然而,Init 容器對資源請求和限制的處理稍有不同。
7.2 使用 init 容器
官網(wǎng)地址: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/
在 Pod 的規(guī)約中與用來描述應(yīng)用容器的 containers
數(shù)組平行的位置指定 Init 容器。
apiVersion: v1
kind: Pod
metadata:
name: init-demo
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', 'echo init-myservice is running! && sleep 5']
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', 'echo init-mydb is running! && sleep 10']
- 查看啟動詳細
$ kubectl describe pod init-demo
# 部分結(jié)果
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m16s default-scheduler Successfully assigned default/init-demo to k8s-node2
Normal Pulling 2m16s kubelet Pulling image "busybox:1.28"
Normal Pulled 118s kubelet Successfully pulled image "busybox:1.28" in 17.370617268s (17.370620685s including waiting)
Normal Created 118s kubelet Created container init-myservice
Normal Started 118s kubelet Started container init-myservice
Normal Pulled 112s kubelet Container image "busybox:1.28" already present on machine
Normal Created 112s kubelet Created container init-mydb
Normal Started 112s kubelet Started container init-mydb
Normal Pulled 101s kubelet Container image "busybox:1.28" already present on machine
Normal Created 101s kubelet Created container myapp-container
Normal Started 101s kubelet Started container myapp-container
8 節(jié)點親和性分配 Pod
官方地址: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/assign-pod-node.html
你可以約束一個 Pod 以便 限制 其只能在特定的節(jié)點上運行, 或優(yōu)先在特定的節(jié)點上運行。 有幾種方法可以實現(xiàn)這點,推薦的方法都是用 標簽選擇算符來進行選擇。 通常這樣的約束不是必須的,因為調(diào)度器將自動進行合理的放置(比如,將 Pod 分散到節(jié)點上, 而不是將 Pod 放置在可用資源不足的節(jié)點上等等)。但在某些情況下,你可能需要進一步控制 Pod 被部署到哪個節(jié)點。例如,確保 Pod 最終落在連接了 SSD 的機器上, 或者將來自兩個不同的服務(wù)且有大量通信的 Pods 被放置在同一個可用區(qū)。
你可以使用下列方法中的任何一種來選擇 Kubernetes 對特定 Pod 的調(diào)度:
- 與節(jié)點標簽匹配的 nodeSelector 推薦
- 親和性與反親和性 推薦
- nodeName
- Pod 拓撲分布約束 推薦
定義: 使用節(jié)點親和性可以把 Kubernetes Pod 分配到特定節(jié)點。
8.1 給節(jié)點添加標簽
-
列出集群中的節(jié)點及其標簽:
$ kubectl get nodes --show-labels #輸出類似于此: NAME STATUS ROLES AGE VERSION LABELS k8s-node1 Ready control-plane 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux... k8s-node2 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux... k8s-node3 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
-
選擇一個節(jié)點,給它添加一個標簽:
kubectl label nodes k8s-node1(節(jié)點名稱) disktype=ssd
-
驗證你所選節(jié)點具有
disktype=ssd
標簽:$ kubectl get nodes --show-labels #輸出類似于此: NAME STATUS ROLES AGE VERSION LABELS k8s-node1 Ready control-plane 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux,disktype=ssd... k8s-node2 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux... k8s-node3 Ready <none> 10d v1.26.0 beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux...
8.2 根據(jù)選擇節(jié)點標簽指派 pod 到指定節(jié)點[nodeSelector]
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd # 選擇節(jié)點為標簽為 ssd 的節(jié)點
8.3 根據(jù)節(jié)點名稱指派 pod 到指定節(jié)點[nodeName]
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: worker1 # 調(diào)度 Pod 到特定的節(jié)點
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
8.4 根據(jù) 親和性和反親和性 指派 pod 到指定節(jié)點
官網(wǎng)地址: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/assign-pod-node.html
說明
nodeSelector
提供了一種最簡單的方法來將 Pod 約束到具有特定標簽的節(jié)點上。 親和性和反親和性擴展了你可以定義的約束類型。使用親和性與反親和性的一些好處有:
- 親和性、反親和性語言的表達能力更強。
nodeSelector
只能選擇擁有所有指定標簽的節(jié)點。 親和性、反親和性為你提供對選擇邏輯的更強控制能力。 - 你可以標明某規(guī)則是“軟需求”或者“偏好”,這樣調(diào)度器在無法找到匹配節(jié)點時仍然調(diào)度該 Pod。
- 你可以使用節(jié)點上(或其他拓撲域中)運行的其他 Pod 的標簽來實施調(diào)度約束, 而不是只能使用節(jié)點本身的標簽。這個能力讓你能夠定義規(guī)則允許哪些 Pod 可以被放置在一起。
親和性功能由兩種類型的親和性組成:
-
節(jié)點親和性功能類似于
nodeSelector
字段,但它的表達能力更強,并且允許你指定軟規(guī)則。 - Pod 間親和性/反親和性允許你根據(jù)其他 Pod 的標簽來約束 Pod。
節(jié)點親和性概念上類似于 nodeSelector
, 它使你可以根據(jù)節(jié)點上的標簽來約束 Pod 可以調(diào)度到哪些節(jié)點上。 節(jié)點親和性有兩種:
-
requiredDuringSchedulingIgnoredDuringExecution
: 調(diào)度器只有在規(guī)則被滿足的時候才能執(zhí)行調(diào)度。此功能類似于nodeSelector
, 但其語法表達能力更強。 -
preferredDuringSchedulingIgnoredDuringExecution
: 調(diào)度器會嘗試尋找滿足對應(yīng)規(guī)則的節(jié)點。如果找不到匹配的節(jié)點,調(diào)度器仍然會調(diào)度該 Pod。
注意:在上述類型中,IgnoredDuringExecution
意味著如果節(jié)點標簽在 Kubernetes 調(diào)度 Pod 后發(fā)生了變更,Pod 仍將繼續(xù)運行。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
#節(jié)點必須包含一個鍵名為 ssd 的標簽, 并且該標簽的取值必須為 fast 或 superfast。
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: ssd
operator: In
values:
- fast
- superfast
containers:
- name: nginx
image: nginx:1.19
注意: 你可以使用 In
、NotIn
、Exists
、DoesNotExist
、Gt
和 Lt
之一作為操作符。NotIn
和 DoesNotExist
可用來實現(xiàn)節(jié)點反親和性行為。
8.5 節(jié)點親和性權(quán)重
你可以為 preferredDuringSchedulingIgnoredDuringExecution
親和性類型的每個實例設(shè)置 weight
字段,其取值范圍是 1 到 100。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
#節(jié)點最好具有一個鍵名為 app 且取值為 fast 的標簽。
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 #取值范圍是 1 到 100
preference:
matchExpressions:
- key: ssd
operator: In
values:
- fast
- weight: 50
preference:
matchExpressions:
- key: app
operator: In
values:
- demo
containers:
- name: nginx
image: nginx:1.19
8.6 pod 間親和性和反親和性及權(quán)重
與節(jié)點親和性類似,Pod 的親和性與反親和性也有兩種類型:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
例如,你可以使用 requiredDuringSchedulingIgnoredDuringExecution
親和性來告訴調(diào)度器, 將兩個服務(wù)的 Pod 放到同一個云提供商可用區(qū)內(nèi),因為它們彼此之間通信非常頻繁。 類似地,你可以使用 preferredDuringSchedulingIgnoredDuringExecution
反親和性來將同一服務(wù)的多個 Pod 分布到多個云提供商可用區(qū)中。
要使用 Pod 間親和性,可以使用 Pod 規(guī)約中的 spec.affinity.podAffinity
字段。 對于 Pod 間反親和性,可以使用 Pod 規(guī)約中的 spec.affinity.podAntiAffinity
字段。
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
app: redis
spec:
containers:
- name: redis
image: redis:5.0.10
imagePullPolicy: IfNotPresent
restartPolicy: Always
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
#更確切的說,調(diào)度器必須將 Pod 調(diào)度到具有 cpu 標簽的節(jié)點上,并且集群中至少有一個位于該可用區(qū)的節(jié)點上運行著帶有 app=nginx 標簽的 Pod。
- topologyKey: cpu
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
- pod 間親和性權(quán)重
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
app: redis
spec:
containers:
- name: redis
image: redis:5.0.10
imagePullPolicy: IfNotPresent
restartPolicy: Always
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
#更確切的說,調(diào)度器必須將 Pod 調(diào)度到具有 cpu 標簽的節(jié)點上,并且集群中至少有一個位于該可用區(qū)的節(jié)點上運行著帶有 app=nginx 標簽的 Pod。
- podAffinityTerm:
topologyKey: cpu
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
weight: 1
- podAffinityTerm:
topologyKey: cpu
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
weight: 30
8.7 污點和容忍度
參考: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/taint-and-toleration.html文章來源:http://www.zghlxwxcb.cn/news/detail-649298.html
8.8 Pod 拓撲分布約束
參考: http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/topology-spread-constraints/文章來源地址http://www.zghlxwxcb.cn/news/detail-649298.html
到了這里,關(guān)于K8s(Kubernetes)學習(三):pod概念及相關(guān)操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!