具狀態服務StatefulSet支援通過VolumeClaimTemplate為每個Pod建立PV和PVC。並且刪除和減少Pod時,不會刪除StatefulSet的PV和PVC。本文為您介紹如何通過VolumeClaimTemplate實現StatefulSet持久化儲存。
前提條件
應用情境
具狀態服務StatefulSet的應用情境:
穩定的部署次序:有序部署或擴充,需要根據定義的順序依次進行(即從0到N-1,在下一個Pod運行之前,所有之前的Pod必須都是Running和Ready狀態)。
穩定的縮容次序:有序收縮或刪除,需要根據定義的順序依次進行(即從N-1到0,從N-1到0, 在下一個Pod執行結束之前 ,所有之前的Pod都需要刪除完成)。
穩定的網路標誌:Pod重新調度後其PodName和HostName不變。
穩定的持久化儲存:基於PVC,Pod重新調度後仍能訪問到相同的持久化資料。
建立StatefulSet服務
您可以通過VolumeClaimTemplates
自動建立PVC及PV。
volumeClaimTemplates:表示一類PVC的模板,系統會根據具狀態服務-StatefulSet配置的replicas數量,建立相應數量的PVC。這些PVC除了名字不一樣,其他配置都相同。
使用以下內容,建立statefulset.yaml。
建立一個Service和StatefulSet,並且設定該StatefulSet包含2個Pod。
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web volumeMounts: - name: disk-ssd mountPath: /data volumeClaimTemplates: - metadata: name: disk-ssd spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-disk-ssd" resources: requests: storage: 20Gi
replicas
:本例中設定為2,表示建立2個Pod。mountPath
:雲端硬碟在容器中掛載的位置。accessModes
:訪問模式。storageClassName
:本例配置為alicloud-disk-ssd
,表示使用的是阿里SSD類型的雲端硬碟。storage
:聲明應用的使用量。
執行以下命令,部署StatefulSet服務。
kubectl create -f statefulset.yaml
執行以下命令,查看已部署的Pod。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 6m web-1 1/1 Running 0 6m
執行以下命令,查看PVC。
kubectl get pvc
預期輸出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 7m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 6m
驗證PVC會根據StatefulSet服務擴容而擴容
執行以下命令,擴容StatefulSet服務到3個Pod。
kubectl scale sts web --replicas=3
預期輸出:
statefulset.apps/web scaled
執行以下命令,查看擴容後的Pod。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 34m web-1 1/1 Running 0 33m web-2 1/1 Running 0 26m
執行以下命令,查看擴容後的PVC。
kubectl get pvc
預期輸出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 35m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 34m disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 27m
可以看到,StatefulSet擴容到3個Pod後,PVC也擴容到3個。
驗證縮容StatefulSet後,PVC保持不變
執行以下命令,縮減StatefulSet服務到2個Pod。
kubectl scale sts web --replicas=2
預期輸出:
statefulset.apps/web scaled
執行以下命令,查看縮容後的Pod。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 38m web-1 1/1 Running 0 38m
Pod的數量已縮減為2。
執行以下命令,查看縮容後的PVC。
kubectl get pvc
預期輸出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 39m disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 39m disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 31m
縮容StatefulSet到2個Pod後,PVC仍為3個。說明PVC不會因StatefulSet縮容而縮減。
驗證StatefulSet再次擴容後,PVC保持不變
驗證StatefulSet擴容後縮容,再次擴容後,PVC保持不變。
執行以下命令,擴容StatefulSet服務到3個Pod。
kubectl scale sts web --replicas=3
預期輸出:
statefulset.apps/web scaled
執行以下命令,查看擴容後的Pod。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 1h web-1 1/1 Running 0 1h web-2 1/1 Running 0 8s
執行以下命令,查看擴容後的PVC。
kubectl get pvc
預期輸出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 1h
擴容後新建立的Pod仍會使用原來的PVC。
驗證刪除StatefulSet服務的Pod,PVC保持不變
執行以下命令,查看名稱為web-1的Pod,引用的PVC。
kubectl describe pod web-1 | grep ClaimName
預期輸出:
ClaimName: disk-ssd-web-1
執行以下命令,刪除名稱為web-1的Pod。
kubectl delete pod web-1
預期輸出:
pod "web-1" deleted
執行以下命令,查看Pod。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 1h web-1 1/1 Running 0 25s web-2 1/1 Running 0 9m
重新建立的Pod與刪除前的Pod名稱一致。
執行以下命令,查看PVC。
kubectl get pvc
預期輸出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-ssd-web-0 Bound d-2zegw7et6xc96nbojuoo 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-1 Bound d-2zefbrqggvkd10xb523h 20Gi RWO alicloud-disk-ssd 1h disk-ssd-web-2 Bound d-2ze4jx1zymn4n9j3pic2 20Gi RWO alicloud-disk-ssd 1h
刪除後新建立的Pod仍會使用原來的PVC。
驗證StatefulSet服務的持久化儲存
執行以下命令,查看/data路徑下的檔案。
kubectl exec web-1 -- ls /data
預期輸出:
lost+found
執行以下命令,在/data路徑下建立檔案statefulset。
kubectl exec web-1 -- touch /data/statefulset
執行以下命令,查看/data路徑下的檔案。
kubectl exec web-1 -- ls /data
預期輸出:
lost+found statefulset
執行以下命令,刪除名稱為web-1的Pod。
kubectl delete pod web-1
預期輸出:
pod "web-1" deleted
執行以下命令,查看/data路徑下的檔案。
kubectl exec web-1 -- ls /data
預期輸出:
lost+found statefulset
statefulset檔案仍然存在,說明雲端硬碟的資料可持久化儲存。