StatefulSet是Kubernetes专为有状态应用设计的控制器,核心功能包括:稳定的网络标识(Pod名称和DNS不变)、持久化存储(PVC与PV绑定,数据不丢失)、有序部署/扩展/删除(按序号依次执行)。适用于数据库(MySQL、PostgreSQL)、消息队列(Kafka、RabbitMQ)、分布式存储(Ceph、GlusterFS)等需要状态保持的场景。
yum -y install nfs-utils rpcbind
systemctl enable nfs rpcbind && systemctl start nfs rpcbind
/usr/local/kubernetes/redis/pv1~/pv6),并设置权限:echo "/usr/local/kubernetes/redis/pv1 *(rw,no_root_squash,sync)" >> /etc/exports
mkdir -p /usr/local/kubernetes/redis/pv{1..6}
chmod 777 /usr/local/kubernetes/redis/pv{1..6}
exportfs -a # 生效配置
```。
Headless Service(clusterIP: None)是为StatefulSet提供稳定网络标识的关键,它会为每个Pod生成可解析的DNS记录(格式:<pod-name>.<service-name>.<namespace>.svc.cluster.local)。
示例YAML(nginx-headless.yaml):
apiVersion: v1
kind: Service
metadata:
name: nginx # Service名称,需与StatefulSet的serviceName一致
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None # 关键:定义为Headless Service
selector:
app: nginx # 必须匹配StatefulSet模板的labels
创建命令:kubectl create -f nginx-headless.yaml。
StatefulSet通过volumeClaimTemplates自动为每个Pod创建PVC(持久化存储),并通过serviceName关联Headless Service。
示例YAML(nginx-sts.yaml):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web # StatefulSet名称,Pod名称格式为<name>-<序号>(如web-0、web-1)
spec:
serviceName: "nginx" # 必须与Headless Service名称一致
replicas: 3 # Pod副本数
selector:
matchLabels:
app: nginx # 必须匹配Pod模板的labels
template:
metadata:
labels:
app: nginx # 必须匹配serviceName的selector
spec:
terminationGracePeriodSeconds: 10 # Pod终止前的宽限期(秒)
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www # 卷名称,需与volumeClaimTemplates中的metadata.name一致
mountPath: /usr/share/nginx/html # 容器内挂载路径
volumeClaimTemplates: # 自动生成PVC的模板
- metadata:
name: www # PVC名称,Pod中挂载的卷名称
spec:
accessModes: ["ReadWriteOnce"] # 存储访问模式(单节点读写)
storageClassName: "managed-nfs-storage" # 存储类(需提前创建)
resources:
requests:
storage: 100Mi # 存储容量
创建命令:kubectl create -f nginx-sts.yaml。
StatefulSet的Pod会按序号依次创建(从0开始),且每个Pod的STATUS为Running:
kubectl get pods -l app=nginx -owide
# 输出示例:
# NAME READY STATUS RESTARTS AGE IP NODE
# web-0 1/1 Running 0 2m 10.244.1.61 node1
# web-1 1/1 Running 0 1m 10.244.2.80 node2
# web-2 1/1 Running 0 1m 10.244.3.91 node3
```。
### 2. 验证网络标识
每个Pod的DNS名称遵循`<pod-name>.<service-name>.<namespace>.svc.cluster.local`格式,可通过`nslookup`解析:
```bash
# 在CentOS节点上执行(需安装busybox工具):
kubectl run -i --tty --image busybox:dnsutils dns-test --restart=Never --rm /bin/sh
# 在容器内执行:
nslookup web-0.nginx
# 输出示例:
# Server: 10.96.0.10
# Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
# Name: web-0.nginx
# Address 1: 10.244.1.61 web-0.nginx.default.svc.cluster.local
即使Pod重启或重新调度,DNS名称和主机名(web-0)保持不变。
进入Pod并向挂载目录写入数据,删除Pod后重新创建,数据仍存在:
# 向web-0写入数据:
kubectl exec -it web-0 -- sh -c "echo 'web-0 data' > /usr/share/nginx/html/index.html"
# 查看web-0的数据:
kubectl exec -it web-0 -- cat /usr/share/nginx/html/index.html
# 输出:web-0 data
# 删除web-0:
kubectl delete pod web-0
# 等待web-0重新创建(NAME仍为web-0):
kubectl get pods -w
# 查看新web-0的数据:
kubectl exec -it web-0 -- cat /usr/share/nginx/html/index.html
# 输出仍为:web-0 data(数据未丢失)
这是因为PVC与PV绑定,Pod重建后会重新挂载原PV。
若volumeClaimTemplates未生成PVC,需检查:
kubectl get storageclass);volumeClaimTemplates配置是否正确(如metadata.name、spec.accessModes)。若Pod无法调度,需检查:
kubectl describe node <node-name>);kubectl get storageclass查看PROVISIONER字段);systemctl status nfs)。若Pod删除后数据丢失,需检查:
kubectl get pvc);persistentVolumeReclaimPolicy是否为Retain(默认是Delete,需修改为Retain以保留数据)。通过以上步骤,可在CentOS环境下快速部署并使用StatefulSet管理有状态应用,确保应用的稳定性和数据持久性。