k8s控制器Statefulset 管理有状态的应用

艺帆风顺 发布于 2025-04-02 31 次阅读


一、Statefulset控制器:概念、原理解读

StatefulSet 是 Kubernetes 中的一种控制器(Controller),用于管理有状态应用程序的部署。与
Deployment 控制器不同,StatefulSet 为每个 Pod 实例分配了一个唯一的标识符,并确保这些标识符
在 Pod 重新创建时保持不变。这为有状态应用程序提供了一些关键的功能和保证,例如稳定的网络标识
符、有序的部署和扩展以及持久化存储。 

    下面是 StatefulSet 的一些基本介绍:1、唯一标识符:每个 StatefulSet 管理的 Pod 实例都被分配了一个唯一的标识符,通常是一个整数索引。这个标识符可以用于在网络中唯一的标识每个 Pod 实例。2、稳定的网络标识符:StatefulSet 中的每个 Pod 实例都有一个稳定的网络标识符,通常是一个DNS 名称。这使得其他应用程序可以通过名称轻松地访问特定的 Pod 实例,而不需要关注其具体的 IP地址变化。3、有序的部署和扩展:StatefulSet 控制器确保 Pod 实例按照定义的顺序逐个启动和关闭。这对于依赖先前实例状态的应用程序非常重要。此外,扩展 StatefulSet 时,新的 Pod 实例也会按照指定的顺序逐个创建。4、持久化存储:StatefulSet 允许每个 Pod 实例关联一个持久化卷(Persistent Volume),这使得有状态应用程序可以在 Pod 重新创建时保留其数据。这为应用程序提供了持久化存储的能力,使得数据不会丢失或重置。

    二、yaml文件编写技巧

      1、查看 StatefulSet 资源的字段定义,使用以下命令:kubectl explain statefulset字段说明:apiVersion:定义 StatefulSet 资源需要使用的 API 版本。kind:定义资源类型。metadata:元数据对象,包含 StatefulSet 的描述信息。spec:容器相关的信息,定义了 StatefulSet 中 Pod 的期望标识。2、查看 StatefulSet 的 spec 字段如何定义,使用以下命令:kubectl explainstatefulset.spec字段说明:podManagementPolicy:Pod 的管理策略。replicas:副本数,定义 StatefulSet 中 Pod 的数量。revisionHistoryLimit:保留的历史版本数。selector:标签选择器,用于选择与之关联的 Pod。serviceName:Headless Service 的名称。template:生成 Pod 的模板,用于描述将创建的 Pod 的属性。updateStrategy:更新策略,定义如何更新 Pod。volumeClaimTemplates:存储卷申请模板,定义 Pod 使用的存储卷。3、查看 StatefulSet 的 spec.template 字段如何定义,使用以下命令:kubectl explainstatefulset.spec.template字段说明:metadata:元数据对象,包含 Pod 模板的描述信息。• spec:定义 Pod 的属性和配置。

      三、使用StatefulSet部署web节点

        #做这个实验要先确保nfs-provisioner制备器安装好创建存储类vim nfs-web.yaml---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: nfs-webprovisioner: example.com/nfsreclaimPolicy: Retain更新资源清单kubectl apply -f nfs-web.yaml查看存储类是否创建成功[root@lx100 statefulset]# kubectl get scNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEnfs example.com/nfs Delete Immediate false 6h1mnfs-web   example.com/nfs   Retain          Immediate           false                  5h15m创建service和StatefulSet控制器vim StatefulSet.yaml---apiVersion: v1kind: Servicemetadata: name: statefulset-dis labels: app: webspec: clusterIP: None ports: - port: 80 name: web selector: app: nginx---apiVersion: apps/v1kind: StatefulSetmetadata: name: statefulsetspec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: app mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: app spec: storageClassName: nfs-web accessModes: ["ReadWriteMany"] resources: requests: storage: 1Gi更新资源清单kubectl apply -f StatefulSet.yaml查看service是否创建成功[root@lx100 statefulset]# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEclient-svc ExternalName nginx-svc.nginx.svc.cluster.local 80/TCP 6dkubernetes ClusterIP 10.96.0.1 443/TCP 34dmysql ClusterIP 10.105.22.22 3306/TCP 5d23hstatefulset-dis ClusterIP None 80/TCP 4h53m查看StatefulSet是否创建成功kubectl get stsNAME READY AGEstatefulset 2/2 4h52m测试:kubectl run busybox --image busybox:1.28 --restart=Never --rm -it -- shkubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead./ # nslookup statefulset-dis.default.svc.cluster.localServer: 10.96.0.10Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
        Name: statefulset-dis.default.svc.cluster.localAddress 1: 10.246.71.106 10-246-71-106.statefulset-dis.default.svc.cluster.localAddress 2: 10.247.66.165 10-247-66-165.statefulset-dis.default.svc.cluster.local

        四、扩容、缩容和更新

          扩容:修改replicas: 2为replicas: 3kubectl apply -f StatefulSet.yaml查看:[root@lx100 statefulset]# kubectl get stsNAME READY AGEstatefulset 3/3 4h57m[root@lx100 statefulset]# kubectl get pod -l app=nginxNAME READY STATUS RESTARTS AGEstatefulset-0 1/1 Running 0 4h57mstatefulset-1 1/1 Running 0 4h57mstatefulset-2 1/1 Running 0 2m25s缩容:修改replicas: 3为replicas: 2kubectl apply -f statefulset.yaml 查看[root@lx100 statefulset]# kubectl get stsNAME READY AGEstatefulset 2/2 4h58m[root@lx100 statefulset]# kubectl get pod -l app=nginxNAME READY STATUS RESTARTS AGEstatefulset-0 1/1 Running 0 4h58mstatefulset-1 1/1 Running 0 4h58m更新:修改image: nginx为image: docker.io/janakiramm/myapp:v1重新开一个终端动态监控pod[root@lx100 ~]# kubectl get pod -w -l app=nginxNAME READY STATUS RESTARTS AGEstatefulset-0 1/1 Running 0 5m14sstatefulset-1 1/1 Running 0 5m12sstatefulset-1 1/1 Terminating 0 5m18sstatefulset-1 1/1 Terminating 0 5m18sstatefulset-1 0/1 Terminating 0 5m19sstatefulset-1 0/1 Terminating 0 5m19sstatefulset-1 0/1 Terminating 0 5m19sstatefulset-1 0/1 Pending 0 0sstatefulset-1 0/1 Pending 0 0sstatefulset-1 0/1 ContainerCreating 0 0sstatefulset-1 0/1 ContainerCreating 0 0sstatefulset-1 1/1 Running 0 1sstatefulset-0 1/1 Terminating 0 5m22sstatefulset-0 1/1 Terminating 0 5m22sstatefulset-0 0/1 Terminating 0 5m23sstatefulset-0 0/1 Terminating 0 5m23sstatefulset-0 0/1 Terminating 0 5m23sstatefulset-0 0/1 Pending 0 0sstatefulset-0 0/1 Pending 0 0sstatefulset-0 0/1 ContainerCreating 0 0sstatefulset-0 0/1 ContainerCreating 0 1sstatefulset-0 1/1 Running 0 29sstatefulset-1 1/1 Running 0 33sstatefulset-0 1/1 Running 0 46s更新资源清单kubectl apply -f StatefulSet.yaml