部署有状态应用

本页面介绍如何使用 Google Kubernetes Engine (GKE) 部署有状态应用。

概览

有状态应用将数据保存到永久性磁盘存储空间,以供服务器、客户端和其他应用使用。供其他应用在其中保存并检索数据的数据库或键值对存储区就是一种有状态应用的示例。

永久性存储空间可动态预配,因此可按需创建底层卷。在 Kubernetes 中,通过创建 StorageClass 来配置动态预配。在 GKE 中,默认 StorageClass 允许您动态预配 Compute Engine 永久性磁盘。

Kubernetes 使用 StatefulSet 控制器将有状态应用部署为 StatefulSet 对象。StatefulSet 中的 Pod 不可互换:每个 Pod 具有唯一的标识符,无论将 Pod 安排在何处,这个标识符都保持不变。

有状态应用与无状态应用不同,在切换会话时,无状态应用不会将客户端数据保存到服务器。

您可以进一步了解多地区集群和区域级集群中的永久性存储

准备工作

在开始之前,请确保您已执行以下任务:

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

您可以遵循快速入门中的说明启用 GKE API,创建集群,并进一步了解 GKE。

在 StatefulSet 中请求永久性存储空间

应用可以通过 PersistentVolumeClaim 请求永久性存储空间。

通常,除了创建 Pod 之外,您还必须创建 PersistentVolumeClaim 对象。不过,StatefulSet 对象包含一个 volumeClaimTemplates 数组,可自动生成 PersistentVolumeClaim 对象。每个 StatefulSet 副本都有自己的 PersistentVolumeClaim 对象。

您还可以在 StatefulSet 中使用预先存在的磁盘

创建 StatefulSet

如需创建 StatefulSet,请使用 kubectl apply 命令。

kubectl apply 命令使用清单文件来创建、更新和删除集群中的资源。这是对象配置的声明式方法。该方法可保留对活跃对象的写入,但不会将更改合并回到对象配置文件中。

Linux

以下清单文件是由单独创建的 Service 所控制的 StatefulSet 的简单示例:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      app: APP_NAME
  serviceName: "SERVICE_NAME"
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: APP_NAME
    spec:
      containers:
      - name: CONTAINER_NAME
        image: ...
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: ...
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
      annotations:
        ...
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

请替换以下内容:

  • STATEFULSET_NAME:StatefulSet 的名称。
  • SERVICE_NAME:Service 的名称。
  • APP_NAME:在 Pod 中运行的应用的名称。
  • CONTAINER_NAME:Pod 中容器的名称。
  • PORT_NAME:StatefulSet 打开的端口名称。
  • PVC_NAME:PersistentVolumeClaim 的名称。

在该文件中,kind 字段指定 StatefulSet 对象应该使用文件中定义的规范来创建。该示例 StatefulSet 生成三个副本 Pod,并打开端口 80 以向互联网公开 StatefulSet。

Windows

如果将集群用于 Windows Server 节点池,您必须创建一个 StorageClass,因为默认 StorageClass 使用仅适用于 Linux 容器的 ext4 作为文件系统类型。如果您使用的是 Compute Engine 永久性磁盘,则必须使用 NTFS 作为文件存储类型,如以下示例所示:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: STORAGECLASS_NAME
parameters:
  type: pd-standard
  fstype: NTFS
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

以下 StatefulSet 清单使用之前定义的 StorageClass。它会创建四个 PersistentVolume 和 PersistentVolumeClaim 对,以表示四个 Compute Engine 永久性磁盘。StatefulSet 中的每个 Pod 各使用一个永久性磁盘。

要确保将 Pod 正确调度到 Windows Server 节点上,您必须在 Pod 规范中添加节点选择器。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  replicas: 4
  selector:
    matchLabels:
      app: APP_NAME
  template:
    metadata:
      labels:
        app: APP_NAME
      name: CONTAINER_NAME
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: CONTAINER_NAME
        image: ...
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: C:\mnt\state
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
    spec:
      storageClassName: STORAGECLASS_NAME
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

请替换以下内容:

  • APP_NAME:在 Pod 中运行的应用的名称。
  • STATEFULSET_NAME:StatefulSet 的名称。
  • CONTAINER_NAME:Pod 中容器的名称。
  • PORT_NAME:StatefulSet 打开的端口名称。
  • PVC_NAME:PersistentVolumeClaim 的名称。
  • STORAGECLASS_NAME:StorageClass 的名称。

如需创建 StatefulSet 资源,请运行以下命令,并将 STATEFULSET_FILE 替换为清单文件的名称:

kubectl apply -f STATEFULSET_FILE

您还可以使用 kubectl apply -f DIRECTORY/ 创建目录中所存储的配置文件中定义的所有对象(现有对象除外)。

检查 StatefulSet

kubectl

如需检查 StatefulSet,请运行以下命令:

kubectl get statefulset STATEFULSET_NAME -o yaml

此命令以 YAML 格式显示 StatefulSet 资源的当前配置。

