Kubernetes StatefulSet
介绍
在 Kubernetes 中,StatefulSet 是一种用于管理有状态应用的工作负载 API 对象。与 Deployment 不同,StatefulSet 为每个 Pod 提供唯一的网络标识和稳定的存储,确保 Pod 的顺序性和唯一性。这使得 StatefulSet 非常适合运行数据库、分布式存储系统等需要持久化存储和稳定网络标识的应用。
备注
StatefulSet 确保 Pod 的创建、删除和扩展操作是有序的,并且每个 Pod 都有唯一的标识符。
StatefulSet 的核心特性
- 稳定的网络标识:每个 Pod 都有一个唯一的、稳定的网络标识符(如
myapp-0
,myapp-1
等),即使 Pod 被重新调度,其标识符也不会改变。 - 稳定的存储:每个 Pod 都有独立的持久化存储卷,即使 Pod 被删除或重新创建,存储卷也会保持不变。
- 有序部署和扩展:StatefulSet 按照顺序创建和删除 Pod,确保应用的有序性。
- 有序滚动更新:StatefulSet 支持有序的滚动更新,确保应用在更新过程中保持稳定。
StatefulSet 的使用场景
StatefulSet 通常用于以下场景:
- 数据库集群:如 MySQL、PostgreSQL 等需要持久化存储和唯一标识的数据库。
- 分布式存储系统:如 Elasticsearch、Cassandra 等需要稳定网络标识和存储的系统。
- 消息队列:如 Kafka、RabbitMQ 等需要有序性和持久化存储的消息队列系统。
创建 StatefulSet
以下是一个简单的 StatefulSet 示例,用于运行一个 MySQL 数据库:
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
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: "password"
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
解释
serviceName: "mysql"
:指定与 StatefulSet 关联的 Headless Service 名称。replicas: 3
:创建 3 个 Pod,分别命名为mysql-0
,mysql-1
,mysql-2
。volumeClaimTemplates
:为每个 Pod 创建一个独立的持久化存储卷。
部署 StatefulSet
使用以下命令部署 StatefulSet:
bash
kubectl apply -f mysql-statefulset.yaml
查看 StatefulSet 状态
bash
kubectl get statefulset mysql
kubectl get pods -l app=mysql
输出示例:
plaintext
NAME READY AGE
mysql-0 1/1 10s
mysql-1 1/1 8s
mysql-2 1/1 6s
StatefulSet 的实际案例
假设我们需要部署一个 Elasticsearch 集群,每个节点都需要独立的存储和唯一的网络标识。我们可以使用 StatefulSet 来实现:
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: elasticsearch
spec:
serviceName: "elasticsearch"
replicas: 3
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: elasticsearch:7.10.1
ports:
- containerPort: 9200
volumeMounts:
- name: es-data
mountPath: /usr/share/elasticsearch/data
volumeClaimTemplates:
- metadata:
name: es-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
提示
StatefulSet 的每个 Pod 都会自动挂载独立的存储卷,确保数据的持久化和隔离。
总结
StatefulSet 是 Kubernetes 中管理有状态应用的重要工具。它通过提供稳定的网络标识、持久化存储和有序的部署方式,确保有状态应用的高可用性和数据一致性。无论是数据库、分布式存储系统还是消息队列,StatefulSet 都能满足其独特的需求。
附加资源
练习
- 尝试创建一个 StatefulSet,运行一个 Redis 集群,并观察 Pod 的创建顺序。
- 修改 StatefulSet 的
replicas
字段,观察 Pod 的扩展和收缩行为。 - 为 StatefulSet 添加一个 Headless Service,并测试 Pod 之间的通信。