基于阿里云组件指标的容器水平伸缩

本文介绍如何在Kubernetes提供外部指标(External Metrics)支持的情况下,通过配置如HTTP请求率、Ingress QPS等指标,在阿里云环境中实现应用的自动水平伸缩。

前提条件

已创建Kubernetes集群。具体操作,请参见创建Kubernetes托管版集群创建Kubernetes专有版集群创建集群

部署alibaba-cloud-metrics-adapter组件

  1. 登录容器服务管理控制台,在左侧导航栏选择集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择应用 > Helm

  3. Helm页面,单击创建。参考如下信息完成基础信息配置。

    参数

    示例值

    应用名

    ack-alibaba-cloud-metrics-adapter

    命名空间

    kube-system

    来源

    默认为应用市场

    Chart

    • 应用场景:选择全部

    • 支持架构:选择amd64

    • 搜索框:搜索ack-alibaba-cloud-metrics-adapter。

    选中ack-alibaba-cloud-metrics-adapter,单击下一步

  4. 参数配置页面,选择Chart 版本,然后单击确定

配置HPA自动伸缩示例

本文以创建名为Nginx的Deployment和Service为例配置HPA自动伸缩。

  1. 登录容器服务管理控制台,在左侧导航栏单击集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态

  3. 无状态页面中,单击使用YAML创建资源

  4. 设置示例模板自定义,并使用以下YAML文件创建一个应用,并暴露一个ClusterIP的Service,然后单击创建

    apiVersion: apps/v1 
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9 
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      namespace: default
    spec:
      ports:
        - port: 80
          protocol: TCP
          targetPort: 80
      selector:
        app: nginx
      type: ClusterIP
  5. 在集群管理页左侧导航栏中,选择网络 > 路由,并在路由页面右上方,单击创建Ingress

  6. 创建面板中填写相关信息,然后单击确定。完成创建后,系统会自动跳转至路由页面。

  7. 名称下,单击生成的Ingress名称,查看路由规则信息。

  8. 配置HPA。

    1. 单击左上角的返回符号,返回集群列表页面。

    2. 在控制台左侧导航栏,选择市场 > 编排模板

    3. 模板列表页面右上角单击创建
    4. 创建对话框中,配置编排模板,最后单击保存

      • 名称:设置该模板的名称,本文配置为HPA。

      • 描述:输入对该模板的描述,可不配置。

      • 模板:配置符合Kubernetes YAML语法规则的编排模板,参考以下文件。

      apiVersion: autoscaling/v2
      kind: HorizontalPodAutoscaler
      metadata:
        name: ingress-hpa
      spec:
        scaleTargetRef:
          apiVersion: apps/v1
          kind: Deployment
          name: nginx-deployment-basic
        minReplicas: 2
        maxReplicas: 10
        metrics:
          - type: External
            external:
              metric:
                name: sls_ingress_qps
                selector:
                  matchLabels:
                    sls.project: "***" # 替换sls.project的值为真实值。
                    sls.logstore: "nginx-ingress"
                    sls.ingress.route: "default-nginx-80"
              target:
                type: AverageValue
                averageValue: 10
          - type: External
            external:
              metric:
                name: sls_ingress_latency_p9999
                selector:
                  matchLabels:
                    # default ingress log project is k8s-log-clusterId
                    sls.project: "***" 
                    # default ingress logstre is nginx-ingress
                    sls.logstore: "nginx-ingress"
                    # namespace-svc-port
                    sls.ingress.route: "default-nginx-80"
                    # sls vpc endpoint, default true
                    # sls.internal.endpoint:true
              target:
                type: Value
                # sls_ingress_latency_p9999 > 10ms
                value: 10

      HPA的配置涉及的参数如下:

      参数名

      描述

      sls.ingress.route

      必填,参数的格式为:<namespace>-<svc>-<port>,例如default-nginx-80

      说明

      <namespace>为Ingress所在的命名空间,<svc>是Ingress对应的Service名称,<port>是Ingress对应Service的Port名称。

      sls.logstore

      日志服务的日志库名称,必填。集群中默认sls.logstore值为nginx-ingress

      sls.project

      日志服务的Project名称,必填。集群中默认sls.project值为k8s-log-集群ID.

      sls.internal.endpoint

      设置通过内网还是外网访问日志服务,默认为true。选择true说明通过内网访问日志服务;选择false说明通过外网访问日志服务。

      说明

      sls_ingress_qpssls_ingress_latency_p9999是本文实现伸缩使用的两个指标。在targettype中。

      • sls_ingress_qps设置的是AverageValue,表示QPS要除以Pod的数目进行判断。

      • sls_ingress_latency_p9999设置的是Value,表示无需除以Pod的数目。

      以上两种不同的type在HPA的设置中会经常用到。

    5. 模板列表页面,选择HPA并单击创建应用

    6. 模板列表 - HPA页面右侧,单击创建

  9. 设置好HPA后,执行以下脚本进行压测。

    #!/bin/bash
    ##使用Apache Benchmark对Ingress暴露的服务设置并发为10,时间为300秒的压测。
    ab -t 300 -c 10 <ingress配置的域名>
  10. 验证指标伸缩状态。

    1. 在控制台左侧导航栏单击集群,并在集群列表页面,选择目标集群操作列的更多 > 通过CloudShell管理集群

    2. 执行以下命令检查伸缩状态。

      kubectl get hpa ingress-hpa

      预期输出:

      NAME            REFERENCE                              TARGETS           MINPODS    MAXPODS    REPLICAPS   AGE
      ingress-hpa     Depolyment/nginx-deployment-basic      21/10 (avg)       2          10         10          7m49s

      REPLICAS的值和MAXPODS的值相同时,说明伸缩成功。

