StatefulSet(有状态应用集)

StatefulSet

如果我们需要部署多个 MySQL 实例,就需要用到 StatefulSet。 StatefulSet 是用来管理有状态的应用。一般用于管理数据库、缓存等。 与 Deployment 类似, StatefulSet 用来管理 Pod 集合的部署和扩缩。 Deployment 用来部署无状态应用。StatefulSet 用来有状态应用。


创建 StatefulSet

StatefulSet 配置模版

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-sts
spec:
  selector:
    matchLabels:
      app: mysql # 必须匹配 .spec.template.metadata.labels
  serviceName: "mysql-svc"
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: mysql # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql #容器中的目录
              name: data-volume
  volumeClaimTemplates:
    - metadata:
        name: data-volume
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: local-path
        resources:
          requests:
            storage: 1Gi

稳定的存储

在 StatefulSet 中使用 VolumeClaimTemplate,为每个 Pod 创建持久卷声明(PVC)。 每个 Pod 将会得到基于 local-path 存储类动态创建的持久卷(PV)。 Pod 创建(或重新调度)时,会挂载与其声明相关联的持久卷。 请注意,当 Pod 或者 StatefulSet 被删除时,持久卷声明和关联的持久卷不会被删除。


Pod 标识

在具有 N 个副本的 StatefulSet 中,每个 Pod 会被分配一个从 0 到 N-1 的整数序号,该序号在此 StatefulSet 上是唯一的。 StatefulSet 中的每个 Pod 主机名的格式为 StatefulSet 名称-序号。 上例将会创建三个名称分别为 mysql-0、mysql-1、mysql-2 的 Pod。


部署和扩缩保证

  • 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 0..N-1。
  • 当删除 Pod 时,它们是逆序终止的,顺序为 N-1..0。
  • 在将扩缩操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
  • 在一个 Pod 终止之前,所有的继任者必须完全关闭。

# 运行
$ kubectl apply -f statefulset.yaml
statefulset.apps/mysql-sts created
# 观察进度
$ kubectl get pod --watch
NAME          READY   STATUS    RESTARTS   AGE
mysql-sts-0   0/1     Pending   0          0s
mysql-sts-0   0/1     Pending   0          17s
mysql-sts-0   0/1     ContainerCreating   0          17s
mysql-sts-0   1/1     Running             0          22s
mysql-sts-1   0/1     Pending             0          0s
mysql-sts-1   0/1     Pending             0          18s
mysql-sts-1   0/1     ContainerCreating   0          19s
mysql-sts-1   1/1     Running             0          35s
mysql-sts-2   0/1     Pending             0          0s
mysql-sts-2   0/1     Pending             0          16s
mysql-sts-2   0/1     ContainerCreating   0          16s
mysql-sts-2   1/1     Running             0          63s

在上面的 mysql 示例被创建后,会按照 mysql-0、mysql-1、mysql-2 的顺序部署三个 Pod。 在 mysql-0 进入 Running 和 Ready 状态前不会部署 mysql-1。 在 mysql-1 进入 Running 和 Ready 状态前不会部署 mysql-2。 如果 mysql-1 已经处于 Running 和 Ready 状态,而 mysql-2 尚未部署,在此期间发生了 mysql-0 运行失败,那么 mysql-2 将不会被部署,要等到 mysql-0 部署完成并进入 Running 和 Ready 状态后,才会部署 mysql-2。 如果用户想将示例中的 StatefulSet 扩缩为 replicas=1,首先被终止的是 mysql-2。 在 mysql-2 没有被完全停止和删除前,mysql-1 不会被终止。 当 mysql-2 已被终止和删除、mysql-1 尚未被终止,如果在此期间发生 mysql-0 运行失败, 那么就不会终止 mysql-1,必须等到 mysql-0 进入 Running 和 Ready 状态后才会终止 web-1。


参考文档:
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/ https://kubernetes.io/zh-cn/docs/tasks/run-application/run-replicated-stateful-application/

results matching ""

    No results matching ""