RedCloud Help

10.Statefulset控制器

10.1 概念、原理解读

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 重新创建时保留其数据。这为应用程序提供了持久化存储的能力,使得数 据不会丢失或重置。

10.2 使用案例:不熟web站点

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: updateStrategy: rollingUpdate: partition: 1 maxUnavailable: 0 selector: matchLabels: app: nginx serviceName: "nginx" replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: web
kubectl apply -f statefulset.yaml # 查看statefulset状态 kubectl get statefulset # 查看pod kubectl get pods -l app=nginx # #使用kubectl run 运行一个提供nslookup 命令的容器的,通过对pod 主机名执行nslookup, 可以检查它们在集群内部的DNS 地址: kubectl run busybox --image docker.io/library/busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh nslookup web-0.nginx.default.svc.cluster.local Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.nginx.default.svc.cluster.local Address 1: 10.188.1.230 web-0.nginx.default.svc.cluster.local # stateful创建的pod也是有dns记录的 nslookup nginx.default.svc.cluster.local Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: nginx.default.svc.cluster.local Address 1: 10.188.1.231 web-1.nginx.default.svc.cluster.local Address 2: 10.188.1.230 web-0.nginx.default.svc.cluster.local #查询service dns,会把对应的pod ip解析出来
apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: type: ClusterIP ports: - port: 80 protocol: TCP targetPort: 80 selector: run: my-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: busybox imagePullPolicy: IfNotPresent ports: - containerPort: 80 command: - sleep - "3600"
kubectl get pods -l run=my-nginx NAME READY STATUS RESTARTS AGE my-nginx-58899fd9cd-j5kxj 1/1 Running 0 60s my-nginx-58899fd9cd-nqt4j 1/1 Running 0 62s # 通过Deployment创建的pod是随机生成的 kubectl run busybox --image docker.io/library/busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh nslookup my-nginx.default.svc.cluster.local Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: my-nginx.default.svc.cluster.local Address 1: 10.105.173.152 my-nginx.default.svc.cluster.local # 有ip的service解析的service的ip

10.3 扩容、缩容、更新

如果我们觉得两个副本太少了,想要增加,只需要修改配置文件statefulset.yaml 里的replicas 的 值即可,原来replicas: 2,现在变成replicaset: 3,修改之后,执行如下命令更新:

root@redcloud001:/data/k8s/test/10.statefulset# vim statefulset.yaml root@redcloud001:/data/k8s/test/10.statefulset# kubectl apply -f statefulset.yaml service/nginx unchanged statefulset.apps/web configured root@redcloud001:/data/k8s/test/10.statefulset# kubectl get pods -l run=ngxin No resources found in default namespace. root@redcloud001:/data/k8s/test/10.statefulset# kubectl get pods -l app=ngxin No resources found in default namespace. root@redcloud001:/data/k8s/test/10.statefulset# kubectl get sts NAME READY AGE web 3/3 4h52m root@redcloud001:/data/k8s/test/10.statefulset# kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 4h52m web-1 1/1 Running 0 4h50m web-2 1/1 Running 0 55s # 实时修改 root@redcloud001:/data/k8s/test/10.statefulset# kubectl edit sts web statefulset.apps/web edited root@redcloud001:/data/k8s/test/10.statefulset# kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 4h53m web-1 1/1 Running 0 4h52m web-2 1/1 Running 0 2m4s web-3 1/1 Running 0 4s web-4 1/1 Running 0 2s

动态缩容

如果我们觉得4 个Pod 副本太多了,想要减少,只需要修改配置文件statefulset.yaml 里的 replicas 的值即可,把replicaset:4 变成replicas: 2,修改之后,执行如下命令更新:

12 January 2026