首先,需要确认StatefulSet和Deployment的主要区别。Deployment管理的Pod是无状态的,每个Pod都是相同的,可以互相替换,名称也是随机的。而StatefulSet的Pod名称是有序且稳定的,,这样每个Pod都有固定的标识,便于有状态应用处理网络和存储。
| 特性 | StatefulSet | Deployment |
|---|---|---|
| 网络标识 | 稳定(固定名称/DNS) | 随机名称,无固定 DNS |
| 存储 | 独立 PVC,持久化 | 临时存储(通常) |
| 部署顺序 | 按序号顺序创建/删除 | 并行创建/删除 |
| 适用场景 | 有状态应用(数据库、中间件) | 无状态应用(Web 服务等) |
StatefulSet如何管理存储呢?每个Pod需要有自己的持久卷(PV),这样即使Pod被重新调度,数据也不会丢失。StatefulSet使用volumeClaimTemplates来为每个Pod生成PersistentVolumeClaim(PVC),这样每个Pod都有自己的存储。例如,当创建mysql-0时,会自动生成一个pvc-mysql-0的声明,绑定到对应的PV。这样保证了数据的持久化和独立性。
StatefulSet 实例:部署 MySQL 集群
1. 创建 Headless Service
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
clusterIP: None # Headless Service 标识
selector:
app: mysql
ports:
- port: 3306
name: mysql
说明:
clusterIP: None表示这是一个 Headless Service,直接暴露 Pod 的 DNS 记录。Headless Service 通过 禁用 ClusterIP 和 直接暴露 Pod IP,为有状态应用提供了稳定的网络标识和精确的端点访问能力。它是 StatefulSet 实现数据持久化、有序扩缩容等特性的关键基础组件。
2. 创建 StatefulSet
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-service # 关联 Headless Service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpassword" #设置 MySQL 的 root 密码,生产环境中建议用Secret。
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ] #该 PV 只能被单节点读写
resources:
requests:
storage: 1Gi
关键配置解析:
volumeClaimTemplates:每个 Pod 自动创建名为mysql-data的 PVC,存储类为默认的standard(可按需替换)。存储挂载: PVC 挂载到 MySQL 的数据目录
/var/lib/mysql,确保数据持久化。
部署与验证
-
应用配置:
kubectl apply -f mysql-service.yaml kubectl apply -f mysql-statefulset.yaml -
查看资源状态:
kubectl get statefulset/mysql # 查看 StatefulSet 状态 kubectl get pods -l app=mysql # 观察 Pod 按顺序创建 kubectl get pvc -l app=mysql # 查看自动创建的 PVC -
验证 DNS 稳定性:
# 进入第一个 Pod 执行 nslookup kubectl exec -it mysql-0 /bin/sh apt-get update && apt-get install -y dnsutils nslookup mysql-service -
数据持久化测试:
- 在
mysql-0中创建测试数据库。 - 删除 Pod
mysql-0,Kubernetes 会自动重建。 - 验证数据是否仍然存在。
- 在
高级配置
-
唯一性配置(如 MySQL
server-id):env: - name: SERVER_ID value: "$(echo ${HOSTNAME} | sed 's/mysql-//')" # 提取 Pod 序号 - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password -
使用
InitContainer初始化数据:spec: initContainers: - name: init-mysql image: mysql:5.7 command: ["bash", "-c", "..." ] # 自定义初始化脚本 -
配置
livenessProbe和readinessProbe:livenessProbe: #存活探针 tcpSocket: #尝试与容器的 3306 端口建立 TCP 连接 port: 3306 initialDelaySeconds: 30 # 容器启动后等待 30 秒再开始探测 readinessProbe: #就绪探针 exec: command: ["mysql", "-uroot", "-prootpassword", "-e", "SELECT 1"]
总结
StatefulSet 是 Kubernetes 中用于管理有状态应用的核心控制器,提供稳定的网络标识、持久化存储和有序部署,适用于数据库、分布式中间件等需要固定状态和存储的场景。
1171

被折叠的 条评论
为什么被折叠?



