Pod是kubernetes中最基本也是最小的資源對象,一個Pod中可以包含多個容器,一個Pod中的多個容器必須運行在同一個節點(Node)上,Kubernetes會自動將其分配到同一個node上,應該儘可能的將不同的應用運行在不同的Pod中,Pod中的各個容器通過基礎容器pause
共享Network
,NTS Namespace
,PID
,Pod是kubernetes進行動態擴縮容的基礎單元。很少會直接在kubernetes中創建單個Pod,kubernetes提供了控制器(Controller)來管理Pod.
Pod存在形式
- 單Pod單容器:一個Pod中運行一個容器
- 單Pod多容器:一個Pod中運行多個容器
Pod中單個容器模式
一般推薦使用這種模式,一個Pod對應一個應用實例,這樣做更加靈活,kubernetes只能管理Pod,無法直接管理Pod中的容器,如果需要對Pod進行動態擴縮容,這種形式可獨立的按需進行擴縮容。
Pod中多容器模式
對於一些特定的場景,需要輔助容器配合主容器完成一些功能,這時就需要在同一個Pod中運行多個容器
- Sidecar Pattern:爲主容器提供一個輔助容器,每個容器獨立運行
- Ambassador Pattern:爲主容器提供一個訪問遠程服務代理的容器
- Adapter Pattern:爲主容器提供一個適配其他服務的容器
個人感覺Ambassador Pattern
和Adapter Pattern
很相似,目前額外的容器存在的模式一般爲Sidecar Pattern
,如:istio sidecar,Helm hook
Pod的鏡像獲取策略
使用yaml
文件中容器配置(containers)的imagePullPolicy
字段用於指定拉取策略。
- Always:鏡像
tag
爲latest
,或者本地鏡像不存在時,總是從遠程倉庫拉取鏡像 - IfNotPresent:本地鏡像不存在時,從遠程倉庫拉取鏡像
- Never:僅可使用本地鏡像,禁止從遠程倉庫拉取鏡像
注意:tag
爲latest
的鏡像,默認策略爲Always
,其他tag
的鏡像,默認策略爲IfNotPresent
。
Pod中pause
容器
每個Pod啓動的時候,kubelet
都會使用kubernetes/pause
鏡像爲Pod創建一個基礎pause容器,然後再創建其他進程。
pause容器的核心功能
- Pod中linux namespace共享的基礎
- 啓用PID Namespace隔離每個Pod,使得每個Pod都有自己的PID 1進程(init進程),關於PID 1 進程可以參考:Linux下1號進程的前世(kernel_init)今生(init進程)
- 管理殭屍進程
Pod 的生命週期
Pod從創建到銷燬爲其生命週期
pod pause 是PodStatus中的一個字段,這個字段有幾個值
- Pending:Pod資源對象已經存入etcd中,但還未被調度或者存在一個或多個容器未創建完成(正在拉去鏡像)
- Running:Pod已經被調度到集羣中的摸個Node上,並且容器都被創建,存在容器正在啓動或者正在重啓狀態
- Successed:Pod中的所有容器都已經終止,並且不會再重啓
- Failed:Pod 中的所有容器都已終止了,並且至少有一個容器是因爲失敗終止。也就是說,容器以非0狀態退出或者被系統終止
- Unknown:API Server由於某些原因無法獲取到Pod的狀態,通常是因爲與 Pod 所在Node的kubelet通信失敗
Pod的創建過程
- 用戶通過Rest API (kubectl ,rancher API)提交Pod Spec給API Server
- API 將相關信息保存到etcd中,待寫入操作完成後,API Server會返回確認消息給客戶端
kube-scheduler
通過watch
機制檢查到etcd中的Pod狀態爲未綁定Nodekube-scheduler
爲Pod選擇一個Node進行綁定,並且API Server將信息更新到etcd- 目標Node的
kubelet
調用docker啓動容器,kubelet
會獲取Pod的狀態,並將信息返回給API Server,API Server再將信息保存到etcd - etcd信息寫入完成後,API Server將信息發送給kubelet將通過它被接受。
Pod 生命週期的重要行爲
- 創建init container:串行執行完成所有的init container之後纔會創建應用container
- 執行hook (post start)
- 創建應用container
- 探針檢測(livenessProbe,readinessProbe)
Pod Template
apiVersion: v1
kind: Pod
metadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
containers:
- name: string
image: string
imagePullPolicy: [Always | Never | IfNotPresent]
command: [string]
args: [string]
workingDir: string
volumeMounts:
- name: string
mountPath: string
readOnly: boolean
ports:
- name: string
containerPort: init
hostPort: in
protocol: string
env:
- name: string
value: string
resources:
limits:
cpu: string
memory: string
livenessProbe:
exec:
command: [string]
httpGet:
path: string
port: number
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: number
initialDelaySeconds: 0
timeoutSeconds: 0
periodSeconds: 0
successThreshold: 0
failureThreshold: 0
securityContext:
priviledge: false
restartPolicy: [Always | Never | OnFailure]
nodeSelector: object
imagePullSecrets:
- name: string
hostNetwork: false
volumes:
- name: string
emptyDir: {}
hostPath:
path: string
secret:
secretName: string
items:
- keys: string
path: string
configMap:
name: string
items:
- key: string
path: string