Как собирать метрики с приложений, расположенных вне кластера?
- Сконфигурируйте Service по аналогии с сервисом для сбора метрик с вашего приложения, но без указания параметра
spec.selector
. -
Создайте Endpoints для этого Service, явно указав в них
IP:PORT
, по которым ваши приложения отдают метрики.Имена портов в Endpoints должны совпадать с именами этих портов в Service.
Пример
Метрики приложения доступны без TLS, по адресу http://10.182.10.5:9114/metrics
.
1apiVersion: v1
2kind: Service
3metadata:
4 name: my-app
5 namespace: my-namespace
6 labels:
7 prometheus.deckhouse.io/custom-target: my-app
8spec:
9 ports:
10 - name: http-metrics
11 port: 9114
12---
13apiVersion: v1
14kind: Endpoints
15metadata:
16 name: my-app
17 namespace: my-namespace
18subsets:
19 - addresses:
20 - ip: 10.182.10.5
21 ports:
22 - name: http-metrics
23 port: 9114
Как добавить дополнительные дашборды в вашем проекте?
Добавление пользовательских дашбордов для Grafana в Deckhouse реализовано с помощью подхода Infrastructure as a Code.
Чтобы ваш дашборд появился в Grafana, необходимо создать в кластере специальный ресурс — GrafanaDashboardDefinition
.
Пример:
1apiVersion: deckhouse.io/v1
2kind: GrafanaDashboardDefinition
3metadata:
4 name: my-dashboard
5spec:
6 folder: My folder # Папка, в которой в Grafana будет отображаться ваш дашборд.
7 definition: |
8 {
9 "annotations": {
10 "list": [
11 {
12 "builtIn": 1,
13 "datasource": "-- Grafana --",
14 "enable": true,
15 "hide": true,
16 "iconColor": "rgba(0, 211, 255, 1)",
17 "limit": 100,
18...
Системные и добавленные через GrafanaDashboardDefinition дашборды нельзя изменить через интерфейс Grafana.
Алерты, настроенные в панели dashboard, не работают с шаблонами datasource — такой dashboard является невалидным и не импортируется. В версии Grafana 9.0 функционал legacy alerting был признан устаревшим и заменён на Grafana Alerting. В связи с этим, мы не рекомендуем использовать legacy alerting (оповещения панели мониторинга) в dashboards.
Если после применения дашборд не появляется в Grafana, возможно, в JSON файле дашборда присутствует ошибка. Чтобы определить источник проблемы, воспользуйтесь командой kubectl logs -n d8-monitoring deployments/grafana-v10 dashboard-provisioner
для просмотра логов компонента, который осуществляет применение дашбордов.
Как добавить алерты и/или recording-правила для вашего проекта?
Для добавления алертов существует специальный ресурс — CustomPrometheusRules
.
Параметры:
groups
— единственный параметр, в котором необходимо описать группы алертов. Структура групп полностью совпадает с аналогичной в prometheus-operator.
Пример:
1apiVersion: deckhouse.io/v1
2kind: CustomPrometheusRules
3metadata:
4 name: my-rules
5spec:
6 groups:
7 - name: cluster-state-alert.rules
8 rules:
9 - alert: CephClusterErrorState
10 annotations:
11 description: Storage cluster is in error state for more than 10m.
12 summary: Storage cluster is in error state
13 plk_markup_format: markdown
14 expr: |
15 ceph_health_status{job="rook-ceph-mgr"} > 1
Как подключить дополнительные data source для Grafana?
Для подключения дополнительных data source к Grafana существует специальный ресурс — GrafanaAdditionalDatasource
.
Параметры ресурса подробно описаны в документации к Grafana. Тип ресурса смотрите в документации по конкретному datasource.
Пример:
1apiVersion: deckhouse.io/v1
2kind: GrafanaAdditionalDatasource
3metadata:
4 name: another-prometheus
5spec:
6 type: prometheus
7 access: Proxy
8 url: https://another-prometheus.example.com/prometheus
9 basicAuth: true
10 basicAuthUser: foo
11 jsonData:
12 timeInterval: 30s
13 httpMethod: POST
14 secureJsonData:
15 basicAuthPassword: bar
Как обеспечить безопасный доступ к метрикам?
Для обеспечения безопасности настоятельно рекомендуем использовать kube-rbac-proxy
.
Пример безопасного сбора метрик с приложения, расположенного в кластере
Чтобы настроить защиту метрик приложения с использованием kube-rbac-proxy
и последующего сбора метрик с помощью Prometheus, выполните следующие шаги:
-
Создайте
ServiceAccount
с указанными ниже правами:1--- 2apiVersion: v1 3kind: ServiceAccount 4metadata: 5 name: rbac-proxy-test 6--- 7apiVersion: rbac.authorization.k8s.io/v1 8kind: ClusterRoleBinding 9metadata: 10 name: rbac-proxy-test 11roleRef: 12 apiGroup: rbac.authorization.k8s.io 13 kind: ClusterRole 14 name: d8:rbac-proxy 15subjects: 16- kind: ServiceAccount 17 name: rbac-proxy-test 18 namespace: default
Обратите внимание, что используется встроенная в Deckhouse ClusterRole
d8:rbac-proxy
. -
Создайте конфигурацию для
kube-rbac-proxy
:1--- 2apiVersion: v1 3kind: ConfigMap 4metadata: 5 name: rbac-proxy-config-test 6 namespace: rbac-proxy-test 7data: 8 config-file.yaml: |+ 9 authorization: 10 resourceAttributes: 11 namespace: default 12 apiVersion: v1 13 resource: services 14 subresource: proxy 15 name: rbac-proxy-test
Более подробную информацию по атрибутам можно найти в документации Kubernetes.
-
Создайте
Service
иDeployment
для вашего приложения, гдеkube-rbac-proxy
займет позицию sidecar-контейнера:1--- 2apiVersion: v1 3kind: Service 4metadata: 5 name: rbac-proxy-test 6 labels: 7 prometheus.deckhouse.io/custom-target: rbac-proxy-test 8spec: 9 ports: 10 - name: https-metrics 11 port: 8443 12 targetPort: https-metrics 13 selector: 14 app: rbac-proxy-test 15--- 16apiVersion: apps/v1 17kind: Deployment 18metadata: 19 name: rbac-proxy-test 20spec: 21 replicas: 1 22 selector: 23 matchLabels: 24 app: rbac-proxy-test 25 template: 26 metadata: 27 labels: 28 app: rbac-proxy-test 29 spec: 30 securityContext: 31 runAsUser: 65532 32 serviceAccountName: rbac-proxy-test 33 containers: 34 - name: kube-rbac-proxy 35 image: quay.io/brancz/kube-rbac-proxy:v0.14.0 36 args: 37 - "--secure-listen-address=0.0.0.0:8443" 38 - "--upstream=http://127.0.0.1:8081/" 39 - "--config-file=/kube-rbac-proxy/config-file.yaml" 40 - "--logtostderr=true" 41 - "--v=10" 42 ports: 43 - containerPort: 8443 44 name: https-metrics 45 volumeMounts: 46 - name: config 47 mountPath: /kube-rbac-proxy 48 - name: prometheus-example-app 49 image: quay.io/brancz/prometheus-example-app:v0.1.0 50 args: 51 - "--bind=127.0.0.1:8081" 52 volumes: 53 - name: config 54 configMap: 55 name: rbac-proxy-config-test
-
Назначьте необходимые права на ресурс для Prometheus:
1--- 2apiVersion: rbac.authorization.k8s.io/v1 3kind: ClusterRole 4metadata: 5 name: rbac-proxy-test-client 6rules: 7- apiGroups: [""] 8 resources: ["services/proxy"] 9 verbs: ["get"] 10--- 11apiVersion: rbac.authorization.k8s.io/v1 12kind: ClusterRoleBinding 13metadata: 14 name: rbac-proxy-test-client 15roleRef: 16 apiGroup: rbac.authorization.k8s.io 17 kind: ClusterRole 18 name: rbac-proxy-test-client 19subjects: 20- kind: ServiceAccount 21 name: prometheus 22 namespace: d8-monitoring
После шага 4 метрики вашего приложения должны появиться в Prometheus.
Пример безопасного сбора метрик с приложения, расположенного вне кластера
Предположим, что есть доступный через интернет сервер, на котором работает node-exporter
. По умолчанию node-exporter
слушает на порту 9100
и доступен на всех интерфейсах. Необходимо обеспечить контроль доступа к node-exporter
для безопасного сбора метрик. Ниже приведен пример такой настройки.
Требования:
- Из кластера должен быть доступ к сервису
kube-rbac-proxy
, который запущен на удаленном сервере. - От удаленного сервера должен быть доступ к API-серверу кластера.
Выполните следующие шаги:
-
Создайте
ServiceAccount
с указанными ниже правами:1--- 2apiVersion: v1 3kind: ServiceAccount 4metadata: 5 name: prometheus-external-endpoint-server-01 6 namespace: d8-service-accounts 7--- 8apiVersion: rbac.authorization.k8s.io/v1 9kind: ClusterRole 10metadata: 11 name: prometheus-external-endpoint 12rules: 13- apiGroups: ["authentication.k8s.io"] 14 resources: 15 - tokenreviews 16 verbs: ["create"] 17- apiGroups: ["authorization.k8s.io"] 18 resources: 19 - subjectaccessreviews 20 verbs: ["create"] 21--- 22apiVersion: rbac.authorization.k8s.io/v1 23kind: ClusterRoleBinding 24metadata: 25 name: prometheus-external-endpoint-server-01 26roleRef: 27 apiGroup: rbac.authorization.k8s.io 28 kind: ClusterRole 29 name: prometheus-external-endpoint 30subjects: 31- kind: ServiceAccount 32 name: prometheus-external-endpoint-server-01 33 namespace: d8-service-accounts
-
Сгенерируйте
kubeconfig
для созданногоServiceAccount
(пример генерации kubeconfig дляServiceAccount
). -
Положите получившийся
kubeconfig
на удаленный сервер. Необходимо указать путь к этомуkubeconfig
в настройкахkube-rbac-proxy
(в примере используется путь${PWD}/.kube/config
). - Настройте
node-exporter
на удаленном сервере с доступом к нему только на локальном интерфейсе (чтобы он слушал127.0.0.1:9100
). -
Запустите
kube-rbac-proxy
на удаленном сервере:1docker run --network host -d -v ${PWD}/.kube/config:/config quay.io/brancz/kube-rbac-proxy:v0.14.0 --secure-listen-address=0.0.0.0:8443 \ 2 --upstream=http://127.0.0.1:9100 --kubeconfig=/config --logtostderr=true --v=10
-
Проверьте, что порт
8443
доступен по внешнему адресу удаленного сервера. -
Создайте в кластере
Service
иEndpoint
, указав в качестве<server_ip_address>
внешний адрес удаленного сервера:1--- 2apiVersion: v1 3kind: Service 4metadata: 5 name: prometheus-external-endpoint-server-01 6 labels: 7 prometheus.deckhouse.io/custom-target: prometheus-external-endpoint-server-01 8spec: 9 ports: 10 - name: https-metrics 11 port: 8443 12--- 13apiVersion: v1 14kind: Endpoints 15metadata: 16 name: prometheus-external-endpoint-server-01 17subsets: 18 - addresses: 19 - ip: <server_ip_address> 20 ports: 21 - name: https-metrics 22 port: 8443
Как добавить Alertmanager?
Создайте кастомный ресурс CustomAlertmanager
с типом Internal
.
Пример:
1apiVersion: deckhouse.io/v1alpha1
2kind: CustomAlertmanager
3metadata:
4 name: webhook
5spec:
6 type: Internal
7 internal:
8 route:
9 groupBy: ['job']
10 groupWait: 30s
11 groupInterval: 5m
12 repeatInterval: 12h
13 receiver: 'webhook'
14 receivers:
15 - name: 'webhook'
16 webhookConfigs:
17 - url: 'http://webhookserver:8080/'
Подробно о всех параметрах можно прочитать в описании кастомного ресурса CustomAlertmanager.
Как добавить внешний дополнительный Alertmanager?
Создайте кастомный ресурс CustomAlertmanager
с типом External
, который может указывать на Alertmanager по FQDN или через сервис в Kubernetes-кластере.
Пример FQDN Alertmanager:
1apiVersion: deckhouse.io/v1alpha1
2kind: CustomAlertmanager
3metadata:
4 name: my-fqdn-alertmanager
5spec:
6 external:
7 address: https://alertmanager.mycompany.com/myprefix
8 type: External
Пример Alertmanager с Kubernetes service:
1apiVersion: deckhouse.io/v1alpha1
2kind: CustomAlertmanager
3metadata:
4 name: my-service-alertmanager
5spec:
6 external:
7 service:
8 namespace: myns
9 name: my-alertmanager
10 path: /myprefix/
11 type: External
Подробно о всех параметрах можно прочитать в описании кастомного ресурса CustomAlertmanager.
Как в Alertmanager игнорировать лишние алерты?
Решение сводится к настройке маршрутизации алертов в вашем Alertmanager.
Требования:
- Завести получателя без параметров.
- Смаршрутизировать лишние алерты в этого получателя.
Ниже приведены примеры настройки CustomAlertmanager
.
Чтобы получать только алерты с лейблами service: foo|bar|baz
:
1receivers:
2 # Получатель, определенный без параметров, будет работать как "/dev/null".
3 - name: blackhole
4 # Действующий получатель
5 - name: some-other-receiver
6 # ...
7route:
8 # receiver по умолчанию.
9 receiver: blackhole
10 routes:
11 # Дочерний маршрут
12 - matchers:
13 - matchType: =~
14 name: service
15 value: ^(foo|bar|baz)$
16 receiver: some-other-receiver
Чтобы получать все алерты, кроме DeadMansSwitch
:
1receivers:
2 # Получатель, определенный без параметров, будет работать как "/dev/null".
3 - name: blackhole
4 # Действующий получатель.
5 - name: some-other-receiver
6 # ...
7route:
8 # receiver по умолчанию.
9 receiver: some-other-receiver
10 routes:
11 # Дочерний маршрут.
12 - matchers:
13 - matchType: =
14 name: alertname
15 value: DeadMansSwitch
16 receiver: blackhole
С подробным описанием всех параметров можно ознакомиться в официальной документации.
Почему нельзя установить разный scrapeInterval для отдельных таргетов?
Наиболее полный ответ на этот вопрос дает разработчик Prometheus Brian Brazil. Вкратце, разные scrapeInterval’ы принесут следующие проблемы:
- увеличение сложности конфигурации;
- проблемы при написании запросов и создании графиков;
- короткие интервалы больше похожи на профилирование приложения, и, скорее всего, Prometheus — не самый подходящий инструмент для этого.
Наиболее подходящее значение для scrapeInterval находится в диапазоне 10–60 секунд.
Как ограничить потребление ресурсов Prometheus?
Чтобы предотвратить ситуации, когда Variable Policy Agent (VPA) запрашивает у Prometheus или долгосрочного Prometheus больше ресурсов, чем доступно на выделенном узле для этих целей, можно явно установить ограничения для VPA с использованием параметров модуля:
vpa.longtermMaxCPU
;vpa.longtermMaxMemory
;vpa.maxCPU
;vpa.maxMemory
.
Как настроить ServiceMonitor или PodMonitor для работы с Prometheus?
Добавьте лейбл prometheus: main
к Pod/Service Monitor.
Добавьте в пространство имён, в котором находится Pod/Service Monitor, лейбл prometheus.deckhouse.io/monitor-watcher-enabled: "true"
.
Пример:
1---
2apiVersion: v1
3kind: Namespace
4metadata:
5 name: frontend
6 labels:
7 prometheus.deckhouse.io/monitor-watcher-enabled: "true"
8---
9apiVersion: monitoring.coreos.com/v1
10kind: ServiceMonitor
11metadata:
12 name: example-app
13 namespace: frontend
14 labels:
15 prometheus: main
16spec:
17 selector:
18 matchLabels:
19 app: example-app
20 endpoints:
21 - port: web
Как настроить Probe для работы с Prometheus?
Добавьте лейбл prometheus: main
к Probe.
Добавьте в пространство имён, в котором находится Probe, лейбл prometheus.deckhouse.io/probe-watcher-enabled: "true"
.
Пример:
1---
2apiVersion: v1
3kind: Namespace
4metadata:
5 name: frontend
6 labels:
7 prometheus.deckhouse.io/probe-watcher-enabled: "true"
8---
9apiVersion: monitoring.coreos.com/v1
10kind: Probe
11metadata:
12 labels:
13 app: prometheus
14 component: probes
15 prometheus: main
16 name: cdn-is-up
17 namespace: frontend
18spec:
19 interval: 30s
20 jobName: httpGet
21 module: http_2xx
22 prober:
23 path: /probe
24 scheme: http
25 url: blackbox-exporter.blackbox-exporter.svc.cluster.local:9115
26 targets:
27 staticConfig:
28 static:
29 - https://example.com/status
Как настроить PrometheusRules для работы с Prometheus?
Добавьте в пространство имён, в котором находятся PrometheusRules, лейбл prometheus.deckhouse.io/rules-watcher-enabled: "true"
.
Пример:
1---
2apiVersion: v1
3kind: Namespace
4metadata:
5 name: frontend
6 labels:
7 prometheus.deckhouse.io/rules-watcher-enabled: "true"
Как увеличить размер диска
- Для увеличения размера отредактируйте PersistentVolumeClaim, указав новый размер в поле
spec.resources.requests.storage
.- Увеличение размера возможно, если в StorageClass поле
allowVolumeExpansion
установлено вtrue
.
- Увеличение размера возможно, если в StorageClass поле
- Если используемое хранилище не поддерживает изменение диска на лету, в статусе PersistentVolumeClaim появится сообщение
Waiting for user to (re-)start a pod to finish file system resize of volume on node.
. - Перезапустите под для завершения изменения размера файловой системы.
Как получить информацию об алертах в кластере?
Информацию об активных алертах можно получить не только в веб-интерфейсе Grafana/Prometheus, но и в CLI. Это может быть полезным, если у вас есть только доступ к API-серверу кластера и нет возможности открыть веб-интерфейс Grafana/Prometheus.
Выполните следующую команду для получения списка алертов в кластере:
1kubectl get clusteralerts
Пример вывода:
1NAME ALERT SEVERITY AGE LAST RECEIVED STATUS
2086551aeee5b5b24 ExtendedMonitoringDeprecatatedAnnotation 4 3h25m 38s firing
3226d35c886464d6e ExtendedMonitoringDeprecatatedAnnotation 4 3h25m 38s firing
4235d4efba7df6af4 D8SnapshotControllerPodIsNotReady 8 5d4h 44s firing
527464763f0aa857c D8PrometheusOperatorPodIsNotReady 7 5d4h 43s firing
6ab17837fffa5e440 DeadMansSwitch 4 5d4h 41s firing
Выполните следующую команду для просмотра конкретного алерта:
1kubectl get clusteralerts <ALERT_NAME> -o yaml
Пример:
1# kubectl get clusteralerts 235d4efba7df6af4 -o yaml
2alert:
3 description: |
4 The recommended course of action:
5 1. Retrieve details of the Deployment: `kubectl -n d8-snapshot-controller describe deploy snapshot-controller`
6 2. View the status of the Pod and try to figure out why it is not running: `kubectl -n d8-snapshot-controller describe pod -l app=snapshot-controller`
7 labels:
8 pod: snapshot-controller-75bd776d76-xhb2c
9 prometheus: deckhouse
10 tier: cluster
11 name: D8SnapshotControllerPodIsNotReady
12 severityLevel: "8"
13 summary: The snapshot-controller Pod is NOT Ready.
14apiVersion: deckhouse.io/v1alpha1
15kind: ClusterAlert
16metadata:
17 creationTimestamp: "2023-05-15T14:24:08Z"
18 generation: 1
19 labels:
20 app: prometheus
21 heritage: deckhouse
22 name: 235d4efba7df6af4
23 resourceVersion: "36262598"
24 uid: 817f83e4-d01a-4572-8659-0c0a7b6ca9e7
25status:
26 alertStatus: firing
27 lastUpdateTime: "2023-05-15T18:10:09Z"
28 startsAt: "2023-05-10T13:43:09Z"
{% alert level=”info” %}
Присутствие специального алерта DeadMansSwitch
в кластере говорит о работоспособности Prometheus.
{% endalert %}
Как добавить дополнительные эндпоинты в scrape config?
Добавьте в пространство имён, в котором находится ScrapeConfig, лейбл prometheus.deckhouse.io/scrape-configs-watcher-enabled: "true"
.
Пример:
1---
2apiVersion: v1
3kind: Namespace
4metadata:
5 name: frontend
6 labels:
7 prometheus.deckhouse.io/scrape-configs-watcher-enabled: "true"
Добавьте ScrapeConfig, который имеет обязательный лейбл prometheus: main
:
1apiVersion: monitoring.coreos.com/v1alpha1
2kind: ScrapeConfig
3metadata:
4 name: example-scrape-config
5 namespace: frontend
6 labels:
7 prometheus: main
8spec:
9 honorLabels: true
10 staticConfigs:
11 - targets: ['example-app.frontend.svc.{{ .Values.global.discovery.clusterDomain }}.:8080']
12 relabelings:
13 - regex: endpoint|namespace|pod|service
14 action: labeldrop
15 - targetLabel: scrape_endpoint
16 replacement: main
17 - targetLabel: job
18 replacement: kube-state-metrics
19 metricsPath: '/metrics'