前言:
前面文中對通過DaemonSet、儲存資源物件,實現了在指定節點中執行一個守護程式。
在真實的業務場景中,部署的服務都是有狀態的、且有資料需要持久化的;那麼如何實現呢?
那麼接下來學習一種更加重要的資源——StatefulSets。
一、StatefulSets 介紹
StatefulSet 是用來管理有狀態應用的工作負載 API 物件。
StatefulSet 用來管理某 Pod 集合的部署和擴縮, 併為這些 Pod 提供持久儲存和持久識別符號。
與Deployment 類似,StatefulSet 管理基於相同容器規約的一組 Pod。但和 Deployment 不同的是,StatefulSet 為它們的每個 Pod 維護了一個有粘性的ID。這些 Pod 是基於相同的規約來建立的,但是不能相互替換:無論怎麼排程,每個 Pod 都有一個永久不變的 ID。
如果希望使用儲存卷為工作負載提供持久儲存,可以使用 StatefulSet 作為解決方案的一部分。 儘管 StatefulSet 中的單個 Pod 仍可能出現故障, 但持久的 Pod 識別符號使得將現有卷與替換已失敗 Pod 的新 Pod 相匹配變得更加容易。
應用場景:
· StatefulSets 對於需要滿足以下一個或多個需求的應用程式很有價值:
- 穩定的、唯一的網路識別符號。
- 穩定的、持久的儲存。
- 有序的、優雅的部署和縮放。
- 有序的、自動的滾動更新。
使用限制:
- 給定 Pod 的儲存必須由 PersistentVolume 驅動 基於所請求的
storage class
來提供,或者由管理員預先提供。 - 刪除或者收縮 StatefulSet 並不會刪除它關聯的儲存卷。 這樣做是為了保證資料安全,它通常比自動清除 StatefulSet 所有相關的資源更有價值。
- StatefulSet 當前需要無頭服務 來負責 Pod 的網路標識。你需要負責建立此服務。
- 當刪除 StatefulSets 時,StatefulSet 不提供任何終止 Pod 的保證。 為了實現 StatefulSet 中的 Pod 可以有序地且體面地終止,可以在刪除之前將 StatefulSet 縮放為 0。
- 在預設 Pod 管理策略(
OrderedReady
) 時使用 滾動更新,可能進入需要人工干預 才能修復的損壞狀態
二、StatefulSets使用方式
-
建立StatefulSets
建立StatefulSets的yaml格式:
apiVersion: apps/v1 kind: StatefulSet #StatefulSet型別 metadata: name: web #StatefulSet 名稱 spec: #service名稱 serviceName: "nginx" #Pod數量 replicas: 2 selector: matchLabels: app: nginx #Pod定義 template: metadata: labels: app: nginx spec: #容器設定 containers: - name: nginx #映象名稱 image: nginx:1.9.6 ports: - containerPort: 80 name: web volumeMounts: #持久化儲存名稱 - name: www mountPath: /usr/share/nginx/html #持久化儲存定義 volumeClaimTemplates: - metadata: #名稱 name: www spec: #訪問方式 accessModes: ["ReadWriteOnce"] #資源定義 resources: requests: storage: 1Gi
應用該yaml後Pod建立順序如下:
>>kubectl apply -f web.yaml
service/nginx created
statefulset apps/web created
>>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 1s web-0 1/1 Running 0 3s web-1 0/1 Pending 0 0s web-1 0/1 Pending 0 0s web-1 0/1 ContainerCreating 0 0s web-1 1/1 Running 0 2s
可見:StatefulSets中Pod順序建立成功。
再檢視下Nginx中持久化儲存資源:
kubectl get pvc -l app=nginx NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-c431e9d6-0dba-4c1d-ba83-b9f1d5b8824a 1Gi RWO standard 137m www-web-1 Bound pvc-58070d7f-9fec-4e28-b77b-b15fdf30c965 1Gi RWO standard 124m
-
擴容/縮容StatefulSets
StatefulSet策略:
-
- 對於包含 N 個 副本的 StatefulSet,當部署 Pod 時,它們是依次建立的,順序為
0..N-1
。 - 當刪除 Pod 時,它們是逆序終止的,順序為
N-1..0
。 - 在將縮放操作應用到 Pod 之前,它前面的所有 Pod 必須是 Running 和 Ready 狀態。
- 在 Pod 終止之前,所有的繼任者必須完全關閉。
- 對於包含 N 個 副本的 StatefulSet,當部署 Pod 時,它們是依次建立的,順序為
擴容:StatefulSet 按序號索引順序的建立每個 Pod,並且會等待前一個 Pod 變為 Running 和 Ready 才會啟動下一個 Pod
#擴容Pod數量為4 >>kubectl scale sts web --replicas=4 statefulset.apps/web scaled #檢視pod變化 >>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 53m web-1 1/1 Running 0 53m web-2 0/1 Pending 0 0s web-2 0/1 Pending 0 0s web-2 0/1 Pending 0 3s web-2 0/1 ContainerCreating 0 3s web-2 1/1 Running 0 6s web-3 0/1 Pending 0 0s web-3 0/1 Pending 0 0s web-3 0/1 Pending 0 2s web-3 0/1 ContainerCreating 0 2s web-3 1/1 Running 0 4s
縮容:會按照與 Pod 序號索引相反的順序每次刪除一個 Pod。在刪除下一個 Pod 前會等待上一個被完全關閉
#縮容為2個pod >>kubectl scale -n default statefulset web --replicas=2 #檢視Pod變化: >>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 59m web-1 1/1 Running 0 59m web-2 1/1 Running 0 4m30s web-3 1/1 Running 0 4m24s web-3 1/1 Terminating 0 7m23s web-3 0/1 Terminating 0 7m24s web-3 0/1 Terminating 0 7m25s web-3 0/1 Terminating 0 7m25s web-2 1/1 Terminating 0 7m31s web-2 0/1 Terminating 0 7m32s web-2 0/1 Terminating 0 7m33s web-2 0/1 Terminating 0 7m33s
注意:擴容時會根據設定自動建立久化儲存資源(PVC)並關聯到Pod,當縮容時,PVC不會同步刪除。當再次擴容時;會自動繫結到之前的PVC上。
-
StatefulSets更新策略
更新策略由 StatefulSet API Object 的spec.updateStrategy
欄位決定。這個特效能夠用來更新一個 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。 RollingUpdate
滾動更新是 StatefulSets 預設策略。
OnDelete:當 StatefulSet 的 .spec.updateStrategy.type
設定為 OnDelete
時,它的控制器將不會自動更新 StatefulSet 中的 Pod。 使用者必須手動刪除 Pod 以便讓控制器建立新的 Pod,以此來對 StatefulSet 的 .spec.template
的變動作出反應
滾動更新:RollingUpdate
更新策略對 StatefulSet 中的 Pod 執行自動的滾動更新。 在沒有宣告 .spec.updateStrategy
時,RollingUpdate
是預設配置。 當 StatefulSet 的 .spec.updateStrategy.type
被設定為 RollingUpdate
時, StatefulSet 控制器會刪除和重建 StatefulSet 中的每個 Pod。 它將按照與 Pod 終止相同的順序(從最大序號到最小序號)進行,每次更新一個 Pod。 它會等到被更新的 Pod 進入 Running 和 Ready 狀態,然後再更新前一個
-
StatefulSets刪除
StatefulSet 同時支援級聯和非級聯刪除。使用非級聯方式刪除 StatefulSet 時,StatefulSet 的 Pod 不會被刪除。使用級聯刪除時,StatefulSet 和它的 Pod 都會被刪除。
StatefulSet 永遠不會刪除和一個 Pod 相關聯的 PersistentVolumes。 當你重建這個 StatefulSet 並且重新啟動了Pod時,它原本的 PersistentVolume 會被重新掛載
非級聯刪除:Pod不會刪除
#非級聯刪除statefulset kubectl delete statefulset web --cascade=orphan
檢視狀態:Pod資訊,所有Pod依舊執行
級聯刪除:StatefulSet 和它的 Pod 都會被刪除
#級聯刪除 kubectl delete statefulset web
檢視狀態:Pod逐步從Pod1->Pod0刪除
三、總結
StatefulSet 是一種較常用的資源型別,能夠穩定、有序的部署和擴縮Pod集合, 併為這些 Pod 提供持久儲存和持久識別符號。