10.Statefulset控制器
10.1 概念、原理解读
StatefulSet 是Kubernetes 中的一种控制器(Controller),用于管理有状态应用程序的部署。与 Deployment 控制器不同,StatefulSet 为每个Pod 实例分配了一个唯一的标识符,并确保这些标识符 在Pod 重新创建时保持不变。这为有状态应用程序提供了一些关键的功能和保证,例如稳定的网络标识符、有序的部署和扩展以及持久化存储。
下面是StatefulSet 的一些基本介绍:
唯一标识符:每个StatefulSet 管理的Pod 实例都被分配了一个唯一的标识符,通常是一个整数 索引。这个标识符可以用于在网络中唯一地标识每个Pod 实例。
稳定的网络标识符:StatefulSet 中的每个Pod 实例都有一个稳定的网络标识符,通常是一个 DNS 名称。这使得其他应用程序可以通过名称轻松地访问特定的Pod 实例,而不需要关注其具体的IP 地址变化。
有序的部署和扩展:StatefulSet 控制器确保Pod 实例按照定义的顺序逐个启动和关闭。这对于 依赖先前实例状态的应用程序非常重要。此外,扩展StatefulSet 时,新的Pod 实例也会按照指定的顺 序逐个创建。
持久化存储: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