有狀態服務StatefulSet支持通過VolumeClaimTemplate為每個Pod創建PV和PVC。并且刪除和減少Pod時,不會刪除StatefulSet的PV和PVC。本文為您介紹如何通過VolumeClaimTemplate實現StatefulSet持久化存儲。
前提條件
應用場景
有狀態服務StatefulSet的應用場景:
穩定的部署次序:有序部署或擴展,需要根據定義的順序依次進行(即從0到N-1,在下一個Pod運行之前,所有之前的Pod必須都是Running和Ready狀態)。
穩定的縮容次序:有序收縮或刪除,需要根據定義的順序依次進行(即從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文件仍然存在,說明云盤的數據可持久化保存。