有状态服务StatefulSet支持通过VolumeClaimTemplate为每个Pod创建PV和PVC。并且删除和减少Pod时,不会删除StatefulSet的PV和PVC。本文为您介绍如何通过VolumeClaimTemplate实现StatefulSet持久化存储。
背景信息
有状态服务-StatefulSet的应用场景:
稳定的部署次序:有序部署或扩展,需要根据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前,所有之前的Pod必须都是Running和Ready状态)。
稳定的扩展次序:有序收缩或删除,需要根据定义的顺序依次进行(即从N-1到0,在下一个Pod运行之前,所有之前的Pod必须都是Running和Ready状态)。
稳定的网络标志:Pod重新调度后其PodName和HostName保持不变。
稳定的持久化存储:基于PVC,Pod重新调度后仍能访问到相同的持久化数据。
有状态服务-StatefulSet的使用方式:
通过volumeClaimTemplates
自动创建PVC及PV。
文本将介绍:
创建StatefulSet服务
伸缩StatefulSet服务
删除StatefulSet服务
StatefulSet服务的持久化存储
前提条件
部署StatefulSet服务
volumeClaimTemplates
:表示一类PVC的模板,系统会根据有状态服务-StatefulSet配置的replicas数量,创建相应数量的PVC。这些PVC除了名字不一样之外其他配置都是一样的。
创建statefulset.yaml文件。
说明storageClassName
配置为alicloud-disk-ssd,表示使用的是阿里SSD类型的云盘。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
执行以下命令,部署StatefulSet服务。
kubectl create -f statefulset.yaml
同时在另一个窗口中,执行以下命令,查看Pod按照次序部署。
kubectl get pod -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 0s web-0 1/1 Running 0 20s 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 7s
执行以下命令,查看已部署的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
伸缩StatefulSet服务
扩容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服务
执行以下命令,缩减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
PVC和PV并没有随Pod一起缩减。
再次扩容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 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和PV。
删除StatefulSet服务
执行以下命令,查看名称为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与删除前的Pod一致。
同时在另一个窗口中,执行以下命令,查看Pod删除和重新创建的过程。
kubectl get pod -w -l app=nginx
预期输出:
NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 102m web-1 1/1 Running 0 69s web-2 1/1 Running 0 10m web-1 1/1 Terminating 0 89s web-1 0/1 Terminating 0 89s web-1 0/1 Terminating 0 90s web-1 0/1 Terminating 0 90s 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 20s
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路径下的文件,刚刚创建的文件statefulset并没有被删除,说明云盘的数据可持久保存。
kubectl exec web-1 -- ls /data
预期输出:
lost+found statefulset