StatefulSet

本页面介绍 Kubernetes StatefulSet 对象及其在 Google Kubernetes Engine 中的使用。

什么是 StatefulSet?

StatefulSet 表示一组具有唯一持久身份和稳定主机名的 [Pod]。无论这些 Pod 安排到何处,GKE 都会对其进行维护。任何给定 StatefulSet Pod 的状态信息和其他弹性数据都存放在与 StatefulSet 关联的永久性磁盘存储空间中。

StatefulSet 针对 Pod 的身份和排序使用序数索引。默认情况下,StatefulSet Pod 按顺序部署,并按反向顺序终止。例如,名为 web 的 StatefulSet 有三个 Pod,分别名为 web-0web-1web-2。在 web Pod 规范被更改后,系统会按顺序正常停止并重新创建其 Pod。在此示例中,系统会先终止 web-2,然后终止 web-1,依此类推。或者,您也可以指定 podManagementPolicy: Parallel 字段,让 StatefulSet 并行启动或终止其所有 Pod,而不是等待 Pod 变为运行并就绪状态,或者在启动或终止另一个 Pod 之前终止。

StatefulSet 使用 Pod 模板,其中包含其 Pod 的规范。Pod 规范确定每个 Pod 的外观:应在 Pod 容器内运行的应用、应装载的卷、Pod 标签和选择器等。

使用模式

StatefulSet 设计用于部署有状态应用和集群应用,以将数据保存到永久性存储空间(例如 Google Compute Engine 永久性磁盘)。StatefulSet 适合部署 Kafka、MySQL、Redis、ZooKeeper 以及其他需要唯一持久身份和稳定主机名的应用。对于无状态应用,请使用 Deployment

创建 StatefulSet

您可以使用 kubectl apply 创建 StatefulSet

创建之后,StatefulSet 即会确保所需数量的 Pod 正在运行并且始终可用。StatefulSet 会自动替换失败或从其节点中逐出的 Pod,并自动将新 Pod 与存储资源、资源请求和限制以及在 StatefulSet 的 Pod 规范中定义的其他配置相关联。

以下是 Service 和 StatefulSet 清单文件的示例:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # Label selector that determines which Pods belong to the StatefulSet
                 # Must match spec: template: metadata: labels
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx # Pod template's label selector
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

在此示例中:

  • 创建了一个名为 nginxService 对象,由 metadata: name 字段指示。该 Service 会定位一个名为 nginx 的应用,由 labels: app: nginxselector: app: nginx 指示。该 Service 会公开端口 80 并将其命名为 web。而且该 Service 会控制网域并将互联网流量路由到 StatefulSet 部署的容器化应用。
  • 使用三个副本 Pod (replicas: 3) 创建了一个名为 web 的 StatefulSet。
  • Pod 模板 (spec: template) 指示其 Pod 标记为 app: nginx
  • Pod 规范 (template: spec) 指示 StatefulSet 的 Pod 运行一个容器 nginx,该容器运行版本为 0.8nginx-slim 映像。容器映像由 Container Registry 托管。
  • Pod 规范使用由 Service 打开的 web 端口。
  • template: spec: volumeMounts 指定一个名为 wwwmountPathmountPath 是容器中应装载存储卷的路径。
  • StatefulSet 预配了一个具有 1 GB 预配存储空间的 PersistentVolumeClaimwww

总而言之,Pod 规范包含以下说明:

  • 将每个 Pod 标记为 app: nginx
  • 在每个 Pod 中,运行一个名为 nginx 的容器。
  • 运行版本为 0.8nginx-slim 映像。
  • 让 Pod 使用端口 80
  • 将数据保存到装载路径。

如需详细了解 StatefulSet 配置,请参阅 StatefulSet API 参考

更新 StatefulSet

您可以通过更改 StatefulSet Pod 规范(包括 StatefulSet 容器映像和卷)来更新 StatefulSet。您还可以更新对象的资源请求和限制、标签以及注释。要更新 StatefulSet,您可以使用 kubectl、Kubernetes API 或者 Google Cloud Platform Console 中的“GKE 工作负载”菜单

StatefulSet 会使用 spec: updateStrategy 中定义的更新策略来确定如何处理更新。有两种策略(OnDeleteRollingUpdate):

  • 更改对象的配置时,OnDelete 不会自动删除并重新创建 Pod。您必须手动删除旧 Pod,以使控制器创建更新的 Pod。
  • 更改对象的配置时,RollingUpdate 会自动删除并重新创建 Pod。新 Pod 必须处于运行并就绪状态,其前身才能被删除。使用此策略时,更改 Pod 规范会自动触发发布操作。这是 StatefulSet 的默认更新策略。

StatefulSet 以反向顺序更新 Pod。您可以运行以下命令来监控更新发布:

kubectl rollout status statefulset [STATEFULSET_NAME]

划分滚动更新

您可以划分滚动更新。如果要暂存更新、发布 canary 版或执行分阶段发布,则分区很有用。

如果划分更新,则当您更新 StatefulSet 的 Pod 规范时,系统会更新序号大于或等于分区值的所有 Pod。序号小于分区值的 Pod 不会更新,而且即使 Pod 被删除,也会使用规范的先前版本重新创建。如果分区值大于副本数量,则更新不会传播到 Pod。

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Kubernetes Engine 文档