学习路线:可伸缩应用 - 扩缩


本系列教程适用于想要部署、运行和管理在 Google Kubernetes Engine (GKE) Enterprise 版本上运行的现代应用环境的 IT 管理员和运维人员。在学习本系列教程的过程中,您将学习如何使用 Cymbal Bank 示例微服务应用配置监控和提醒、扩缩工作负载以及模拟故障。

  1. 创建集群并部署示例应用
  2. 使用 Google Cloud Managed Service for Prometheus 进行监控
  3. 扩缩工作负载(本教程)
  4. 模拟故障

概览和目标

Cymbal Bank 等消费者应用在不同时间通常具有不同数量的用户。理想情况下,您的网站能够应对流量激增,而不会减慢运行速度或出现其他问题,但组织不必为实际上并不需要的 Cloud 资源付费。Google Cloud 为此提供的解决方案是自动扩缩。

在本教程中,您将学习如何在 GKE 集群中配置集群和工作负载,以使用内置 Kubernetes 指标以及 Cloud Monitoring 和 Cloud Trace 中的自定义指标进行扩缩。您将了解如何完成以下任务:

  • 在 Cloud Monitoring for Trace 中启用自定义指标。
    • 借助自定义指标,您可以使用 Kubernetes 集群感知之外的其他监控数据或外部输入(例如网络流量或 HTTP 响应代码)进行扩缩。
  • 配置 Pod 横向自动扩缩器,这是一项 GKE 功能,可根据指定的指标自动增加或减少工作负载的 Pod 数量。
  • 模拟应用负载并查看集群自动扩缩器和 Pod 横向自动扩缩器的响应。

费用

您将为本系列教程启用 GKE Enterprise 并部署 Cymbal Bank 示例应用,这意味着您需要按照我们价格页面中列出的价格,按集群为 GKE Enterprise on Google Cloud 付费,直到您停用 GKE Enterprise 或删除项目。

您还需要负责运行 Cymbal Bank 示例应用时产生的其他 Google Cloud 费用,例如 Compute Engine 虚拟机和 Trace 的费用。

准备工作

如需了解如何扩缩部署,您必须完成第一个教程,创建一个使用 Autopilot 的 GKE 集群并部署 Cymbal Bank 基于微服务的示例应用。

我们建议您按顺序针对 Cymbal Bank 完成本系列教程。在完成本系列教程的过程中,您将学习新技能并使用其他 Google Cloud 产品和服务。

您还需要创建一个 IAM 服务账号并授予一些权限,以便 Pod 横向自动扩缩器正常运行:

  1. 创建 IAM 服务账号。 本教程使用此服务账号授予对自定义指标的访问权限,这些自定义指标可让 Pod 横向自动扩缩器确定何时扩容或缩容:

    gcloud iam service-accounts create scalable-apps
    
  2. 向 IAM 服务账号授予执行所需的扩缩操作的权限:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/cloudtrace.agent \
      --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com"
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/monitoring.metricWriter \
      --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com"
    
    gcloud iam service-accounts add-iam-policy-binding "scalable-apps@PROJECT_ID.iam.gserviceaccount.com" \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[default/default]"
    

    向 IAM 服务账号授予以下访问权限:

    • roles/cloudtrace.agent:将跟踪记录数据(例如延迟时间信息)写入 Trace。
    • roles/monitoring.metricWriter:将指标写入 Cloud Monitoring。
    • roles/iam.workloadIdentityUser:允许 Kubernetes 服务账号使用 Workload Identity 充当 IAM 服务账号。
  3. default 命名空间中配置 default Kubernetes 服务账号,以充当您创建的 IAM 服务账号:

    kubectl annotate serviceaccount default \
        iam.gke.io/gcp-service-account=scalable-apps@PROJECT_ID.iam.gserviceaccount.com
    

    此配置允许 default 命名空间中使用 default Kubernetes 服务账号的 Pod 访问与 IAM 服务账号相同的 Google Cloud 资源。

设置自定义指标收集

