什么是 Kubernetes StatefulSet?

StatefulSet 是 Kubernetes 中用于管理有状态应用的工作负载 API 对象。它可以用于部署像数据库这样的有状态服务,这些服务不仅需要持久容器存储,还需要基于顺序和固定的网络标识符。

StatefulSet 的主要功能包括:

  1. 稳定的网络标识符:StatefulSet 中的每个 Pod 都被分配一个唯一的网络标识符,这个标识符会在 Pod 重启时保持不变。
  2. 有序部署和扩展:StatefulSet 中的 Pod 会根据其序号顺序启动和终止。当进行扩展时,新添加的 Pod 会被分配一个新的序号。
  3. 有序滚动更新:当进行滚动更新时,StatefulSet 会逐个更新 Pod,同时确保不会同时更新一个 Pod 和它的后继 Pod。
  4. 持久存储:StatefulSet 可以利用 Kubernetes 的持久卷声明为其 Pod 提供存储。此存储会与 Pod 的生命周期绑定在一起。

例如,我们可以使用 StatefulSet 来部署一个有 3 个副本的 MySQL 集群:

yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  clusterIP: None

---

apiVersion: apps/v1 
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: "mysql"
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-persistent-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

这个清单定义了以下资源:

  1. mysql 服务,其类型为 Headless 服务,用于网络标识。
  2. mysql StatefulSet,使用 mysql 服务,拥有 3 个副本。
  3. 每个 Pod 都挂载 MySQL 的持久卷存储。
    这样我们就可以部署一个具有稳定网络标识的有状态 MySQL 集群。StatefulSet 可以确保 Pod 有序部署和滚动更新,并且存储也会随着 Pod 终止而终止。

所以,总结来说 StatefulSet 是 Kubernetes 中用于部署有状态应用的关键机制。它为 Pod 提供:

  1. 稳定的网络标识符
  2. 有序的部署、终止与更新
  3. 持久存储

理解 StatefulSet 的原理和用法对于在 Kubernetes 上部署有状态服务至关重要。这需要我们不仅理解 StatefulSet 的API接口,也需要在实践中掌握各种配置方法和注意事项。