使用Prometheus指标对Pod进行水平扩展

首先

我认为有一种情况是希望利用Prometheus获取某些指标,并根据需要自动缩放Pod。这次我们将使用Prometheus和sidekiq-exporter,获取Redis中待处理作业的数量,如果作业数量过多,则会自动水平缩放Pod(通过HPA实现)。

在Kubernetes和HPA上的Prometheus架构

为了简便起见,本次省略了图像,但要注意的是 Prometheus 由多个组件构成,实际上比以下图像展示的资源更为丰富。

undefined

我认为以下Prometheus操作员图表很容易理解。

undefined

参考:https://github.com/prometheus-operator/prometheus-operator/blob/9c0db5656f04e005de6a0413fd8eb8f11ec99757/Documentation/troubleshooting.md#troubleshooting-servicemonitor-changes

可以在上述链接中找到有关排查ServiceMonitor更改的故障排除信息。

将Redis和sidekiq-exporter连接起来。

将exporter引入非常简单。按照以下步骤创建Deployment。将REDIS_URL设为ElasticCache for Redis的端点。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: sidekiq
  name: sidekiq-exporter
spec:
  selector:
    matchLabels:
      app: sidekiq-exporter
  replicas: 1
  template:
    metadata:
      labels:
        app: sidekiq-exporter
      name: sidekiq-exporter
    spec:
      containers:
      - name: sidekiq-exporter
        image: strech/sidekiq-prometheus-exporter:latest
        env:
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: sidekiq-exporter-secret
              key: redis_url
        ports:
        - name: exporter
          containerPort: 9292

此外,我们将创建一个服务(Service)和一个服务监控器(ServiceMonitor),以便Prometheus能够从导出器(exporter)获取指标。服务监控器是由prometheus-operator提供的自定义资源定义(CRD),它通过服务对象检测终节点(Endpoints),并设置Prometheus来监视这些Pod。

apiVersion: v1
kind: Service
metadata:
  namespace: sidekiq
  name: sidekiq-exporter-service
  labels:
    app: sidekiq-exporter
spec:
  selector:
    app: sidekiq-exporter
  ports:
  - name: exporter
    port: 9292
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  namespace: sidekiq
  name: sidekiq-exporter-service-monitor
spec:
  selector:
    matchLabels:
      app: sidekiq-exporter
  endpoints:
  - port: exporter

使用Port Forwarding将sidekiq-exporter的Pod传输到本地,以确认它是否能够连接到Redis。

kubectl port-forward -n sidekiq <redis-exporterのPod> 8080:9292

在使用curl命令时,若能成功显示指标,则说明连接正常。

curl -s localhost:8080/metrics

2. 引入 Prometheus-Operator

prometheus-operator可以作为Kubernetes资源来管理Prometheus及其相关工具(如Alertmanager和Grafana等)。本次仅安装所需组件。



spec:
  project: default
  source:
    repoURL: https://github.com/prometheus-community/helm-charts.git
    path: charts/kube-prometheus-stack/crds/
    targetRevision: kube-prometheus-stack-37.0.0
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: default
  syncPolicy:
    automated:
      prune: true
    syncOptions:
    - Replace=true
---


spec:
  project: default
  source:
    repoURL: 'https://prometheus-community.github.io/helm-charts'
    targetRevision: 37.0.0
    helm:
      skipCrds: true
      values: |
        alertmanager:
          enabled: false
        grafana:
          enabled: false
        kubeApiServer:
          enabled: false
        kubelet:
          enabled: false
        kubeControllerManager:
          enabled: false
        coreDns:
          enabled: false
        kubeDns:
          enabled: false
        kubeEtcd:
          enabled: false
        kubeScheduler:
          enabled: false
        kubeProxy:
          enabled: false
        kubeStateMetrics:
          enabled: false
        nodeExporter:
          enabled: false
        prometheusOperator:
          admissionWebhooks:
            enabled: false
            patch:
              enabled: false
        prometheus:
          prometheusSpec:
            serviceMonitorSelectorNilUsesHelmValues: false
            serviceMonitorNamespaceSelector: {}
            serviceMonitorSelector: {}
    chart: kube-prometheus-stack
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: default
  syncPolicy:
    automated:
      prune: true
    syncOptions:
    - Replace=true

如果Prometheus的控制台界面能够显示如下内容,那就可以了。只要sidekiq-exporter处于运行状态即可。

kubectl port-forward prometheus-prometheus-operator-kube-p-prometheus-0 8000:9090

3. Prometheus适配器从Prometheus获取指标,并使其可用作API。



spec:
  project: default
  source:
    repoURL: 'https://prometheus-community.github.io/helm-charts'
    targetRevision: 3.0.0
    helm:
      values: |
        rules:
          default: false
          custom:
          - seriesQuery: 'sidekiq_enqueued_jobs{namespace!="",service!=""}'
            resources:
              overrides:
                namespace:
                  resource: namespace
                service:
                  resource: service
            name:
              as: sidekiq_enqueued_jobs
            metricsQuery: '<<.Series>>{<<.LabelMatchers>>}'
        prometheus:
          url: http://prometheus-operator-kube-p-prometheus.default
        logLevel: 2
    chart: prometheus-adapter
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: default

只要输入以下命令并显示正常,就没问题了。

kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/sidekiq/services/sidekiq-exporter-service/sidekiq_enqueued_jobs | jq .

使用custom.metrics.k8s.io API来进行HPA。

根据注册在自定义指标API中的sidekiq_enqueued_jobs值,可以控制Pod的数量。可以使用metrics.object.target.value来设置阈值。使用以下设置,当等待中的作业达到1个或更多时,Pod将进行水平扩展。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa
  namespace: sidekiq
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: <水平スケーツの対象>
  minReplicas: 1
  maxReplicas: 2
  metrics:
  - type: Object
    object:
      describedObject:
        apiVersion: v1
        kind: Service
        name: sidekiq-exporter
      metric:
        name: sidekiq_enqueued_jobs
      target:
        type: Value
        value: 1

文献来源

Sidekiq导出工具

 

普罗米修斯操作员

 

普罗米修斯适配器 (Pǔ xiū sū ěr shì qì)

 

水平Pod自动缩放(HPA)

 

其他