您可以将 Pod 横向自动扩缩器配置为使用基本的内置 Kubernetes CPU 和内存指标,也可以使用 Cloud Monitoring 中的自定义指标,例如每秒 HTTP 请求数或 SELECT 语句的数量。自定义指标无需更改应用即可运行,并且可让您的集群更深入地了解应用的整体性能和需求。在本教程中,您将学习如何同时使用内置指标和自定义指标。

  1. 要允许 Pod 横向自动扩缩器从 Monitoring 读取自定义指标,您必须在集群中安装自定义指标 - Stackdriver Adapter 适配器。

    将自定义指标 Stackdriver 适配器部署到您的集群:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
    
  2. 要允许 Stackdriver 适配器从集群中获取自定义指标,请使用 Workload Identity。此方法使用有权读取监控指标的 IAM 服务账号。

    向该 IAM 服务账号授予 roles/monitoring.viewer 角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/monitoring.viewer
    
  3. 将 Stackdriver 适配器配置为使用 Workload Identity 和有权读取监控指标的 IAM 服务账号:

    gcloud iam service-accounts add-iam-policy-binding scalable-apps@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[custom-metrics/custom-metrics-stackdriver-adapter]"
    
  4. Kubernetes 包含自己的系统,供服务账号在集群内进行访问。如需让您的应用向 Google Kubernetes Engine (GKE) Enterprise 版本集群之外的服务和资源(例如 Monitoring)进行身份验证,请使用 Workload Identity。此方法会将 Kubernetes 服务账号配置为使用 GKE 的 IAM 服务账号。

    为适配器使用的 Kubernetes 服务账号添加注释:

    kubectl annotate serviceaccount custom-metrics-stackdriver-adapter \
        --namespace=custom-metrics \
        iam.gke.io/gcp-service-account=scalable-apps@PROJECT_ID.iam.gserviceaccount.com
    
  5. 重启 Stackdriver 适配器 Deployment 以应用更改:

    kubectl rollout restart deployment custom-metrics-stackdriver-adapter \
        --namespace=custom-metrics
    

配置 Pod 横向自动扩缩器

GKE Autopilot 可以通过几种不同的方式进行扩缩。在本教程中,您将了解集群如何使用以下方法进行扩缩:

  • Pod 横向自动扩缩器:扩缩工作负载的 Pod 数量。
  • 集群自动扩缩器:扩缩集群中可用的节点资源。

这两种方法可以协同工作,因此随着应用的 Pod 数量发生变化,支持这些 Pod 的节点资源也会发生变化。

其他实现可用于扩缩在 Pod 横向自动扩缩器的基础上构建的 Pod,您还可以使用 Pod 纵向自动扩缩器来调整 Pod 的 CPU 和内存请求(而不是 Pod 的数量)。

在本教程中,您将使用内置指标为 userservice Deployment 配置 Pod 横向自动扩缩器,使用自定义指标为 frontend Deployment 配置 Pod 横向自动扩缩器。

对于您自己的应用,请与您的应用开发者和平台工程师合作,了解他们的需求并配置 Pod 横向自动扩缩器规则。

扩缩 userservice Deployment

当 Cymbal Bank 示例应用的用户数量增加时,userservice Service 会消耗更多 CPU 资源。您可以使用 HorizontalPodAutoscaler 对象来控制应用响应负载的方式。在 HorizontalPodAutoscaler 的 YAML 清单中,您可以定义 Pod 横向自动扩缩器要扩缩的 Deployment、要监控的指标以及要运行的副本数下限和上限。

  1. 查看 userservice Deployment 的 HorizontalPodAutoscaler 示例清单:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: userservice
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: userservice
      minReplicas: 5
      maxReplicas: 50
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 60
    

    此清单执行以下操作:

    • 将纵向扩容期间的副本数上限设置为 50
    • 将纵向缩容期间的副本数下限设置为 5
    • 使用内置的 Kubernetes 指标做出扩缩决策。在此示例中,指标为 CPU 利用率,目标利用率为 60%,这可以避免过度利用和利用不充分的情况。
  2. 将清单应用于集群:

    kubectl apply -f extras/postgres-hpa/hpa/userservice.yaml
    

扩缩 frontend Deployment

在上一部分中,您根据内置的 CPU 利用率 Kubernetes 指标在 userservice Deployment 上配置了 Pod 横向自动扩缩器。对于 frontend Deployment,您可能希望根据传入的 HTTP 请求数量进行扩缩。此方法使用 Stackdriver 适配器从 Monitoring 读取 HTTP(S) 负载均衡器 Ingress 对象的自定义指标。

  1. 查看 frontend Deployment 的 HorizontalPodAutoscaler 清单:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: frontend
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: frontend
      minReplicas: 5
      maxReplicas: 25
      metrics:
        - type: External
          external:
            metric:
              name: loadbalancing.googleapis.com|https|request_count
              selector:
                matchLabels:
                  resource.labels.forwarding_rule_name: FORWARDING_RULE_NAME
            target:
              type: AverageValue
              averageValue: "5"
    

    此清单使用以下字段:

    • spec.scaleTargetRef:要扩缩的 Kubernetes 资源。
    • spec.minReplicas:副本数下限,在本示例中为 5
    • spec.maxReplicas:副本数上限,在本示例中为 25
    • spec.metrics.*:要使用的指标。在本示例中,这是每秒的 HTTP 请求数,它是您部署的适配器提供的 Monitoring 中的自定义指标。
    • spec.metrics.external.metric.selector.matchLabels:扩缩时要过滤的特定资源标签。
  2. frontend Ingress 负载均衡器中查找转发规则的名称:

    export FW_RULE=$(kubectl get ingress frontend -o=jsonpath='{.metadata.annotations.ingress\.kubernetes\.io/forwarding-rule}')
    echo $FW_RULE
    

    输出类似于以下内容:

    k8s2-fr-j76hrtv4-default-frontend-wvvf7381
    
  3. 将您的转发规则添加到清单中:

    sed -i "s/FORWARDING_RULE_NAME/$FW_RULE/g" "extras/postgres-hpa/hpa/frontend.yaml"
    

    此命令将 FORWARDING_RULE_NAME 替换为已保存的转发规则。

  4. 将清单应用于集群:

    kubectl apply -f extras/postgres-hpa/hpa/frontend.yaml
    

