本页面介绍 Kubernetes 的 StatefulSet 对象及其在 Google Kubernetes Engine (GKE) 中的用法。您还可以了解如何部署有状态应用。
概览
StatefulSet 表示一组具有唯一持久身份和稳定主机名的 Pod。无论这些 Pod 调度到何处,GKE 都会对其进行维护。任何指定 StatefulSet Pod 的状态信息和其他弹性数据都存放在与该 StatefulSet 关联的永久性磁盘存储空间中。
StatefulSet 针对 Pod 的身份和排序使用序数索引。
默认情况下,StatefulSet Pod 按顺序部署,并按反向顺序终止。例如,名为 web
的 StatefulSet 有三个 Pod,分别名为 web-0
、web-1
、web-2
。在 web
Pod 规范被更改后,系统会按顺序正常停止并重新创建其 Pod。在此示例中,系统会先终止 web-2
,然后终止 web-1
,依此类推。或者,您也可以指定 podManagementPolicy: Parallel
字段,让 StatefulSet 并行启动或终止其所有 Pod,而不是等待 Pod 变为运行并就绪状态,或者在启动或终止另一个 Pod 之前终止。
StatefulSet 使用 Pod 模板,此模板包含适用于其 Pod 的规范。Pod 规范确定每个 Pod 的外观:应在 Pod 容器内运行的应用、应装载的卷、Pod 标签和选择器等。
使用模式
StatefulSet 旨在用于部署有状态应用和集群化应用,这些应用会将数据保存到永久性存储空间(例如 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: k8s.gcr.io/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
在此示例中:
- 创建了一个名为
nginx
的 Service 对象,由metadata: name
字段指示。该 Service 会定位一个名为nginx
的应用,由labels: app: nginx
和selector: 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.8
的nginx-slim
映像。容器映像由 Container Registry 托管。 - Pod 规范使用由 Service 打开的
web
端口。 template: spec: volumeMounts
指定一个名为www
的mountPath
。mountPath
是容器中应装载存储卷的路径。- StatefulSet 预配了一个具有 1 GB 预配存储空间的 PersistentVolumeClaim:
www
。
总而言之,Pod 规范包含以下说明:
- 将每个 Pod 标记为
app: nginx
。 - 在每个 Pod 中,运行一个名为
nginx
的容器。 - 运行
0.8
版的nginx-slim
映像。 - 让 Pod 使用端口
80
。 - 将数据保存到装载路径。
如需详细了解 StatefulSet 配置,请参阅 StatefulSet API 参考。
更新 StatefulSet
您可以通过更改 StatefulSet Pod 规范(包括 StatefulSet 容器映像和卷)来更新 StatefulSet。您还可以更新对象的资源请求和限制、标签以及注释。如需更新 StatefulSet,您可以使用 kubectl
、Kubernetes API 或 Google Cloud Console 中的“GKE 工作负载”菜单。
StatefulSet 使用 spec: updateStrategy
中定义的更新策略来确定更新的处理方式。策略分为 OnDelete
和 RollingUpdate
这两种:
- 如果更改对象的配置,
OnDelete
不会自动删除并重新创建 Pod。您必须手动删除旧 Pod,以使控制器创建更新的 Pod。 - 如果更改对象的配置,
RollingUpdate
会自动删除并重新创建 Pod。新 Pod 必须处于运行并就绪状态,其前身才能被删除。使用此策略时,更改 Pod 规范会自动触发发布操作。这是 StatefulSet 的默认更新策略。
StatefulSet 以反向顺序更新 Pod。您可以运行以下命令来监控更新发布:
kubectl rollout status statefulset statefulset-name
划分滚动更新
您可以划分滚动更新。如果要暂存更新、发布 canary 版或执行分阶段发布,则分区很有用。
如果划分更新,则当您更新 StatefulSet 的 Pod 规范时,系统会更新序号大于或等于分区值的所有 Pod。序号小于分区值的 Pod 不会更新,而且即使 Pod 被删除,也会使用规范的先前版本重新创建。如果分区值大于副本数量,则更新不会传播到 Pod。
后续步骤
- 了解如何部署有状态应用。
- 详细了解如何在 GKE 中部署工作负载。
- 在 Kubernetes 文档中详细了解 StatefulSet。
- 了解 StatefulSet 基础知识。
- 学习有关如何升级运行有状态工作负载的集群的教程。