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

默认HPA只支持基于CPU和内存的自动伸缩,并不能满足日常的运维需求。阿里云Prometheus监控全面对接开源Prometheus生态,支持类型丰富的组件监控,提供多种开箱即用的预置监控大盘,且提供全面托管的Prometheus服务。本文介绍如何将阿里云Prometheus指标转换成HPA可用的指标,从而为应用提供更加便捷的扩缩机制。

前提条件

已部署阿里云Prometheus监控组件。具体操作,请参见使用阿里云Prometheus监控ACS集群状态

操作步骤

部署ack-alibaba-cloud-metrics-adapter

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

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

  3. Helm页面,单击左上角的创建

  4. 创建面板中,Chart搜索选择ack-alibaba-cloud-metrics-adapter,然后单击下一步

  5. 在参数配置页面,选择版本号并设置相应参数,然后单击确定

    Helm页面可看到ack-alibaba-cloud-metrics-adapter组件已成功部署到集群中。

    image

  6. Helm页面,找到ack-alibaba-cloud-metrics-adapter,并单击右侧的更新

  7. 使用以下内容,替换模板中对应的参数,然后单击更新

      ......
      prometheus:
      	enabled: true
        # 填写阿里云Prometheus监控的地址。
        url: https://cn-beijing.arms.aliyuncs.com:9443/api/v1/prometheus/xxxx/xxxx/xxxx/cn-beijing
      	# 阿里云Prometheus开启鉴权Token后,请配置prometheusHeader Authorization。
        prometheusHeader:
        	Authorization: xxxxxxx
        adapter:
          rules:
            custom:
            # 添加新的转换规则,请确保阿里云Prometheus中指标标签和此处一致,如果不一致,请参见阿里云Prometheus中指标标签修改。
            - seriesQuery: http_requests_total{namespace!="",pod!=""}
              resources:
                overrides:
                  # 此处resource为Kubernetes的API Resource,可通过kubectl api-resources -o wide查看。
                  # 此处key对应Prometheus数据中的LabelName,请确认Prometheus指标数据中有此LabelName。
                  namespace: {resource: "namespace"}
                  pod: {resource: "pod"}
              name:
                matches: ^(.*)_total
                as: ${1}_per_second
              metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)
            default: false
        enabled: true    # 这里设置为true,打开Prometheus adapter。
        ......

    参数名

    说明

    AlibabaCloudMetricsAdapter.prometheus.url

    填写阿里云Prometheus监控的地址。

    关于如何获取Prometheus数据请求URL,请参见如何获取Prometheus数据请求URL

    AlibabaCloudMetricsAdapter.prometheus.prometheusHeader.Authorization

    填写Token。

    关于如何获取Token,请参见如何获取Prometheus数据请求URL

    AlibabaCloudMetricsAdapter.prometheus.adapter.rules.custom

    字段内容修改为下面示例YAML中对应的内容。

    AlibabaCloudMetricsAdapter.prometheus.adapter.rules.default

    默认创建预置指标,推荐关闭,配置为false

    说明

    关于ack-alibaba-cloud-adapter配置文件详细说明,请参见ack-alibaba-cloud-adapter配置文件详解

部署示例应用

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

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

  3. 无状态页面,单击右上角的使用YAML创建资源

  4. 创建页面,部署以下YAML文件创建一个名为sample-app的应用及对应的Service,然后单击创建

    说明

    此容器暴露出http_requests_total的指标,用来标识访问次数。

    展开查看YAML文件内容

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-app
      labels:
        app: sample-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs/knative-sample-fib-server:v1
            name: metrics-provider
            ports:
            - name: http
              containerPort: 8080
            env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name  
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sample-app
      namespace: default
      labels:
        app: sample-app
    spec:
      ports:
        - port: 8080
          name: http
          protocol: TCP
          targetPort: 8080
      selector:
        app: sample-app
      type: ClusterIP

添加ServiceMonitor

  1. 登录ARMS控制台

  2. 在左侧导航栏,单击接入中心,然后在搜索框中搜索自定义指标采集,单击自定义指标采集卡片。

  3. 在弹出面板的开始接入页签下,选中容器服务环境,并选择目标ACS集群。

  4. 参考下表在配置信息区域填写ServiceMonitor的配置信息,然后单击确定

    配置项

    示例值

    接入名称

    sample-app

    服务发现方式

    ServiceMonitor

    命名空间

    default

    端口名称

    http

    指标采集路径

    /metrics

    采集间隔(秒)

    30

    标签匹配

    • app

    • sample-app

  5. 等待接入状态检查完成。出现接入成功,开始您的观测之旅字样则说明接入操作已完成。

  6. 单击接入管理,确认监控状态。效果如下图。

    image

