Одним из основных преимуществ использования Kubernetes для оркестровки контейнеров является то, что он позволяет легко масштабировать наше приложение горизонтально и учитывать увеличенную нагрузку. Назнакомительно, горизонтальное автомассалирование POD может масштабировать развертывание на основе использования процессора и памяти, но в более сложных сценариях мы хотели бы объяснить другие показатели, прежде чем принимать решения о масштабе.
Добро пожаловать Adapter Prometheus Анкет Прометей является стандартным инструментом для мониторинга развернутых рабочих нагрузок и самого кластера Kubernetes. Adapter Prometheus помогает нам использовать метрики, собранные Prometheus, и использовать их для принятия решений масштабирования. Эти метрики выставлены службой API и могут быть легко использованы нашим Горизонтальный POD Autoscaling объект.
Обзор архитектуры
Мы будем использовать Adapter Prometheus для извлечения пользовательских метрик из нашей установки Prometheus, а затем позволить Horizontal Pod Autoscaler (HPA) Используйте его, чтобы масштабировать стручки вверх или вниз.
Предпосылка
- Основные знания о горизонтальном POD Autoscaling
- Прометей развернут в кластере или доступен с помощью конечной точки.
Мы будем использовать Прометеус-Танс Высоко доступное развертывание.
Развертывание приложения пример
Давайте сначала развертываем приложение, на котором мы будем тестировать наши метрики Prometheus. Мы можем использовать манифест ниже, чтобы сделать это
apiVersion: v1 kind: Namespace metadata: name: nginx --- apiVersion: extensions/v1beta1 kind: Deployment metadata: namespace: nginx name: nginx-deployment spec: replicas: 1 template: metadata: annotations: prometheus.io/path: "/status/format/prometheus" prometheus.io/scrape: "true" prometheus.io/port: "80" labels: app: nginx-server spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - nginx-server topologyKey: kubernetes.io/hostname containers: - name: nginx-demo image: vaibhavthakur/nginx-vts:1.0 imagePullPolicy: Always resources: limits: cpu: 2500m requests: cpu: 2000m ports: - containerPort: 80 name: http --- apiVersion: v1 kind: Service metadata: namespace: nginx name: nginx-service spec: ports: - port: 80 targetPort: 80 name: http selector: app: nginx-server type: LoadBalancer
Это создаст пространство имен с именем nginx и развернуть в нем приложение Nginx. Приложение можно получить с помощью Сервиса, а также раскрывает Nginx VTS Metrics в конечной точке /status/format/prometheus
над портом 80. Ради нашей настройки мы создали запись DNS для внешнего вида, которая отображает в nginx.gotham.com
root$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 1/1 1 1 43d root$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-65d8df7488-c578v 1/1 Running 0 9h root$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service ClusterIP 10.63.253.154 35.232.67.34 80/TCP 43d root$ kubectl describe deploy nginx-deployment Name: nginx-deployment Namespace: nginx CreationTimestamp: Tue, 08 Oct 2019 11:47:36 -0700 Labels: app=nginx-server Annotations: deployment.kubernetes.io/revision: 1 kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"nginx"},"spec":... Selector: app=nginx-server Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge Pod Template: Labels: app=nginx-server Annotations: prometheus.io/path: /status/format/prometheus prometheus.io/port: 80 prometheus.io/scrape: true Containers: nginx-demo: Image: vaibhavthakur/nginx-vts:v1.0 Port: 80/TCP Host Port: 0/TCP Limits: cpu: 250m Requests: cpu: 200m Environment:Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable OldReplicaSets: NewReplicaSet: nginx-deployment-65d8df7488 (1/1 replicas created) Events: root$ curl nginx.gotham.com Welcome to nginx! Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.Thank you for using nginx.
Это все метрики, которые в настоящее время обнажаются приложением
$ curl nginx.gotham.com/status/format/prometheus # HELP nginx_vts_info Nginx info # TYPE nginx_vts_info gauge nginx_vts_info{hostname="nginx-deployment-65d8df7488-c578v",version="1.13.12"} 1 # HELP nginx_vts_start_time_seconds Nginx start time # TYPE nginx_vts_start_time_seconds gauge nginx_vts_start_time_seconds 1574283147.043 # HELP nginx_vts_main_connections Nginx connections # TYPE nginx_vts_main_connections gauge nginx_vts_main_connections{status="accepted"} 215 nginx_vts_main_connections{status="active"} 4 nginx_vts_main_connections{status="handled"} 215 nginx_vts_main_connections{status="reading"} 0 nginx_vts_main_connections{status="requests"} 15577 nginx_vts_main_connections{status="waiting"} 3 nginx_vts_main_connections{status="writing"} 1 # HELP nginx_vts_main_shm_usage_bytes Shared memory [ngx_http_vhost_traffic_status] info # TYPE nginx_vts_main_shm_usage_bytes gauge nginx_vts_main_shm_usage_bytes{shared="max_size"} 1048575 nginx_vts_main_shm_usage_bytes{shared="used_size"} 3510 nginx_vts_main_shm_usage_bytes{shared="used_node"} 1 # HELP nginx_vts_server_bytes_total The request/response bytes # TYPE nginx_vts_server_bytes_total counter # HELP nginx_vts_server_requests_total The requests counter # TYPE nginx_vts_server_requests_total counter # HELP nginx_vts_server_request_seconds_total The request processing time in seconds # TYPE nginx_vts_server_request_seconds_total counter # HELP nginx_vts_server_request_seconds The average of request processing times in seconds # TYPE nginx_vts_server_request_seconds gauge # HELP nginx_vts_server_request_duration_seconds The histogram of request processing time # TYPE nginx_vts_server_request_duration_seconds histogram # HELP nginx_vts_server_cache_total The requests cache counter # TYPE nginx_vts_server_cache_total counter nginx_vts_server_bytes_total{host="_",direction="in"} 3303449 nginx_vts_server_bytes_total{host="_",direction="out"} 61641572 nginx_vts_server_requests_total{host="_",code="1xx"} 0 nginx_vts_server_requests_total{host="_",code="2xx"} 15574 nginx_vts_server_requests_total{host="_",code="3xx"} 0 nginx_vts_server_requests_total{host="_",code="4xx"} 2 nginx_vts_server_requests_total{host="_",code="5xx"} 0 nginx_vts_server_requests_total{host="_",code="total"} 15576 nginx_vts_server_request_seconds_total{host="_"} 0.000 nginx_vts_server_request_seconds{host="_"} 0.000 nginx_vts_server_cache_total{host="_",status="miss"} 0 nginx_vts_server_cache_total{host="_",status="bypass"} 0 nginx_vts_server_cache_total{host="_",status="expired"} 0 nginx_vts_server_cache_total{host="_",status="stale"} 0 nginx_vts_server_cache_total{host="_",status="updating"} 0 nginx_vts_server_cache_total{host="_",status="revalidated"} 0 nginx_vts_server_cache_total{host="_",status="hit"} 0 nginx_vts_server_cache_total{host="_",status="scarce"} 0 nginx_vts_server_bytes_total{host="*",direction="in"} 3303449 nginx_vts_server_bytes_total{host="*",direction="out"} 61641572 nginx_vts_server_requests_total{host="*",code="1xx"} 0 nginx_vts_server_requests_total{host="*",code="2xx"} 15574 nginx_vts_server_requests_total{host="*",code="3xx"} 0 nginx_vts_server_requests_total{host="*",code="4xx"} 2 nginx_vts_server_requests_total{host="*",code="5xx"} 0 nginx_vts_server_requests_total{host="*",code="total"} 15576 nginx_vts_server_request_seconds_total{host="*"} 0.000 nginx_vts_server_request_seconds{host="*"} 0.000 nginx_vts_server_cache_total{host="*",status="miss"} 0 nginx_vts_server_cache_total{host="*",status="bypass"} 0 nginx_vts_server_cache_total{host="*",status="expired"} 0 nginx_vts_server_cache_total{host="*",status="stale"} 0 nginx_vts_server_cache_total{host="*",status="updating"} 0 nginx_vts_server_cache_total{host="*",status="revalidated"} 0 nginx_vts_server_cache_total{host="*",status="hit"} 0 nginx_vts_server_cache_total{host="*",status="scarce"} 0
Среди них нас особенно интересует nginx_vts_server_requests_total
. Мы будем использовать значение этой метрики, чтобы определить, масштабируйте ли наше развертывание NGINX.
Создать Prometheus Adapter configmap
Используйте манифест ниже, чтобы создать ConfigMap Adapter Prometheus
apiVersion: v1 kind: ConfigMap metadata: name: adapter-config namespace: monitoring data: config.yaml: | rules: - seriesQuery: 'nginx_vts_server_requests_total' resources: overrides: kubernetes_namespace: resource: namespace kubernetes_pod_name: resource: pod name: matches: "^(.*)_total" as: "${1}_per_second" metricsQuery: (sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>))
Эта карта конфигурации указывает только одну метрику. Тем не менее, мы всегда можем добавить больше метрик.
Создать развертывание адаптера Prometheus
Используйте следующий манифест для развертывания адаптера Prometheus
apiVersion: apps/v1 kind: Deployment metadata: labels: app: custom-metrics-apiserver name: custom-metrics-apiserver namespace: monitoring spec: replicas: 1 selector: matchLabels: app: custom-metrics-apiserver template: metadata: labels: app: custom-metrics-apiserver name: custom-metrics-apiserver spec: serviceAccountName: monitoring containers: - name: custom-metrics-apiserver image: quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1 args: - /adapter - --secure-port=6443 - --tls-cert-file=/var/run/serving-cert/serving.crt - --tls-private-key-file=/var/run/serving-cert/serving.key - --logtostderr=true - --prometheus-url=http://thanos-querier.monitoring:9090/ - --metrics-relist-interval=30s - --v=10 - --config=/etc/adapter/config.yaml ports: - containerPort: 6443 volumeMounts: - mountPath: /var/run/serving-cert name: volume-serving-cert readOnly: true - mountPath: /etc/adapter/ name: config readOnly: true volumes: - name: volume-serving-cert secret: secretName: cm-adapter-serving-certs - name: config configMap: name: adapter-config
Это создаст наше развертывание, которое появит стручок адаптера Prometheus, чтобы вытащить метрик от Prometheus. Следует отметить, что мы установили аргумент
-Пометеус-URL = http://thanos-querier.monitoring: 9090/
Анкет Это связано с тем, что мы развернули кластер Prometheus-thanos в пространстве имен мониторинга в том же кластере Kubernetes, что и адаптер Prometheus. Вы можете изменить этот аргумент, чтобы указать на ваше развертывание Prometheus.
Если вы заметите журналы этого контейнера, вы увидите, что он получает метрику, определенную в файле конфигурации
I1122 00:26:53.228394 1 api.go:74] GET http://thanos-querier.monitoring:9090/api/v1/series?match%5B%5D=nginx_vts_server_requests_total&start=1574381213.217 200 OK I1122 00:26:53.234234 1 api.go:93] Response Body: {"status":"success","data":[{"__name__":"nginx_vts_server_requests_total","app":"nginx-server","cluster":"prometheus-ha","code":"1xx","host":"*","instance":"10.60.64.39:80","job":"kubernetes-pods","kubernetes_namespace":"nginx","kubernetes_pod_name":"nginx-deployment-65d8df7488-sbp95","pod_template_hash":"65d8df7488"},{"__name__":"nginx_vts_server_requests_total","app":"nginx-server","cluster":"prometheus-ha","code":"1xx","host":"*","instance":"10.60.64.8:80","job":"kubernetes-pods","kubernetes_namespace":"nginx","kubernetes_pod_name":"nginx-deployment-65d8df7488-mwzxg","pod_template_hash":"65d8df7488"}
Создание службы API API API Prometheus
Манифест ниже создаст услугу API, так что наш адаптер Prometheus доступен Kubernetes API, и, таким образом, метрики могут быть получены нашим горизонтальным Autoscaler.
apiVersion: v1 kind: Service metadata: name: custom-metrics-apiserver namespace: monitoring spec: ports: - port: 443 targetPort: 6443 selector: app: custom-metrics-apiserver --- apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: name: v1beta1.custom.metrics.k8s.io spec: service: name: custom-metrics-apiserver namespace: monitoring group: custom.metrics.k8s.io version: v1beta1 insecureSkipTLSVerify: true groupPriorityMinimum: 100 versionPriority: 100
Тестирование настройки
Давайте проверим, какие доступны все пользовательские метрики
root$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . { "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "custom.metrics.k8s.io/v1beta1", "resources": [ { "name": "pods/nginx_vts_server_requests_per_second", "singularName": "", "namespaced": true, "kind": "MetricValueList", "verbs": [ "get" ] }, { "name": "namespaces/nginx_vts_server_requests_per_second", "singularName": "", "namespaced": false, "kind": "MetricValueList", "verbs": [ "get" ] } ] }
Мы можем видеть это nginx_vts_server_requests_per_second
Метрика доступна. Теперь давайте проверим текущее значение этой метрики
root$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/nginx/pods/*/nginx_vts_server_requests_per_second" | jq . { "kind": "MetricValueList", "apiVersion": "custom.metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/nginx/pods/%2A/nginx_vts_server_requests_per_second" }, "items": [ { "describedObject": { "kind": "Pod", "namespace": "nginx", "name": "nginx-deployment-65d8df7488-v575j", "apiVersion": "/v1" }, "metricName": "nginx_vts_server_requests_per_second", "timestamp": "2019-11-19T18:38:21Z", "value": "1236m" } ] }
Создайте HPA, который будет использовать эти метрики. Мы можем использовать манифест ниже, чтобы сделать это.
apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: nginx-custom-hpa namespace: nginx spec: scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: nginx-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metricName: nginx_vts_server_requests_per_second targetAverageValue: 4000m
После того, как вы примените этот манифест, вы можете проверить текущее состояние HPA следующим образом:
root$ kubectl describe hpa Name: nginx-custom-hpa Namespace: nginx Labels:Annotations: autoscaling.alpha.kubernetes.io/metrics: [{"type":"Pods","pods":{"metricName":"nginx_vts_server_requests_per_second","targetAverageValue":"4"}}] kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx-custom-hpa","namespace":"n... CreationTimestamp: Thu, 21 Nov 2019 11:11:05 -0800 Reference: Deployment/nginx-deployment Min replicas: 2 Max replicas: 10 Deployment pods: 0 current / 0 desired Events:
Теперь давайте создадим некоторую нагрузку на нашу службу. Мы будем использовать утилиту под названием Вегета для этого. В отдельном терминале запустить следующую команду
echo "GET http://nginx.gotham.com/" | vegeta attack -rate=5 -duration=0 | vegeta report
Тем временем контролируйте стручки Nginx и горизонтальный POD Autoscaler, и вы должны увидеть что -то подобное
root$ kubectl get -w pods NAME READY STATUS RESTARTS AGE nginx-deployment-65d8df7488-mwzxg 1/1 Running 0 9h nginx-deployment-65d8df7488-sbp95 1/1 Running 0 4m9s NAME AGE nginx-deployment-65d8df7488-pwjzm 0s nginx-deployment-65d8df7488-pwjzm 0s nginx-deployment-65d8df7488-pwjzm 0s nginx-deployment-65d8df7488-pwjzm 2s nginx-deployment-65d8df7488-pwjzm 4s nginx-deployment-65d8df7488-jvbvp 0s nginx-deployment-65d8df7488-jvbvp 0s nginx-deployment-65d8df7488-jvbvp 1s nginx-deployment-65d8df7488-jvbvp 4s nginx-deployment-65d8df7488-jvbvp 7s nginx-deployment-65d8df7488-skjkm 0s nginx-deployment-65d8df7488-skjkm 0s nginx-deployment-65d8df7488-jh5vw 0s nginx-deployment-65d8df7488-skjkm 0s nginx-deployment-65d8df7488-jh5vw 0s nginx-deployment-65d8df7488-jh5vw 1s nginx-deployment-65d8df7488-skjkm 2s nginx-deployment-65d8df7488-jh5vw 2s nginx-deployment-65d8df7488-skjkm 3s nginx-deployment-65d8df7488-jh5vw 4s root$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE nginx-custom-hpa Deployment/nginx-deployment 5223m/4 2 10 3 5m5s
Ясно видно, что HPA увеличил наши стручки в соответствии с требованием, и когда мы прервали команду Вегеты, мы получили отчет Вегеты. Это ясно показывает, что все наши запросы были поданы заявлением.
root$ echo "GET http://nginx.gotham.com/" | vegeta attack -rate=5 -duration=0 | vegeta report ^CRequests [total, rate, throughput] 224, 5.02, 5.02 Duration [total, attack, wait] 44.663806863s, 44.601823883s, 61.98298ms Latencies [mean, 50, 95, 99, max] 63.3879ms, 60.867241ms, 79.414139ms, 111.981619ms, 229.310088ms Bytes In [total, mean] 137088, 612.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 100.00% Status Codes [code:count] 200:224 Error Set:
Эта установка демонстрирует, как мы можем использовать адаптер Prometheus для автоматических развертываний на основе некоторых пользовательских метрик. Для простоты мы получили только одну метрику с нашего сервера Prometheus. Тем не менее, конфигурация адаптера может быть расширена, чтобы принести некоторые или все доступные метрики и использовать их для автоматической мастерской. Если установка Prometheus находится за пределами нашего кластера Kubernetes, нам просто нужно убедиться, что конечная точка запроса доступна из кластера и обновить его в манифесте развертывания адаптера. При более сложных сценариях можно извлечь несколько метрик и использовать в комбинированности для принятия решений масштабирования.
Оригинал: «https://dev.to/appfleet/prometheus-metrics-based-autoscaling-in-kubernetes-5fig»