扩缩 Kubernetes 部署

借助 Kubernetes 环境,您可以根据工作负载需求的变化动态扩缩数据库资源。如果您是使用 Helm 图表部署的 Spanner Omni,请使用以下伸缩程序。

准备工作

在扩缩 Kubernetes 部署之前,您必须执行以下操作:

最佳做法是,在添加更多服务器以进行横向伸缩之前,先将每个服务器的内存纵向扩缩到至少 32 GB。

限制

在 Kubernetes 中进行扩缩存在以下限制:

  • 仅限非 root 服务器:横向伸缩仅适用于非 root 实例。不支持 root 服务器伸缩。

  • StatefulSet 存储空间限制:由于 Kubernetes volumeClaimTemplates 是不可变的,因此您无法使用 单个 helm upgrade 命令来扩充 pod 磁盘。相反,伸缩存储空间需要手动执行卷扩充步骤。

纵向扩缩

如需调整服务器的 CPU 或内存资源,请使用 Helm 升级来更新配置:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set resources.cpu=CPU_CORES \
  --set resources.memory=MEMORY_LIMIT \
  -n NAMESPACE

替换以下内容:

  • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni
  • VERSION:Helm 图表的版本,例如 0.2.0
  • CPU_CORES:要分配给每个服务器 pod 的 vCPU 核心数,例如 8
  • MEMORY_LIMIT:每个服务器 pod 的 RAM 上限,例如 32Gi
  • NAMESPACE:部署的 Kubernetes 命名空间,例如 spanner-ns

横向扩缩

如需进行横向扩缩,请向部署添加更多服务器。横向伸缩仅适用于非 root 服务器。

添加非 root 服务器

如需添加非 root 服务器,请增加 Helm 图表配置中的副本数。您可以统一扩缩所有可用区,也可以扩缩特定可用区。

统一扩缩

如需将部署中的每个可用区扩缩到 15 台服务器,请运行以下命令:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set deployment.replicasPerZone=REPLICAS \
  -n NAMESPACE

替换以下内容:

  • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni
  • VERSION:Helm 图表的版本,例如 0.2.0
  • REPLICAS:每个可用区的目标服务器副本数,例如 15
  • NAMESPACE:Kubernetes 命名空间,例如 spanner-ns

扩缩特定可用区

如果您的初始部署为各个可用区配置了不同的服务器数量,则可以指定单个可用区。例如,如需将第一个位置内第一个可用区的副本数增加到 15,请运行以下命令:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set locations[0].zones[0].replicas=REPLICAS \
  -n NAMESPACE

REPLICAS 替换为目标可用区副本数,例如 15

如需验证新服务器是否已成功加入部署,请查询 Spanner Omni CLI 以列出部署服务器,或查看您的 Grafana 信息中心

spanner deployment servers list \
  --zone=ZONE \
  --deployment-endpoint=ENDPOINT

替换以下内容:

  • ZONE:您要列出的可用区,例如 us-central1-a
  • ENDPOINT:部署的外部端点,例如 ${ENDPOINT}:15000

移除非 root 服务器

缩减服务器需要执行额外的步骤,因为系统必须安全地将数据分区从已停用的服务器中移出。由于 Kubernetes StatefulSet 会按从最高到最低的索引顺序移除 pod,因此您必须先移除索引最高的非 root 服务器。

如需缩容服务器数量,请执行以下步骤:

  1. 列出可用区中的服务器,以确定要移除的候选服务器:

    spanner deployment servers list \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    输出示例:

    NAME                                                          HOST                        PORT_BASE  ROOT  STATE
    zones/us-central1-a/servers/spanner-a-0.pod.spanner-ns:15000  spanner-a-0.pod.spanner-ns  15000      true  -
    zones/us-central1-a/servers/spanner-a-1.pod.spanner-ns:15000  spanner-a-1.pod.spanner-ns  15000      -     -
    

    删除索引最高的已停用非 root 服务器(例如 spanner-a-1.pod.spanner-ns:15000):

    spanner deployment servers delete SERVER_NAME \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    SERVER_NAME 替换为服务器标识符,例如 spanner-a-1.pod.spanner-ns:15000

    检查服务器列表,直到目标服务器从列表中移除。 删除后,服务器在系统中会转换为不健康状态,并从活跃服务路径中移除。

  2. 运行 Helm 升级命令,以缩容 Helm 部署,使其与目标副本数相符。例如,如需将每个可用区的副本数减少到 1 个 pod,请运行以下命令:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set deployment.replicasPerZone=REPLICAS \
      -n NAMESPACE
    

    REPLICAS 替换为更新后的副本数,例如 1

  3. 删除与已移除的 pod 关联的 Kubernetes 永久性卷声明 (PVC)。为了防止意外丢失数据,在缩减 StatefulSet 时,Helm 和 Kubernetes 不会自动删除 PVC。手动删除 PVC 以完全回收存储空间:

    kubectl delete pvc LOGS_PVC DATA_PVC -n NAMESPACE
    

    例如,如需删除命名空间 spanner-nsspanner-a-1 的日志和数据卷:

    kubectl delete pvc logs-volume-spanner-a-1 data-volume-spanner-a-1 -n spanner-ns
    