如需列出由 StatefulSet 创建的 Pod,请运行以下命令:

kubectl get pods -l app=APP_NAME

在此命令中,-l 标志指示 kubectl 获取标有 APP_NAME 的所有 Pod。

输出内容类似如下:

NAME                                READY     STATUS    RESTARTS   AGE
pod-name                            1/1       Running   0          1m
pod-name                            1/1       Running   0          1m

如需获取有关 StatefulSet 的详细信息,请运行以下命令:

kubectl describe statefulset STATEFULSET_NAME

如需获取有关特定 Pod 的信息,请运行以下命令:

kubectl describe pod POD_NAME

如需列出已创建的 PersistentVolumeClaim 对象,请运行以下命令:

kubectl get pvc

输出内容类似如下:

NAME                            STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
STATEFULSET_NAME-PVC_NAME-0     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800002   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-1     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800003   1G         RWO            standard        9s
STATEFULSET_NAME-PVC_NAME-2     Bound     pvc-bdff4e1e-183e-11e8-bf6d-42010a800004   1G         RWO            standard        9s

如需获取有关特定 PersistentVolumeClaim 的信息,请运行以下命令:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

如需获取有关特定 PersistentVolume 的信息,请运行以下命令:

kubectl describe pv PV_NAME

控制台

要检查 StatefulSet,请执行以下步骤:

  1. 转到 Cloud Console 中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要检查的 StatefulSet 的名称。

  3. StatefulSet 详情页面上,执行以下任一操作:

    • 点击修订历史记录标签页以查看 StatefulSet 的修订历史记录。
    • 点击事件标签页,以查看与 StatefulSet 相关的所有事件。
    • 点击日志标签页以查看 StatefulSet 的容器日志。
    • 点击 YAML 标签页以查看、复制或下载 StatefulSet 的配置 YAML。

更新 StatefulSet

您可以通过多种方式更新 StatefulSet。常用的声明式方法是 kubectl apply。您可以使用 kubectl edit 直接从 shell 或您的首选编辑器更新 StatefulSet。您还可以访问 Cloud Console 的 GKE“工作负载”菜单,使用其中提供的 YAML 编辑器。

您可以发布对 StatefulSet 资源的 Pod 规范的更新,例如其映像、资源使用情况/请求或配置。

kubectl 适用

您可以通过应用新的或更新的清单文件来更新 StatefulSet。 如果您要对 StatefulSet 进行各种更改,例如扩缩或者指定应用的新版本,则这种操作十分有用。

如需更新 StatefulSet,请运行以下命令:

kubectl apply -f STATEFULSET_FILE

STATEFULSET_FILE 替换为更新后的清单文件。

kubectl apply 命令可将清单文件应用于资源。如果指定的资源不存在,则命令将创建该资源。

如需详细了解 kubectl apply,请参阅 kubectl 参考文档

控制台

要修改 StatefulSet 的活动配置,请执行以下步骤:

  1. 转到 Cloud Console 中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要修改的 StatefulSet 的名称。

  3. 点击 修改

  4. 根据需要更改配置 YAML。

  5. 点击保存

检查更新发布

kubectl

如需检查 StatefulSet 的发布,请运行以下命令:

kubectl rollout status statefulset STATEFULSET_NAME

如需查看 StatefulSet 的发布历史记录,请运行以下命令:

kubectl rollout history statefulset STATEFULSET_NAME

如需撤消发布,请运行以下命令:

kubectl rollout undo statefulset STATEFULSET_NAME

控制台

要查看 StatefulSet 的修订历史记录,请执行以下步骤:

  1. 转到 Cloud Console 中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要检查的 StatefulSet 的名称。

  3. 点击修订历史记录标签页。

  4. 选择所需的修订版本。

更新策略

通过 StatefulSet 的 updateStrategy 字段,您可以为 StatefulSet 中 Pod 的容器、标签、资源请求、限制以及注解配置及停用自动滚动更新。

您可以在 Kubernetes 文档中详细了解 StatefulSet 的更新策略

扩缩 StatefulSet

kubectl

您可以随时使用 kubectl scale 命令来扩缩 StatefulSet。

要手动扩缩 StatefulSet,请运行以下命令:

kubectl scale statefulset STATEFULSET_NAME --replicas NUMBER_OF_REPLICAS

NUMBER_OF_REPLICAS 替换为所需的副本 Pod 数。

控制台

要扩缩 StatefulSet,请执行以下步骤:

  1. 转到 Cloud Console 中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要修改的 StatefulSet 的名称。

  3. 点击 扩缩

  4. 输入 StatefulSet 的新副本数量。

  5. 点击调节

删除 StatefulSet

kubectl

如需删除 StatefulSet,请运行以下命令:

kubectl delete statefulset STATEFULSET_NAME

控制台

要删除 StatefulSet,请执行以下步骤:

  1. 转到 Cloud Console 中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,选择一个或多个要删除的 StatefulSet。

  3. 点击 删除

  4. 当系统提示您确认时,点击删除

后续步骤