Как масштабировать мое приложение на метриках nginx без prometheus?

Я хочу масштабировать свое приложение на основе пользовательских показателей (в данном случае RPS или активных подключений). Без необходимости настраивать Prometheus или использовать какой-либо внешний сервис. Я могу открыть этот API из своего веб-приложения. Каковы мои варианты?

1 ответ

Мониторинг различных типов метрик (например, пользовательских метрик) в большинстве кластеров Kubernetes — это основа, которая ведет к более стабильным и надежным системам/приложениям/рабочим нагрузкам. Как обсуждалось в разделе комментариев, для мониторинга пользовательских метрик рекомендуется использовать инструменты, предназначенные для этой цели, а не изобретать обходной путь. Я рад, что в данном случае окончательное решение было использовать Prometheus и KEDA для правильного масштабирования веб-приложения.

Я хотел бы кратко показать другим членам сообщества, которые борются со схожими соображениями, как работает KEDA.


Чтобы использовать Prometheus в качестве масштабатора для Keda, нам нужно установить и настроить Prometheus. Существует множество различных способов установки Prometheus, и вы должны выбрать тот, который соответствует вашим потребностям.

Я установил стек kube-prometheus с помощью Helm:
ПРИМЕЧАНИЕ. Я разрешил Prometheus обнаруживать все PodMonitors/ ServiceMonitorsвнутри своего пространства имен, не применяя фильтрацию меток, установив параметр prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValuesа также prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValuesзначения для false.

      $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm install prom-1 prometheus-community/kube-prometheus-stack --set prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues=false --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false

$ kubectl get pods
NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-prom-1-kube-prometheus-sta-alertmanager-0   2/2     Running   0          2m29s
prom-1-grafana-865d4c8876-8zdhm                          3/3     Running   0          2m34s
prom-1-kube-prometheus-sta-operator-6b5d5d8df5-scdjb     1/1     Running   0          2m34s
prom-1-kube-state-metrics-74b4bb7857-grbw9               1/1     Running   0          2m34s
prom-1-prometheus-node-exporter-2v2s6                    1/1     Running   0          2m34s
prom-1-prometheus-node-exporter-4vc9k                    1/1     Running   0          2m34s
prom-1-prometheus-node-exporter-7jchl                    1/1     Running   0          2m35s
prometheus-prom-1-kube-prometheus-sta-prometheus-0       2/2     Running   0          2m28s

Затем мы можем развернуть приложение, за которым будет следить Prometheus. Я создал простое приложение, которое предоставляет некоторые метрики (например, ) на /status/format/prometheusдорожка:

      $ cat app-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1
spec:
  selector:
    matchLabels:
      app: app-1
  template:
    metadata:
      labels:
        app: app-1
    spec:
      containers:
      - name: app-1
        image: mattjcontainerregistry/nginx-vts:v1.0
        resources:
          limits:
            cpu: 50m
          requests:
            cpu: 50m
        ports:
        - containerPort: 80
          name: http
---
apiVersion: v1
kind: Service
metadata:
  name: app-1
  labels:
    app: app-1
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: app-1
  type: LoadBalancer

Затем создайте ServiceMonitor , который описывает, как отслеживать наше приложение:

      $ cat servicemonitor.yaml
kind: ServiceMonitor
apiVersion: monitoring.coreos.com/v1
metadata:
  name: app-1
  labels:
    app: app-1
spec:
  selector:
    matchLabels:
      app: app-1
  endpoints:
  - interval: 15s
    path: "/status/format/prometheus"
    port: http

Подождав некоторое время, давайте проверим журналы, чтобы убедиться, что он правильно удален:

      $ kubectl get pods | grep app-1
app-1-5986d56f7f-2plj5                                   1/1     Running   0          35s

$ kubectl logs -f app-1-5986d56f7f-2plj5
10.44.1.6 - - [07/Feb/2022:16:31:11 +0000] "GET /status/format/prometheus HTTP/1.1" 200 2742 "-" "Prometheus/2.33.1" "-"
10.44.1.6 - - [07/Feb/2022:16:31:26 +0000] "GET /status/format/prometheus HTTP/1.1" 200 3762 "-" "Prometheus/2.33.1" "-"
10.44.1.6 - - [07/Feb/2022:16:31:41 +0000] "GET /status/format/prometheus HTTP/1.1" 200 3762 "-" "Prometheus/2.33.1" "-"

Теперь пришло время развернуть KEDA. Существует несколько подходов к развертыванию среды выполнения KEDA, как описано в документации KEDA . Я решил установить KEDA с помощью Helm, потому что это очень просто :-)

      $ helm repo add kedacore https://kedacore.github.io/charts
$ helm repo update
$ kubectl create namespace keda
$ helm install keda kedacore/keda --namespace keda

Последнее, что нам нужно создать, этоScaledObjectкоторый используется для определения того, как KEDA должен масштабировать наше приложение и каковы триггеры. В приведенном ниже примере я использовал nginx_vts_server_requests_totalметрика.
ПРИМЕЧАНИЕ. Дополнительные сведения о триггере prometheus см. в документации по спецификации триггера .

      $ cat scaled-object.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: scaled-app-1
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app-1
  pollingInterval: 30                               
  cooldownPeriod:  120                              
  minReplicaCount: 1                                
  maxReplicaCount: 5                               
  advanced:                                         
    restoreToOriginalReplicaCount: false            
    horizontalPodAutoscalerConfig:                  
      behavior:                                     
        scaleDown:
          stabilizationWindowSeconds: 300
          policies:
          - type: Percent
            value: 100
            periodSeconds: 15
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prom-1-kube-prometheus-sta-prometheus.default.svc:9090
      metricName: nginx_vts_server_requests_total
      query: sum(rate(nginx_vts_server_requests_total{code="2xx", service="app-1"}[2m])) # Note: query must return a vector/scalar single element response
      threshold: '10'
  
$ kubectl apply -f scaled-object.yaml
scaledobject.keda.sh/scaled-app-1 created

Наконец, мы можем проверить, app-1приложение правильно масштабируется в зависимости от количества запросов:

      $ for a in $(seq 1 10000); do curl <PUBLIC_IP_APP_1> 1>/dev/null 2>&1; done

$ kubectl get hpa -w
NAME                    REFERENCE          TARGETS          MINPODS   MAXPODS   REPLICAS   
keda-hpa-scaled-app-1   Deployment/app-1   0/10 (avg)        1         5         1           
keda-hpa-scaled-app-1   Deployment/app-1   15/10 (avg)       1         5         2         
keda-hpa-scaled-app-1   Deployment/app-1   12334m/10 (avg)   1         5         3       
keda-hpa-scaled-app-1   Deployment/app-1   13250m/10 (avg)   1         5         4      
keda-hpa-scaled-app-1   Deployment/app-1   12600m/10 (avg)   1         5         5          

$ kubectl get pods | grep app-1
app-1-5986d56f7f-2plj5                                   1/1     Running   0          36m
app-1-5986d56f7f-5nrqd                                   1/1     Running   0          77s
app-1-5986d56f7f-78jw8                                   1/1     Running   0          94s
app-1-5986d56f7f-bl859                                   1/1     Running   0          62s
app-1-5986d56f7f-xlfp6                                   1/1     Running   0          45s

Как вы можете видеть выше, наше приложение было правильно масштабировано до 5 реплик.

Другие вопросы по тегам