添加可用区

向部署添加新可用区可以提高可用性,并保护数据库免受单可用区中断的影响。

例如,以下命令会在 us 区域的 us-east1-b 可用区中初始化在 Google Kubernetes Engine (GKE) 上运行的单可用区 部署:

helm upgrade --install spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --set resources.cpu=2 \
  --set resources.memory=8Gi \
  --set global.platform=gke \
  --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
  -n NAMESPACE

如需将可用区 us-east1-c 添加到此配置,请执行以下步骤:

  1. 运行 helm upgrade 命令并在其中传递包含新位置可用区的更新后的 JSON 代码块,以在新可用区中启动 pod:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"},{"name":"us-east1-c","shortName":"east-c"}]}]' \
      -n NAMESPACE
    
  2. 使用 Spanner Omni CLI 添加新可用区。等待新创建的可用区中的 root 服务器 pod 进入 Running 和就绪状态。然后,执行可用区创建命令:

    spanner deployment zones create NEW_ZONE \
      --location=LOCATION \
      --root-servers=ROOT_SERVERS_LIST \
      --deployment-endpoint=ENDPOINT
    

    替换以下内容:

    • NEW_ZONE:要添加的可用区的标识符,例如 us-east1-c
    • LOCATION:部署位置,例如 us
    • ROOT_SERVERS_LIST:新可用区中 root 服务器端点的英文逗号分隔列表,例如 spanner-east-c-0.pod.spanner-ns:15000,spanner-east-c-1.pod.spanner-ns:15000,spanner-east-c-2.pod.spanner-ns:15000
    • ENDPOINT:外部部署端点,例如 ${ENDPOINT}:15000
  3. 等待可用区创建完成。将现有数据库架构和表复制到新可用区需要一些时间。通过列出部署可用区来监控可用区同步的进度:

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    

移除可用区

您可以从多可用区部署中停用活跃可用区,以减少资源或适应拓扑更改。

如需移除上一部分中创建的可用区 us-east1-c,请执行以下步骤:

  1. 删除可用区并在 Spanner Omni 中启动可用区拆除:

    spanner deployment zones delete ZONE --deployment-endpoint=ENDPOINT
    

    ZONE 替换为要移除的可用区,例如 us-east1-c

  2. 验证可用区是否已移除。运行列表命令,并等待直到该可用区不再显示在输出中:

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    
  3. 运行 Helm 升级命令并在其中传递更新后的位置 JSON 代码块(不包含已移除的可用区),以从 Kubernetes 集群中移除服务器:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
      -n NAMESPACE
    

扩缩存储空间

由于 Kubernetes volumeClaimTemplates 是不可变的,因此您无法直接使用 helm upgrade 命令来扩容 pod 存储容量。相反,您必须执行手动卷扩充。如需了解详情,请参阅 GKE StatefulSet 卷扩充指南

如需扩充磁盘存储空间,请执行以下步骤:

  1. 在终端中将卷扩充的参数定义为环境变量:

    NEW_SIZE="NEW_SIZE"
    NAMESPACE="NAMESPACE"
    RELEASE_NAME="spanner-omni"
    STATEFULSET_NAMES="STATEFULSET_NAME_1 STATEFULSET_NAME_2 STATEFULSET_NAME_3"
    HELM_CHART_PATH="HELM_CHART_PATH"
    VERSION="VERSION"
    

    替换以下内容:

    • NEW_SIZE:目标存储容量大小,例如 200Gi
    • NAMESPACE:Kubernetes 命名空间,例如 spanner-ns
    • STATEFULSET_NAME_1STATEFULSET_NAME_2 等:部署中 StatefulSets 的名称,通常与可用区的简称相对应(例如 spanner-east-b spanner-east-c)。
    • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni
    • VERSION:Helm 图表的版本,例如 0.2.0
  2. 运行命令以修补 PVC、删除 StatefulSet(保持后端 pod 完好无损)并升级 Helm 部署:

    # Patch all associated PVCs directly.
    for pvc in $(kubectl get pvc -n $NAMESPACE \
      -l app.kubernetes.io/instance=$RELEASE_NAME \
      -o name | grep "data-volume"); do
      kubectl patch $pvc -n $NAMESPACE -p "{\"spec\":{\"resources\":{\"requests\":{\"storage\":\"$NEW_SIZE\"}}}}"
    done
    
    # Delete the StatefulSet while leaving backend pods intact (orphan cascade).
    kubectl delete statefulset $STATEFULSET_NAMES -n $NAMESPACE --cascade=orphan
    
    # Run Helm upgrade to align the templates with the expanded size.
    helm upgrade $RELEASE_NAME $HELM_CHART_PATH \
      --version $VERSION \
      --reuse-values \
      --set storage.data.size=$NEW_SIZE \
      -n $NAMESPACE
    

后续步骤