本文介绍如何实现阿里云指标自动伸缩,帮助您完成集群内应用的扩缩容。

前提条件

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

背景信息

很多场景下,往往需要更多的监测指标来指导集群的扩缩容,如HTTP请求率、Ingress QPS等,但是默认HPA并不支持这些自定义的指标或外部指标,但是Kubernetes提供了External Metrics的机制,为应用提供更加便捷的扩缩机制。

部署alibaba-cloud-metrics-adapter组件

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,选择市场 > 应用目录
  3. 应用目录页面阿里云应用页签下单击弹性伸缩,单击ack-alibaba-cloud-metrics-adapter
  4. 创建区域选择目标集群,单击创建
  5. 查看已创建的ack-alibaba-cloud-metrics-adapter组件信息。
    1. 在控制台左侧导航栏中,单击集群
    2. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    3. 在集群管理页左侧导航栏中,选择工作负载 > 有状态
    4. 在集群管理页左侧导航栏中,选择应用 > Helm
      Helm页面可看到ack-alibaba-cloud-metrics-adapter组件已经成功部署到集群中。

配置HPA自动伸缩示例

本文以创建名为Nginx的Deployment和Service为例配置HPA自动伸缩。
  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
  5. 无状态页面中,单击使用YAML创建资源
  6. 设置示例模板自定义,并使用以下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
  7. 在集群管理页左侧导航栏中,选择网络 > 路由,并在路由页面右上方,单击创建
  8. 创建面板中填写相关信息,然后单击创建。完成创建后,系统自动跳转至路由页面。
  9. 在生成的Ingress地址右侧,单击详情查看路由信息。
  10. 配置HPA。
    1. 单击左上角的返回符号,返回集群列表页面。
    2. 在控制台左侧导航栏选择市场 > 编排模板
    3. 模板列表页面,选择hpa并单击创建应用,然后部署以下文件。
      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:ture
              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.project 日志服务的Project名称,必填。
      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的设置中会经常用到。
    4. 模板列表 - hpa页面右侧,单击创建
  11. 设置好HPA后,执行以下脚本进行压测。
    #!/bin/bash
    ##使用Apache Benchmark对Ingress暴露的服务设置并发为10,时间为300秒的压测。
    ab -t 300 -c 10 <ingress配置的域名>
  12. 验证指标伸缩状态。
    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的值相同时,说明伸缩成功。

常见问题

  • 问:如果执行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相关指标,您需要提前部署日志服务组件。更多信息,请参见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_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