Продовжуємо розвивати наш стек моніторингу. Див. VictoriaMetrics: створення Kubernetes monitoring stack з власним Helm-чартом.
Що хочеться: зробити доступ девелоперам, щоб вони могли в Alertmanager самі виставляти Silence для алертів аби не спамити в Slack, див. Prometheus: Alertmanager Web UI и Silence алертов.
Для того, щоб забезпечити безпечний доступ до нього можна використати рішення від VictoriaMetrics – компонент VMAuth, який дозволяє створити єдиний ендпоінт, через який будуть ходити всі юзери і налаштувати відповідні бекенди для інших компонентів кластеру.
Кратко – що можна з VMAuth:
- створити єдину точку входу для сервісів з Basic або Bearer user аутентифікацією та авторизацією
- в залежності від юзера та роута/URI направляти його до відповідного сервіса (фактично, ви можете створити один Ingress і всі запити обслуговувати через нього замість того, щоб створювати Ingress та аутентифікацію для кожного сервіса окремо)
- мати простий round-robin load balancer
- налаштувати IP фільтри з Allow та Deny листами
- керувати додаванням власних хедерів до запитів
Деплоїти будемо у AWS EKS з Helm-чарту victoria-metrics-auth, але можна робити через yaml-маніфести, див. документацію та інші приклади на Authorization and exposing components та VMAuth.
Зміст
Встановлення чарту VMAuth
Так як ми маємо umbrella-chart, то додаємо в Chart.yaml в блок dependecy новий сабчарт:
... - name: victoria-metrics-auth version: ~0.3.3 repository: https://victoriametrics.github.io/helm-charts/ ...
Дефолтні вальюси – values.yaml.
У власних values.yaml описуємо конфіг VMAuth – створення Ingress, ім’я користувача, пароль, та куди перенаправляти його запити – тут це буде Kubernetes Service для Alertmanager:
...
victoria-metrics-auth:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:49***148:certificate/66e3050e-7f27-4f0c-8ad4-0733a6d8071a
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600
hosts:
- name: vmauth.dev.example.co
path: /
port: http
config:
users:
- username: "vmadmin"
password: "p@ssw0rd"
url_prefix: "http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093"
...
Вновлюмо Helm dependency:
[simterm]
$ helm dependency update
[/simterm]
І деплоїмо чарт:
[simterm]
$ helm -n dev-monitoring-ns upgrade --install atlas-victoriametrics . -f values/dev/atlas-monitoring-dev-values.yaml
[/simterm]
Перевіряємо чи додався Ingress і AWS ALB до нього:
[simterm]
$ kk -n dev-monitoring-ns get ingress NAME CLASS HOSTS ADDRESS PORTS AGE atlas-victoriametrics-victoria-metrics-auth <none> vmauth.dev.example.co k8s-***elb.amazonaws.com 80 3m12s
[/simterm]
Чекаємо поки оновляться DNS, і відкриваємо https://vmauth.dev.example.co:
Логінимось, і попадаємо прямо в Алертменеджер:
Конфіг в Kubernetes Secret
Замість того, щоб тримати конфіг в values чарту можно створити Kubernetes Secret. Це додатково дасть можливість передавати пароль, якщо він у вас один, через helm install --set:
apiVersion: v1
kind: Secret
metadata:
name: vmauth-config-secret
stringData:
auth.yml: |-
users:
- username: vmadmin
password: {{ .Values.vmauth_password }}
url_map:
url_prefix: http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093/
VMAuth, users та routes
Є можливість створити одного користувача, і з url_map йому налаштувати кілька роутів – в залежності від URI запиту, він буде перенаправлений на відповідний бекенд, а з default_url задати URL, куди будуть перенаравлені запроси, для яких не задано роута. При цьому в роутах можна використовувати регулярки.
Наприклад:
...
users:
- username: vmadmin
password: {{ .Values.vmauth_password }}
url_map:
- src_paths:
- /alertmanager.*
url_prefix: http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093/
- src_paths:
- /vmui.*
url_prefix: http://vmsingle-vm-k8s-stack.dev-monitoring-ns.svc:8429
default_url:
- https://google.com
Якщо плануєте додавати доступ до інстансу VMSingle – додайте блок для Prometheus, бо інакше будуть помилки виду:
{“ts”:”2023-08-22T14:37:43.363Z”,”level”:”warn”,”caller”:”VictoriaMetrics/app/vmauth/main.go:159″,”msg”:”remoteAddr: \”10.0.0.74:25806, X-Forwarded-For: 217.***.***.253\”; requestURI: /prometheus/vmui/custom-dashboards; missing route for \”/prometheus/v
mui/custom-dashboards\””}
{“ts”:”2023-08-22T14:37:43.396Z”,”level”:”warn”,”caller”:”VictoriaMetrics/app/vmauth/main.go:159″,”msg”:”remoteAddr: \”10.0.0.74:25806, X-Forwarded-For: ***.***.165.253\”; requestURI: /prometheus/api/v1/label/__name__/values; missing route for \”/promet
heus/api/v1/label/__name__/values\””}
Для Prometheus блок виглядає аналогічно:
...
- src_paths:
- /prometheus.*
url_prefix: http://vmsingle-vm-k8s-stack.dev-monitoring-ns.svc:8429
Для того, щоб сам Alertmanager працював через URI /alertmanager – в його values налаштовуємо routePrefix:
...
alertmanager:
enabled: true
spec:
configSecret: "alertmanager-config"
routePrefix: "/alertmanager"
...
І не забудьте в такому випадку змінити дефолтний URL для VMAlert у його values:
...
vmalert:
annotations: {}
enabled: true
spec:
notifier:
url: "http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093/alertmanager"
...
Деплоїмо зміни, а щоб застосувати зміни конфіг в самому інстансі VMAuth, виконуємо запит до ендпоінту /-/reload, тобто – https://vmauth.dev.example.co/-/reload.
Тепер Alertmanager доступний за адресою https://vmauth.dev.example.co/alertmanager:
Насправді, настройка src_paths може бути трохи геморною, бо, наприклад, в документації роути вказані просто як /uri/path:
url_map: - src_paths: - /api/v1/query - /api/v1/query_range
Але коли я почав це робити, то виявилось, що при виконанні редіректу з VMAuth на внутрішній сервіс в кінці додається зайвий слеш, і доступ до Alertmanager не працював.
Саме тому в моїх прикладах вище роути задані з “.*“.
Години дві спілкувався з саппортом в VictoriaMetrcis Slack, намагались знайти причину проблем з доступом к Alertmanager, наче знайшли, завів GitHub issue, подивимось, як воно буде далі.
Взагалі, підтримку VictoriaMetrics варто згадати окремо, бо працює вона чудово і досить швидко. Є Slack, є Telegram-канал.
Basic Auth vs Bearer token
Замість звичайного логіна:пароля можемо використати ServiceAccount токен.
Створюємо ServiceAccount та Secret для нього з типом kubernetes.io/service-account-token:
apiVersion: v1
kind: ServiceAccount
metadata:
name: vmauth-sa
namespace: dev-monitoring-ns
secrets:
- name: vmauth-token-secret
---
apiVersion: v1
kind: Secret
metadata:
name: vmauth-token-secret
namespace: dev-monitoring-ns
annotations:
kubernetes.io/service-account.name: vmauth-sa
type: kubernetes.io/service-account-token
Деплоїмо, отримуємо токен для цього ServicAccount:
[simterm]
$ kk -n dev-monitoring-ns create token vmauth-sa eyJhbGciOi***gfeNGWVjJn5-LWd2aslxAwnUTpQ
[/simterm]
Додаємо bearer_token в конфіг VMAuth:
...
users:
- username: vmadmin
password: {{ .Values.vmauth_password }}
url_map:
- src_paths:
- /alertmanager.*
url_prefix: http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093
- src_paths:
- /vmui.*
url_prefix: http://vmsingle-vm-k8s-stack.dev-monitoring-ns.svc:8429
- src_paths:
- /prometheus.*
url_prefix: http://vmsingle-vm-k8s-stack.dev-monitoring-ns.svc:8429
- bearer_token: "eyJhbGciOiJSUzI1NiIsImtpZ***gfeNGWVjJn5-LWd2aslxAwnUTpQ"
url_prefix: http://vmalertmanager-vm-k8s-stack.dev-monitoring-ns.svc:9093
Деплоїмо, знов робимо /-/reload, та перевіряємо доступ.
Заносимо токен в змінну:
[simterm]
$ token="eyJhbGciOiJSUzI1NiIsImt***-LWd2aslxAwnUTpQ"wnUTpQ
[/simterm]
І з curl відкриваємо ендпоінт:
[simterm]
$ curl -H "Authorization: Bearer ${token}" https://vmauth.dev.example.co/
<a href="/alertmanager">Found</a>.
[/simterm]
VMAuth та “AnyService”
Ну і на останнє – VMAuth можна використовувати для аутентифікації не тільки VictoriaMetrics та її сервісів, а (майже) будь-яких.
Наприклад, маємо под з Nginx Demo:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-pod
spec:
containers:
- name: my-container
image: nginxdemos/hello
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
У VMAuth додаємо роут:
...
- src_paths:
- /nginxdemo.*
url_prefix: http://my-service.default.svc:80
І тепер за адресою https://vmauth.dev.example.co/nginxdemo попадаемо на Nginx:
А от для стандартної Kubernetes Dashboard так не вийде, бо вона використовує self-signed TLS сертифиікат, і VMAuth не підключається до відповідного сервісу, бо не може провалідувати сертификат. Можливо, є рішення, але не шукав, бо в принципі не потрібно.
VMAuth Self-Security
Див. документацію.
Закрийте аутентифікацією “службові” роути самого VMAuth.
У values.yaml додаємо ключі:
...
extraArgs:
reloadAuthKey: password
flagsAuthKey: password
metricsAuthKey: password
pprofAuthKey: password
...
Деплоїмо, і тепер якщо викликати /-/reload без ключа – буде помилка:
[simterm]
$ curl https://vmauth.dev.example.co/-/reload The provided authKey doesn't match -reloadAuthKey
[/simterm]
Щоб передати ключ для аутентифікації – використовуємо форму /-/reload?authKey=password:
[simterm]
$ curl -I https://vmauth.dev.example.co/-/reload?authKey=password HTTP/2 200
[/simterm]
Поки що наче немає можливості передачи ключі через Kubertes Secret, тільки хардкодити у values.yaml, але вже є фіча-реквест.







