跳到主要内容

Kubernetes StatefulSet

介绍

在 Kubernetes 中,StatefulSet 是一种用于管理有状态应用的工作负载 API 对象。与 Deployment 不同,StatefulSet 为每个 Pod 提供唯一的网络标识和稳定的存储,确保 Pod 的顺序性和唯一性。这使得 StatefulSet 非常适合运行数据库、分布式存储系统等需要持久化存储和稳定网络标识的应用。

备注

StatefulSet 确保 Pod 的创建、删除和扩展操作是有序的,并且每个 Pod 都有唯一的标识符。

StatefulSet 的核心特性

  1. 稳定的网络标识:每个 Pod 都有一个唯一的、稳定的网络标识符(如 myapp-0, myapp-1 等),即使 Pod 被重新调度,其标识符也不会改变。
  2. 稳定的存储:每个 Pod 都有独立的持久化存储卷,即使 Pod 被删除或重新创建,存储卷也会保持不变。
  3. 有序部署和扩展:StatefulSet 按照顺序创建和删除 Pod,确保应用的有序性。
  4. 有序滚动更新: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 都能满足其独特的需求。

附加资源

练习

  1. 尝试创建一个 StatefulSet,运行一个 Redis 集群,并观察 Pod 的创建顺序。
  2. 修改 StatefulSet 的 replicas 字段,观察 Pod 的扩展和收缩行为。
  3. 为 StatefulSet 添加一个 Headless Service,并测试 Pod 之间的通信。