模拟负载

在本部分中,您将使用负载生成器模拟流量高峰,并观察副本数和节点数如何纵向扩容以适应随时间增加的负载。然后,您可以停止生成流量,并观察副本数和节点数如何相应地纵向缩容。

  1. 在开始之前,请检查 Pod 横向自动扩缩器的状态并查看使用中的副本数。

    获取 HorizontalPodAutoscaler 资源的状态:

    kubectl get hpa
    

    输出类似于以下内容,显示有 1 个 frontend 副本和 5 个 userservice 副本:

    NAME                     REFERENCE                            TARGETS             MINPODS   MAXPODS   REPLICAS   AGE
    frontend                 Deployment/frontend                  <unknown>/5 (avg)   5         25        1          34s
    userservice              Deployment/userservice               0%/60%              5         50        5          4m56s
    
  2. Cymbal Bank 示例应用包含 loadgenerator Service。此 Service 会不断向前端发送模仿用户的请求,并定期创建新账号并模拟它们之间的交易。

    在本地公开 loadgenerator 网页界面。您可以使用此界面来模拟 Cymbal Bank 示例应用上的负载:

    kubectl port-forward svc/loadgenerator 8080
    

    如果您看到错误消息,请在 Pod 运行时重试。

  3. 在计算机上的浏览器中,打开负载生成器网页界面:

    • 如果您使用的是本地 shell,请打开浏览器并转到 http://127.0.0.1:8080。
    • 如果您使用的是 Cloud Shell,请点击 网页预览,然后点击在端口 8080 上预览
  4. 在负载生成器网页界面中,如果失败值显示 100%,请完成以下步骤以更新测试设置:

    1. 点击失败率计数器旁边的停止按钮。
    2. 状态下,点击新建测试选项。
    3. 主机值更新为 Cymbal Bank 入站流量的 IP 地址。
    4. 点击开始大量生成请求
  5. 在负载生成器网页界面中,点击图表标签页以观察一段时间内的性能。查看请求数和资源利用率。

  6. 打开一个新的终端窗口,并观察 frontenduserservice Pod 的副本计数:

    kubectl get hpa -w
    

    副本数量会随着负载的增加而增加。 由于集群识别出已配置的指标达到定义的阈值,并使用 Pod 横向自动扩缩器对 Pod 数量进行纵向扩容,因此纵向扩容操作可能需要大约 10 分钟时间。

    以下示例输出显示随着负载生成器的运行,副本数量已增加:

    NAME                     REFERENCE                            TARGETS          MINPODS   MAXPODS   REPLICAS
    frontend                 Deployment/frontend                  5200m/5 (avg)    5         25        13
    userservice              Deployment/userservice               71%/60%          5         50        17
    
  7. 打开另一个终端窗口,并检查集群中的节点数:

    gcloud container clusters list \
        --filter='name=scalable-apps' \
        --format='table(name, currentMasterVersion, currentNodeVersion, currentNodeCount)' \
        --region="REGION"
    

    REGION 替换为集群在其中运行的区域。

    节点数也从起始数量增加,以容纳新副本。节点数的增加由 GKE Autopilot 提供支持。您无需为此节点规模配置任何内容。

  8. 打开负载生成器界面,然后点击停止以结束测试。

  9. 再次检查副本数和节点数,并观察数量随着负载的减少而减少。纵向缩容可能需要一些时间,因为 Kubernetes HorizontalPodAutoscaler 资源中副本的默认稳定时长为 5 分钟。

在实际环境中,环境中的节点数和 Pod 数都会按照与此模拟负载相同的方式自动扩缩。Cymbal Bank 示例应用旨在适应此类扩缩。请与您的应用运营人员和站点可靠性工程 (SRE) 或应用开发者联系,了解他们的工作负载是否可以从这些扩缩功能中受益。

清理

Cymbal Bank 的这组教程需要逐个完成。在完成本系列教程的过程中,您将学习新技能并使用其他 Google Cloud 产品和服务。

如果您想在继续学习下一个教程之前休息一下,并避免系统因本教程中使用的资源向您的 Google Cloud 账号收取费用,请删除您创建的项目。

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤

在下一教程中了解如何模拟 GKE Enterprise 中的故障