Маємо на проекті багато AWS Lambda функцій, з яких девелопери хочуть мати можливість відправляти метрики до нашого Prometheus, щоб додати власних алертів та графіків у Grafana.
Для цього у функціях використовується бібліотека Prometheus, яка дозволяє ці метрики створювати (див. Prometheus: створення Custom Prometheus Exporter на Python), але ж ми не маємо змоги нормально отримати ці дані з Prometheus, бо функції можуть жити декілька секунд, а Prometheus використовує PULL-модель, тобто він сам ходить до експортерів, та витягує звідти дані.
Що можемо зробити у випадку AWS Lambda – це додати Prometheus Pushgateway, який буде мати зовнішній ендпоінт, на який функції будуть слати свої метрики, а Prometheus буде забирати ці дані з Pushgateway, який виконує таку собі “проксі роль”.
Загальна схема роботи Prometheus та роль Pushgateway добре відображена на цій схемі:
Тож сьогодні запустимо Prometheus Pushgateway у Kubernetes використовуючи Helm-чарт, а чарт будемо встановлювати за допомогою Terraform.
Зміст
Pushgateway Helm chart
Спочатку, давайте подивимося, що у нас є у values чарту Pushgateway.
По факту, наразі нам тут можуть бути цікавими тільки два параметри – це Ingress та ServiceMonitor.
Напишемо свій values, для тесту задеплоїмо на Dev оточення, а потім додамо до Terraform, через який Pushgateway вже буде деплоїтися по всіх наших моніторинг-оточеннях:
ingress:
enabled: true
className: alb
path: /
pathType: Prefix
annotations:
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:638***021:certificate/e97f17e9-33f9-46e7-9b2b-d50de8a72219
alb.ingress.kubernetes.io/target-type: ip
hosts:
- test-pushgateway.monitoring.dev.example.com
serviceMonitor:
enabled: true
namespace: monitoring
additionalLabels:
release: prometheus
Тут описуємо створення Kubernetes Ingress, якому на порт 443 відповідного AWS Application Load Balancer підключимо SSL сертифікат з Amazon Certificate Manager. В hosts задаємо ім’я хоста, яке за допомогою ExternalDNS буде створено в AWS Route53.
І додаємо ServiceMonitor з лейблою release: prometheus, щоб Prometheus із Kube Prometheus Stack його побачив.
Додаємо репозиторій Prometheus:
[simterm]
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm repo update
[/simterm]
І встановлюємо Pushgateway до неймспейсу monitoring:
[simterm]
$ helm -n monitoring upgrade --install prometheus-pushgateway-test prometheus-community/prometheus-pushgateway -f pushgateway-values-dev.yaml ... NOTES: 1. Get the application URL by running these commands: http://test-pushgateway.monitoring.example.com/
[/simterm]
Перевіряємо Pod та Ingress:
[simterm]
$ kubectl get pod,ingress --namespace monitoring -l app.kubernetes.io/instance=prometheus-pushgateway-test NAME READY STATUS RESTARTS AGE pod/prometheus-pushgateway-test-6b5dfbdd7f-chzkf 1/1 Running 0 53s NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/prometheus-pushgateway-test alb test-pushgateway.monitoring.dev.example.com internal-k8s-monitori-promethe-***-***.us-west-2.elb.amazonaws.com 80 54s
[/simterm]
Pushgateway має власний веб-інтерфейс – відкриваємо доступ до його поду на порт 9091:
[simterm]
$ kubectl -n monitoring port-forward pod/prometheus-pushgateway-test-6b5dfbdd7f-chzkf 9091 Forwarding from 127.0.0.1:9091 -> 9091 Forwarding from [::1]:9091 -> 9091
[/simterm]
Та в браузері переходимо на http://localhost:9091:
Далі, перевіримо чи бачить сам Prometheus цей Pushgateway – відкриваємо порт 9090 до Prometheus Pod:
[simterm]
$ kk -n monitoring port-forward prometheus-prometheus-kube-prometheus-prometheus-0 9090 Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090
[/simterm]
Та переходимо до Status > Targets, і шукаємо Pushgateway target:
І перевіримо, чи потраплять метрики з Pushgateway до Prometheus.
Оскільки наш Ingress/ALB має тип internal, тобто недоступний ззовні, то запустимо Kubernetes Pod з Ubuntu в Kubernetes-кластері:
[simterm]
$ kubectl run pod --rm -i --tty --image ubuntu -- bash If you don't see a command prompt, try pressing enter. root@pod:/#
[/simterm]
Встановлюємо в ньому curl:
[simterm]
root@pod:/# apt update && apt -y install curl
[/simterm]
Та користуючись документацією відправимо запит, тільки порт не вказуємо, бо у нас він 443, SSL:
[simterm]
root@pod:/# echo "some_metric 3.14" | curl --data-binary @- https://test-pushgateway.monitoring.dev.exmaple.com/metrics/job/some_job
[/simterm]
Перевіряємо в Pushgateway:
Та у Prometheus:
Є, чудово.
Аутентифікація Pushgateway
Оскільки у нас Pushgateway працює на internal-ALB, то я не став поки робити аутентифікацію, бо він це все ще в процесі тестування, і поки невідомо як воно там зайде девелоперам.
Але у values є блок, з прикладом запуску контейнера з openshift/oauth-proxy, а у Using OpenShift OAuth Proxy to secure your Applications on OpenShift наче непогано описано приклад його використання – якось можна буде спробувати.
Terraform та Helm для Pushgateway
“Так в проекті повелося” (с), що більша частина ресурсів у Kubernetes деплоїться за допомогою Terraform та його helm_release resource.
У нас багато аккаунтів AWS, і в кожному буде свій ARN сертифікату, тож отримаємо його за допомогою Data Source (або можна створити власний за допомогою aws_acm_certificate):
data "aws_acm_certificate" "wildcard" {
domain = "*.${var.root_domain}"
}
Змінна root_domain у нас передається з основного модулю, та має вигляд monitoring.dev.example.com.
Для нашого values створюємо темплейт pushgateway-values.tpl.yaml:
ingress:
enabled: true
className: alb
path: /
pathType: Prefix
annotations:
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/certificate-arn: ${acmWildcardArn}
alb.ingress.kubernetes.io/target-type: ip
hosts:
- ${pushgatewayUrl}
serviceMonitor:
enabled: true
namespace: monitoring
additionalLabels:
release: prometheus
І додаємо сам helm_release, в якому у values[] задаємо файл темплейту та пару змінних – ARN сертифікату, який отримали за допомогою data.aws_acm_certificate, та домен для Ingress hosts:
resource "helm_release" "pushgateway" {
name = "prometheus-pushgateway"
namespace = kubernetes_namespace.monitoring.id
repository = "https://prometheus-community.github.io/helm-charts"
chart = "prometheus-pushgateway"
version = "2.1.3"
max_history = 10
values = [
templatefile("${path.module}/configs/prometheus/pushgateway-values.tpl.yaml", {
acmWildcardArn : data.aws_acm_certificate.wildcard.arn,
pushgatewayUrl : "pushgateway.${var.root_domain}"
})
]
}
Деплоїмо:
[simterm]
$ terraform apply ... module.monitoring.helm_release.pushgateway: Creating... module.monitoring.helm_release.pushgateway: Still creating... [10s elapsed] module.monitoring.helm_release.pushgateway: Still creating... [20s elapsed] module.monitoring.helm_release.pushgateway: Still creating... [30s elapsed] module.monitoring.helm_release.pushgateway: Creation complete after 32s [id=prometheus-pushgateway] ... Apply complete! Resources: 1 added, 1 changed, 0 destroyed.
[/simterm]
Перевіряємо Ingress та Pod:
[simterm]
$ kk -n monitoring get ingress,pod -l app.kubernetes.io/instance=prometheus-pushgateway NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/prometheus-pushgateway alb pushgateway.monitoring.dev.example.com internal-k8s-monitori-promethe-***-***.us-west-2.elb.amazonaws.com 80 10m NAME READY STATUS RESTARTS AGE pod/prometheus-pushgateway-55b9f5ffd6-sm9ck 1/1 Running 0 10m
[/simterm]
Все є.
Готово.