通过命令行查询数据

可以通过以下命令行查询数据。以请求指标sls_ingress_qps为例。

kubectl get --raw  /apis/external.metrics.k8s.io/v1beta1/namespaces/*/sls_ingress_qps?labelSelector=sls.project={{SLS_Project}},sls.logstore=nginx-ingress

其中 {{SLS_Project}}是此ACK集群对应的SLS日志中心的Project名。若未自定义配置,默认为k8s-log-{{ClusterId}},{{ClusterId}}为此集群的ClusterId。

若返回结果为:

Error from server: {
    "httpCode": 400,
    "errorCode": "ParameterInvalid",
    "errorMessage": "key (slb_pool_name) is not config as key value config,if symbol : is  in your log,please wrap : with quotation mark \"",
    "requestID": "xxxxxxx"
}

表明此指标无数据。原因可能是未配置使用ALB Ingress,但使用了sls_alb_ingress_qps指标进行数据查询。

常见问题

  • 问:如果执行kubectl get hpa后发现target一栏为<unknow>怎么办?

    答:请按照以下操作解决。

    1. 执行kubectl describe hpa <hpa_name>,确认HPA失效的原因。

      • 如果Conditions字段提示AbleToScaleFalse,请确认Deployment是否正常部署。

      • 如果Conditions字段提示ScalingActiveFalse,请继续下一步。

    2. 执行kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/"。如果返回为Error from server (NotFound): the server could not find the requested resource,请确认alibaba-cloud-metrics-adapter的启动状态。

      如果确认alibaba-cloud-metrics-adapter状态正常,请确认HPA指标是否是Ingress相关指标。如果是Ingress相关指标,您需要提前部署日志服务组件。更多信息,请参见Nginx Ingress访问日志分析与监控

    3. 确认HPA指标填写正确。sls.ingress.route的值格式为<namespace>-<svc>-<port>

      • namespace为Ingress所在的命名空间。

      • svc是Ingress对应的Service名称。

      • port是Ingress对应Service的端口名称。

  • 问:如何查找HPA支持的指标名称?

    答:请参见阿里云HPA指标, 以下列举为常用指标。

    指标名称

    描述

    附加参数

    sls_ingress_qps

    指定的IngressRoute每秒查询率

    sls.ingress.route

    sls_alb_ingress_qps

    ALB数据的IngressRoute每秒查询率

    sls.ingress.route

    sls_ingress_latency_avg

    所有请求的延迟

    sls.ingress.route

    sls_ingress_latency_p50

    50%请求的延迟

    sls.ingress.route

    sls_ingress_latency_p95

    95%请求的延迟

    sls.ingress.route

    sls_ingress_latency_p99

    99%请求的延迟

    sls.ingress.route

    sls_ingress_latency_p9999

    99.99%请求的延迟

    sls.ingress.route

    sls_ingress_inflow

    Ingress的流入带宽

    sls.ingress.route

  • 问:当用户自定义了Nginx Ingress日志格式,如何进行适配操作?

    答:本文介绍的使用SLS Ingress指标进行容器水平伸缩,需要您开启并正确配置集群中Nginx Ingress日志接入阿里云日志服务。

    • 在创建集群时,日志服务是默认开启的。当您保持默认值不变,集群创建成功后,您可以在阿里云日志服务SLS控制台查看Nginx Ingress的访问日志分析报表和监控Nginx Ingress实时状态。

    • 在创建集群时,若您手动关闭了日志服务,集群创建完成后,如果想要使用SLS Ingress指标进行容器水平伸缩,您需要重新开启或配置日志服务。详细信息,请参见Nginx Ingress访问日志分析与监控

    • 当您需要自定义Nginx Ingress日志格式时,由于集群中初次开启日志服务部署AliyunLogConfig的CRD只针对ACK默认Ingress Controller中的日志格式生效,若您修改过Ingress Controller的访问日志格式,请修改CRD配置中的正则表达式提取processor_regex部分。具体操作,请参见通过DaemonSet-CRD方式采集容器日志

相关文档