引言
本文是《深入剖析Kubernetes》學習筆記——《深入剖析Kubernetes》
正文
控制器都遵循K8s的項目中一個通用的編排模式——控制循環
for {實際狀態 := 獲取集群中對象X的實際狀態期望狀態 := 獲取集群中對象X的期望狀態if 實際狀態 == 期望狀態 {// do nothing} else {執行編排動作,將實際狀態調整為期望狀態}
}
作業副本與水平擴展
如果更新了Deployment的Pod模版,那么Deployment就需要遵循滾動更新的方式,來升級現有容器 → ReplicaSet.
DeployController 只需要修改它所控制的ReplicaSet的Pod副本個數就可以了。
相關命令
k scale deployment nginx-deployment --replicas=4 # 調整replicas數量k rollout status deployment nginx-deployment # 實時查看Deployment對象的狀態變化k edit deployment/nginx-deployment # 通過修改yaml文件調整deployment狀態
滾動更新,要求一定使用Pod的健康檢查機制檢查應用的運行狀態,而不是簡單地依賴容器的Running狀態。
在控制器在滾動更新過程中永遠會確保2個Pod處于可用狀態,至多只有4個Pod同時存在于集群中,由RollingUpdateStrategy進行控制。
strategy:type: RollingUpdaterollingUpdate:maxSurge: 1 # 除了DESIRED數量外,在一次滾動更新中Deplyment控制氣還可以創建多個新PodmaxUnavailable: 1 # 可以刪除多少舊Pod
上述案例
k set image deployment/nginx-deployment nginx=nginx:1.91 # 設置deployment nginx版本
k rollout undo deployment/nginx-deployment # 錯誤回滾,rs仍然保存k rollout history deployment/nginx-deployment --revision=2 # 查看API對象的細節k rollout undo deployment/nginx-deployment --to-revision=2 # 最后加上目標版本號,來回滾指定版本
每一次操作都會生成rs,是否造成資源浪費?
解決方案1:
k rollout pause deployment/nginx-deployment... k edit / k set imagek rollout resume deploy/nginx-deployment
解決方案2:
spec.revisionHistoryLimit=0 再也不能進行回滾操作
問題
應用的發布流程往往千差萬別,可能有很多定制化的需求。例如:會有會話粘連(session sticky),這就意味著更新時哪個Pod能下線不是隨便選擇的。
StatefulSet :拓撲狀態
有些實例之間有不對等關系,以及實例對外部數據有依賴關系的應用,就稱為有狀態應用。
StatefulSet將應用狀態抽象為兩種情況
- 拓撲狀態:應用的多個實例之間不是完全對等的。
- 存儲狀態:應用的多個實例分別綁定了不同的存儲數據。
Headless Service
Services是K8s用來將一組Pod暴露給外界訪問的一個機制。
- 以Service的VIP(virtual IP的方式):當訪問10.0.23.1這個Service IP地址時,會把請求轉發到該Service所代理的Pod上。
- 以Service的DNS方式:訪問my-svc-namespace.svc.cluster.local這條DNS記錄,就可以訪問my-svc所代理的Pod上
- Normal Servcie:解析DNS時,返回的是VIP
- Headless Service:解析DNS時,直接返回的是Pod IP
創建Healess Service
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:selector:app: nginxports:- name: webport: 80clusterIP: None # 不同點
創建一個Healess Service之后,所代理的所有Pod的IP都會被綁定到<pod-name>.<svc-name>.<namespace>.svc.cluster.local
上。
StatefulSet如何使用這個DNS記錄為維持Pod的拓撲狀態
StatefulSet讓其所有Pod都有唯一的網絡標識,即使Pod被刪除,重新創建的容器網絡標識與原先 相同 (IP不同)
StatefulSet:存儲狀態
PVC和PV的設計,實際上類似于“接口”和“實現”的思想。
開發者只要知道并會使用PVC;運維人員負責給“接口”綁定具體的實現,即PV;
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:serviceName: nginx-servicereplicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.9.1ports:- containerPort: 80name: webvolumeMounts:- mountPath: /usr/share/nginx/htmlname: wwwvolumeClaimTemplates:- metadata:name: wwwspec:accessModes:- ReadWriteOnceresources:requests:storage: 1Gi
使用volumeClaimTemplate進行PV和PVC的綁定
總結
- StatefulSet的控制器直接管理的是Pod。
- K8s通過Headless Service為這些編號的Pod,在DNS服務器中生成有相同編號的DNS記錄。
- StatefulSet為每一個Pod分配并創建一個相同編號的PVC。