ack-alibaba-cloud-adapter配置文件详解

以上文中sample-app容器中暴露出来的http_requests_total指标转换成HPA中的http_requests_per_second为例,完整的ack-alibaba-cloud-adapter配置文件如下。

- seriesQuery: http_requests_total{namespace!="",pod!=""}
  resources:
    overrides:
      namespace: {resource: "namespace"}
      pod: {resource: "pod"}
  name:
    matches: ^(.*)_total
    as: ${1}_per_second
  metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)

配置项

说明

seriesQuery

PromQL请求数据。

metricsQuery

seriesQuery中PromQL请求的数据做聚合操作。

resources

PromQL里的数据Label,与resource进行匹配。这里的resource是指集群内的api-resource,例如Pod、Namespace。可通过kubectl api-resources -o wide查看。此处Key对应Prometheus数据中的LabelName,请确认Prometheus指标数据中有此LabelName。

name

根据正则匹配把Prometheus指标名转为比较可读的指标名,这里是把http_request_total转为http_request_per_second

  • Discovery:ack-alibaba-cloud-adapter组件会从Prometheus发现可用的指标。

    指定待转换的Prometheus指标,您可以通过seriesFilters精确过滤指标。seriesQuery可以根据标签进行查找(示例代码如下)。

    seriesQuery: http_requests_total{namespace!="",pod!=""}
    seriesFilters:
        - isNot: "^container_.*_seconds_total"
    说明

    seriesFilters为非必填项,用来过滤指标:

    • is:<regex>,匹配包含该正则表达式的指标。

    • isNot:<regex>,匹配不包含该正则表达式的指标。

  • Association:将指标与Kubernetes资源(Pod、Namespace)相关联。

    设置Prometheus指标标签与Kubernetes中的资源映射关系。http_requests_total指标的标签包括namespace!=""pod!=""

    - seriesQuery: http_requests_total{namespace!="",pod!=""}
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
  • Naming:定义转换后的HPA可用指标名称。

    用于将Prometheus指标名称转换成HPA的指标名称,但不会改变Prometheus本身的指标名称。如果使用Prometheus原来的指标,可以不设置。

    说明

    您可以通过执行命令kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1"查看HPA可用的所有指标。

    - seriesQuery: http_requests_total{namespace!="",pod!=""}
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: "^(.*)_total"
        as: "${1}_per_second"
  • Querying:定义查询Prometheus语句。

    查询Prometheus API的模板。ack-alibaba-cloud-adapter会根据HPA中的参数,填充参数到此模板中,然后发送给Prometheus API请求,并将获得的值最终提供给HPA进行弹性扩缩。

    - seriesQuery: http_requests_total{namespace!="",pod!=""}
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: ^(.*)_total
        as: ${1}_per_second
      metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)

如何获取Prometheus数据请求URL

阿里云Prometheus监控

  1. 登录ARMS控制台

  2. 在左侧导航栏选择Prometheus监控 > 实例列表,进入可观测监控 Prometheus 版的实例列表页面。

  3. Prometheus监控页面左上角选择ACS集群所在的地域,然后单击目标实例名称进入对应实例页面。

  4. 在左侧导航栏单击设置,然后单击设置页签。

  5. 设置页签下获取HTTP API地址(Grafana读取地址)和Token。

    推荐使用内网,如无法使用内网时,可使用公网。

    Prometheus.png

开源Prometheus监控

  1. 部署Prometheus监控方案。

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

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

    3. Helm页面,单击左上角的创建

    4. 创建面板中,Chart搜索选择ack-prometheus-operator,然后单击下一步

    5. 参数配置页面,设置相应参数,然后单击确定

      1. 查看部署结果:

        1. 执行以下命令,将集群中的Prometheus映射到本地9090端口。

          kubectl port-forward svc/ack-prometheus-operator-prometheus 9090:9090 -n monitoring
        2. 在浏览器中访问localhost:9090,即可查看Prometheus。

        3. 选择菜单栏Status > Targets,查看所有采集任务。采集任务如果所有任务的状态为UP,表示所有采集任务均已正常运行。Targets

  2. 查看Labels中对应的servicenamespace

    以ServiceName是ack-prometheus-operator-prometheus,ServiceNamespace是monitoring为例说明该开源Prometheus数据请求的URL:

    http://ack-prometheus-operator-prometheus.monitoring.svc.cluster.local:9090