1119 字
6 分钟
kubernetes-statefulSet
1. StatefulSet 简介
StatefulSet 是 Kubernetes 中用于 有状态应用(Stateful Applications)的控制器,与 Deployment 类似,但提供稳定的 Pod 标识、持久存储和有序部署等特性。常用于 数据库、分布式存储、ZooKeeper、Kafka 等应用。
StatefulSet 主要特点:
- 稳定的网络标识(Pod 名称唯一且有序)。
- 稳定且持久的存储(每个 Pod 绑定独立的 PV,不随 Pod 删除)。
- 有序部署、扩容、缩容、删除(保证 Pod 按序号启动/停止)。
- 支持拓扑感知(不同 Pod 可部署到不同节点)。
2. StatefulSet 关键组件
| 组件 | 作用 |
|---|---|
| StatefulSet | 控制有状态应用的部署与管理 |
| Headless Service | 提供稳定的 Pod 解析,格式 pod-name.service-name.namespace.svc.cluster.local |
| PersistentVolumeClaim (PVC) | 绑定持久存储,确保 Pod 重新调度后仍然可用 |
3. StatefulSet 拓扑结构
StatefulSet 主要通过 Headless Service 结合 DNS 解析,确保每个 Pod 都有稳定的 FQDN:
+--------------------+
| Service: my-svc |
| ClusterIP: None | <--- 通过 DNS 解析 Pod
+--------------------+
|
------------------------
| | |
Pod-0 Pod-1 Pod-2- Pod 名称固定,例如
web-0, web-1, web-2 - 解析方式:
web-0.my-svc.default.svc.cluster.local - 允许应用使用 直接 Pod-to-Pod 连接,适用于数据库主从复制等场景。
4. StatefulSet 存储管理
在 StatefulSet 中,每个 Pod 绑定一个 独立的 PersistentVolume (PV),即使 Pod 重新调度,也会保持相同的存储数据。
+----------------------+ +----------------------+
| Pod-0 (web-0) | --> | PVC-0 -> PV-0 |
+----------------------+ +----------------------+
| Pod-1 (web-1) | --> | PVC-1 -> PV-1 |
+----------------------+ +----------------------+📌 重要特性:
- PVC 绑定不变:Pod-0 永远绑定
PVC-0,不会与 Pod-1 共享。 - 适用于数据库、分布式存储,保证数据持久化,不会因 Pod 重新调度丢失。
5. StatefulSet 部署示例
(1)创建 Headless Service
apiVersion: v1
kind: Service
metadata:
name: my-svc
spec:
clusterIP: None # Headless Service
selector:
app: my-app
ports:
- port: 80(2)创建 StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "my-svc"
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: web-storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: web-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi📌 关键点:
serviceName: "my-svc"绑定 Headless Service。replicas: 3创建web-0, web-1, web-2。volumeClaimTemplates自动为每个 Pod 申请 独立 PVC。
6. StatefulSet 关键特性
| 关键点 | 说明 |
|---|---|
| Pod 有序命名 | Pod 名称格式 statefulset-name-index,如 web-0, web-1 |
| Pod 有序启动 & 终止 | 按 web-0 -> web-1 -> web-2 顺序创建,按相反顺序删除 |
| Pod 拓扑感知 | 可通过 nodeAffinity 或 podAntiAffinity 指定调度策略 |
| 持久存储 PVC 绑定不变 | web-0 始终绑定 PVC-0,不会随意更换 |
7. StatefulSet 拓扑调度
(1)节点亲和性(Node Affinity) 指定 Pod 只能运行在 region=us-east-1 的节点:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/region
operator: In
values:
- us-east-1(2)Pod 反亲和性(Pod Anti-Affinity) 确保 Pod 不运行在相同节点,提高可用性:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-app
topologyKey: "kubernetes.io/hostname"8. StatefulSet 操作
(1)查看 StatefulSet
kubectl get statefulset
kubectl describe statefulset web(2)查看 Pod & 存储
kubectl get pods -o wide
kubectl get pvc
kubectl get pv(3)访问 Pod
kubectl exec -it web-0 -- /bin/sh(4)扩容 StatefulSet
kubectl scale statefulset web --replicas=5(5)删除 StatefulSet
kubectl delete statefulset web --cascade=orphan # 保留 PVC9. StatefulSet VS Deployment
| 特性 | StatefulSet | Deployment |
|---|---|---|
| Pod 名称固定 | ✅ 是(web-0, web-1) | ❌ 否(随机生成) |
| 有序部署 & 终止 | ✅ 是 | ❌ 否 |
| 持久存储 PVC 绑定 | ✅ 是(PVC 绑定 Pod) | ❌ 否(Pod 共享 PVC) |
| Headless Service | ✅ 是 | ❌ 否 |
| 适用于 | 数据库、分布式存储 | 无状态 Web 应用 |
练习, MySQL StatefulSet的部署:
- Headless Service:
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
clusterIP: None
selector:
app: mysql
ports:
- name: mysql
port: 3306(base) PS C:\Users\Kevin Leen\OneDrive - San Jose-Evergreen Community College District\Desktop\k8s> k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 67m
mysql ClusterIP None <none> 3306/TCP 10s
(base) PS C:\Users\Kevin Leen\OneDrive - San Jose-Evergreen Community College District\Desktop\k8s> k get ep
NAME ENDPOINTS AGE
kubernetes 10.0.2.177:443,10.0.3.135:443 69m
mysql <none> 2m20s- PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp2 # 明确指定使用 gp2 StorageClass
resources:
requests:
storage: 10GiEKS中的storageclass :
kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 61m(base) PS C:\Users\Kevin Leen\OneDrive - San Jose-Evergreen Community College District\Desktop\k8s> k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 68m
mysql ClusterIP None <none> 3306/TCP 96s- StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: data-cleanup
image: busybox:1.28
command: ["sh", "-c", "rm -rf /var/lib/mysql/*"] #提前清理数据避免报错
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "your_root_password"
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc(base) PS C:\Users\Kevin Leen\OneDrive - San Jose-Evergreen Community College District\Desktop\k8s> k exec -it mysql-0 -c mysql -- sh
sh-4.2#
sh-4.2# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> kubernetes-statefulSet
https://fuwari.vercel.app/posts/kubernetes-statefulset/kubernetes-statefulset/