1. 程式人生 > >Kubernetes學習筆記(九):StatefulSet--部署有狀態的多副本應用

Kubernetes學習筆記(九):StatefulSet--部署有狀態的多副本應用

## StatefulSet如何提供穩定的網路標識和狀態 ReplicaSet中的Pod都是無狀態,可隨意替代的。又因為ReplicaSet中的Pod是根據模板生成的多副本,無法對每個副本都指定單獨的PVC。 來看一下StatefulSet如何解決的。 ### 提供穩定的網路標識 StatefulSet建立Pod都有一個從零開始的順序索引,這會體現在Pod的名稱和主機名上,同樣也會體現在Pod對應的固定儲存上。所以這些名字是可預先知道的,不同於ReplicaSet的隨機生成名字。 因為他們的名字都是固定的,而且彼此狀態都不同,通常會操作他們其中的一個。如此情況,一般都會建立一個與之對應的headless Service,通過這個Service,每個Pod將擁有獨立的DNS記錄。 擴容一個StatefulSet會使用下一個順序索引建立一個新的Pod,縮容會刪除索引值最高的。並且縮容任何時候只會操作一個Pod。 ### 如何提供穩定的儲存 StatefulSet可以擁有一個或多個PVC模板,這些PVC會在建立Pod前創建出來,繫結到一個Pod例項上。 擴容的時候會建立一個Pod以及若干個PVC,刪除的時候只會刪除Pod。StatefulSet縮容時不會刪除PVC,擴容時會重新掛上。 ## 使用StatefulSet ### 定義三個PV 定義pv-(a|b|c) ``` # stateful-pv-list.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-a spec: capacity: storage: 1Mi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle hostPath: path: /tmp/pva --- apiVersion: v1 kind: PersistentVolume # 以下忽略 ``` ### headless的Service ``` # stateful-service-headless.yaml apiVersion: v1 kind: Service metadata: name: rwfile spec: clusterIP: None selector: app: rwfile ports: - port: 80 ``` ### 定義StatefulSet 先建立兩個Pod副本。使用volumeClaimTemplates定義了PVC模板。 ``` # stateful.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: rwfile spec: replicas: 2 serviceName: rwfile selector: matchLabels: app: rwfile template: metadata: labels: app: rwfile spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/orzi/rwfile name: rwfile ports: - containerPort: 8000 volumeMounts: - name: data mountPath: /tmp/data volumeClaimTemplates: - metadata: name: data spec: resources: requests: storage: 1Mi accessModes: - ReadWriteOnce ``` 建立三個PV,一個headless的Service,一個StatefulSet ``` -> [[email protected]] [~] k create -f stateful-pv-list.yaml persistentvolume/pv-a created persistentvolume/pv-b created persistentvolume/pv-c created -> [[email protected]] [~] k create -f stateful-service-headless.yaml service/rwfile created -> [[email protected]] [~] k create -f stateful.yaml statefulset.apps/rwfile created ``` 檢視 ``` -> [[email protected]] [~] k get all -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/rwfile-0 1/1 Running 0 12s 10.244.1.52 kube1.vm pod/rwfile-1 1/1 Running 0 8s 10.244.2.56 kube2.vm NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/kubernetes ClusterIP 10.96.0.1 443/TCP 81s service/rwfile ClusterIP None 80/TCP 23s app=rwfile NAME READY AGE CONTAINERS IMAGES statefulset.apps/rwfile 2/2 12s rwfile registry.cn-hangzhou.aliyuncs.com/orzi/rwfile ``` 檢視PV和PVC,可以看到已經有兩個PVC綁定了PV ``` -> [[email protected]] [~] k get pv,pvc -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE persistentvolume/pv-a 1Mi RWO Recycle Bound default/data-rwfile-0 7m20s Filesystem persistentvolume/pv-b 1Mi RWO Recycle Bound default/data-rwfile-1 7m20s Filesystem persistentvolume/pv-c 1Mi RWO Recycle Available 7m20s Filesystem NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE persistentvolumeclaim/data-rwfile-0 Bound pv-a 1Mi RWO 6m55s Filesystem persistentvolumeclaim/data-rwfile-1 Bound pv-b 1Mi RWO 6m51s Filesystem ``` ### 請求Pod 啟動代理 ``` -> [[email protected]] [~] k proxy Starting to serve on 127.0.0.1:8001 ``` 傳送請求 ``` -> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/ -d "a=123" data stored in : rwfile-0 -> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/ a=123 ``` ### 刪除測試 刪除rwfile-0,然後檢視,從時間上看確實是被刪除重建的。 ``` -> [[email protected]] [~] k delete po rwfile-0 pod "rwfile-0" deleted -> [[email protected]] [~] k get po NAME READY STATUS RESTARTS AGE rwfile-0 1/1 Running 0 7s rwfile-1 1/1 Running 0 19m ``` 看一下之前儲存的資料還在不在 ``` -> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/ a=123 ``` 還是在的,此次測試實際上也證明了StatefulSet提供了穩定的網路標識和儲存。 ## 發現StatefulSet的夥伴節點 使用DNS解析headless的Service的FQDN。 例子以後再寫吧。。 ## 如何處理節點失效 除非確定節點無法執行或者不會在訪問,否則不要強制刪除有狀態的Pod ``` k delete pod rwfile-0 --force --grace-period 0 ``` ## 小結 - StatefulSet建立Pod都有一個從零開始的順序索引 - 通常會建立一個與StatefulSet對應的headless Service。 - 擴容一個StatefulSet會使用下一個順序索引建立一個新的Pod,縮容會刪除索引值最高的。 - 新建StatefulSet需要指定headless ServiceName和volumeClaimTemplates。 - 使用DNS發現StatefulSet的夥伴節點 - 強制刪除:`k delete pod rwfile-0 --force --grace-pe