什麼是Pod?
Kubernetes中最小的管理單元,作為應用運作的載體。當Pod運作多個容器時,同一個Pod中的所有容器可以共享PID、Network、IPC、UTS命名空間。 打個比方,例如Pod是豆莢,Container容器就是豆子,一個豆莢裡可以有一個或者多個豆子。
Pod的使用方式
通過kubectl建立
kubectl run nginx-pod --image=nginx:1.16
通過yaml資源定義清單建立
kubectl apply -f nginx-pod.yaml
apiVersion: v1 #表示api資源是哪一個組及版本
kind: Pod #表示資源類别
metadata: #表示中繼資料
name: nginx #名稱,作用域在名稱空間内唯一
spec: #表示期望狀态
containers: #表示容器資源
- name: nginx #名稱,作用域在Pod内唯一
image: nginx:1.16 #指定鏡像
通過kubectl指令檢視Pod
kubectl get pods

Pod的資源管理
Pod開始建立時會進行請求所需資源,Kubernetes會根據Pod所需要的資源量安排在最合适的Node節點上,這保證了Pod所需要的資源是可以成功獲得的。Pod的資源管理可以設定記憶體,CPU,臨時存儲所需的資源及最大資源使用限制。
kubectl apply -f pod-resouce-management.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
resources:
requests: #所需資源
memory: "64Mi"
cpu: "250m"
limits: #資源限制
memory: "128Mi"
cpu: "500m"
預設情況下不指定資源限制時,Pod對CPU和記憶體的使用是沒有上限的。通常情況下除了對Pod的資源限制之外,也可以對容器的資源進行限制,兩者可以同時進行資源限制。當隻為容器做資源限制時,每個容器不能超過其指定的上限。當隻為Pod做資源限制時,所有容器不能超過指定Pod的上限。
Pod QoS 服務品質
在Kubernetes中,Pod的QoS服務品質有3個級别,通過資源的指定賦予不同的QoS标簽,在節點出現資源不足時根據Pod QoS級别就會采用順序驅逐。
BestEffort
Pod中的容器都沒有設定CPU或記憶體的Requests及Limits,QoS優先級最低,節點資源不足時将被優先驅逐。
Burstable
Pod中的至少有一個容器設定CPU或記憶體的Requests及Limits,且Requests不等于Limits。QoS優先級中等。
Guaranteed
Pod中的全部容器都設定CPU或記憶體的Requests及Limits,且Requests等于Limits。QoS優先級最高。
kubectl apply -f pod-qos-besteffort.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-qos-besteffort
spec:
containers:
- name: nginx
image: nginx:1.16
resources: # 不指定
檢視Pod的QoS等級為BestEffort
kubectl get pods nginx-qos-besteffort -o yaml
kubectl apply -f pod-qos-burstable.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-qos-burstable
spec:
containers:
- name: nginx
image: nginx:1.16
resources: # 指定記憶體資源,但不指定CPU資源,且所需資源及資源限制不同
requests:
memory: "64Mi"
檢視Pod的QoS等級為Burstable
kubectl get pods nginx-qos-burstable -o yaml
kubectl apply -f pod-qos-guaranteed.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-qos-guaranteed
spec:
containers:
- name: nginx
image: nginx:1.16
resources: # 指定相同數值的所需記憶體資源及記憶體資源限制
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "64Mi"
cpu: "250m"
檢視Pod的QoS等級為Guaranteed
kubectl get pods nginx-qos-guaranteed -o yaml
Pod的生命周期
Pod的本身的設計理念就是一部狀态機,生命周期不是一直處于一個狀态的,由使用者手動操作或者控制器操作後将會改變其狀态。
在Pod中的status.phase字段記錄着目前pod的生命周期階段,在Pod中一共有5種運作狀态:
Pending: 叢集已接收Pod建立指令并完成Pod建立,但Pod未被綁定到節點或容器未完成運作。
Running: Pod已綁定到節點,容器已全部建立完成,并且最少有一個容器在運作。
Succeeded: Pod中的容器已終止運作且不會啟動。
Failed: Pod中的容器由故障導緻終止運作。
Unknown: 無法确定Pod的狀态。
Pod的重新開機政策
當Pod中的容器處于退出狀态時,kubelet就根據資源定義清單spec.restartPolicy的重新開機政策進行對應操作。
Always: 預設的重新開機政策,如果容器處于退出狀态時則重新開機。
OnFailure: 當容器退出狀态不為0則重新開機。
Never: 從不重新開機。
kubectl apply -f pod-restart-policy.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
restartPolicy: Always #重新開機政策
containers:
- name: nginx
image: nginx:1.16
Pod的容器探針
容器探針是由各個節點kubelet對容器的健康情況的診斷方法。應用于保證業務可用性,通過檢查到故障後下線服務避免影響業務,以及重新開機服務進行自動恢複。
容器探針
livenessProbe: 存活探針
解決針對容器在運作一段時間後出現異常情況而需要重新開機解決的問題。在探針檢測失敗後,容器會被殺掉,并根據重新開機政策進行重新開機。
readinessProbe: 就緒探針
解決容器由于依賴其他服務等情況無法一啟動就開始被排程。在探針檢測失敗後,将會service endpoint下線掉該Pod,在恢複後會重新加入service endpoint提供服務。
startupProbe: 啟動探針 - v1.16引入新功能
針對在啟動時間較長的容器,避免存活探針檢測時對容器的啟動時間限制。
探測方式
ExecAction 通過對容器執行指令後傳回碼判斷是否成功,如果是0則為健康。
TCPSocketAction 通過對容器IP、端口進行TCP檢查。如果端口開放則為健康。
HTTPGetAction 通過對容器的IP、端口、路徑進行HTTP Get檢查,如果傳回狀态碼為2xx或者3xx則為健康。
探測結果
Success 容器通過了探針的探測檢查
Failure 容器不通過了探針的探測檢查
Unknow 無法探測檢查,不采取任何動作
kubectl apply -f pod-probe.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
ports:
- containerPort: 80
readinessProbe: #就緒探針
exec:
command: /data/check.sh
initialDelaySeconds: 5 #啟動後延遲檢測
periodSeconds: 10 #間隔的探測時間
livenessProbe: #存活探針
httpGet:
path: /health
port: 80
initialDelaySeconds: 15 #啟動後延遲檢測
periodSeconds: 20 #間隔的探測時間
startupProbe: #啟動探針
tcpSocket:
port: 5672
failureThreshold: 30 #檢測失敗後重試次數
periodSeconds: 10 #間隔的探測時間
通用探針字段
initialDelaySeconds Pod啟動後延遲探測
periodSeconds 間隔的探測時間
timeoutSeconds 探測的逾時時間
successThreshold 檢測失敗後重試成功的次數,達到該次數後将認為success
failureThreshold 檢測失敗後重試次數,達到該次數後将認為fail
http探針字段
host 探測的主機名,預設為Pod IP
port 探測的端口号,範圍1-65535
scheme 探測的方式,http或是https
path 探測的http路徑,例如/health
httpHeaders 探測時http标頭
exec探針字段
command 探測的指令
Pod的節點選擇
在預設情況下,Pod會被Kuberentes排程到具有所需運作資源的節點上,可以通過标簽選擇、直接指定節點來選擇運作的節點。
通過節點标簽綁定Pod
kubectl label nodes k8s-c01-p002 environment=prod
kubectl get nodes --show-labels
kubectl apply -f node-lable-selector.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
nodeSelector:
environment: prod #指定比對的标簽
通過節點名稱綁定Pod
kubectl apply -f nodename-selector.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: k8s-c01-p003 #指定節點比對
containers:
- name: nginx
image: nginx:1.16
使用技巧
單獨使用Pod并不能真正發揮Kubernetes的威力,是以一般不會直接進行Pod的建立,而是通過Deployment控制器來建立及管理Pod,這會讓Pod實作故障自愈及滾動更新等功能。