Как собирать метрики с приложений, расположенных вне кластера?
- Сконфигурируйте Service по аналогии с сервисом для сбора метрик с вашего приложения, но без указания параметра
spec.selector
. -
Создайте Endpoints для этого Service, явно указав в них
IP:PORT
, по которым ваши приложения отдают метрики.Имена портов в Endpoints должны совпадать с именами этих портов в Service.
Пример
Метрики приложения доступны без TLS, по адресу http://10.182.10.5:9114/metrics
.
apiVersion: v1
kind: Service
metadata:
name: my-app
namespace: my-namespace
labels:
prometheus.deckhouse.io/custom-target: my-app
spec:
ports:
- name: http-metrics
port: 9114
---
apiVersion: v1
kind: Endpoints
metadata:
name: my-app
namespace: my-namespace
subsets:
- addresses:
- ip: 10.182.10.5
ports:
- name: http-metrics
port: 9114
Как добавить дополнительные дашборды в вашем проекте?
Добавление пользовательских дашбордов для Grafana в Deckhouse реализовано с помощью подхода Infrastructure as a Code.
Чтобы ваш дашборд появился в Grafana, необходимо создать в кластере специальный ресурс — GrafanaDashboardDefinition
.
Пример:
apiVersion: deckhouse.io/v1
kind: GrafanaDashboardDefinition
metadata:
name: my-dashboard
spec:
folder: My folder # Папка, в которой в Grafana будет отображаться ваш дашборд.
definition: |
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
...
{% alert level=”warning” %} Системные и добавленные через GrafanaDashboardDefinition дашборды нельзя изменить через интерфейс Grafana. {% endalert %}
Как добавить алерты и/или recording-правила для вашего проекта?
Для добавления алертов существует специальный ресурс — CustomPrometheusRules
.
Параметры:
groups
— единственный параметр, в котором необходимо описать группы алертов. Структура групп полностью совпадает с аналогичной в prometheus-operator.
Пример:
apiVersion: deckhouse.io/v1
kind: CustomPrometheusRules
metadata:
name: my-rules
spec:
groups:
- name: cluster-state-alert.rules
rules:
- alert: CephClusterErrorState
annotations:
description: Storage cluster is in error state for more than 10m.
summary: Storage cluster is in error state
plk_markup_format: markdown
expr: |
ceph_health_status{job="rook-ceph-mgr"} > 1
Как подключить дополнительные data source для Grafana?
Для подключения дополнительных data source к Grafana существует специальный ресурс — GrafanaAdditionalDatasource
.
Параметры ресурса подробно описаны в документации к Grafana. Тип ресурса смотрите в документации по конкретному datasource.
Пример:
apiVersion: deckhouse.io/v1
kind: GrafanaAdditionalDatasource
metadata:
name: another-prometheus
spec:
type: prometheus
access: Proxy
url: https://another-prometheus.example.com/prometheus
basicAuth: true
basicAuthUser: foo
jsonData:
timeInterval: 30s
httpMethod: POST
secureJsonData:
basicAuthPassword: bar
Как обеспечить безопасный доступ к метрикам?
Для обеспечения безопасности настоятельно рекомендуем использовать kube-rbac-proxy
.
Пример безопасного сбора метрик с приложения, расположенного в кластере
Чтобы настроить защиту метрик приложения с использованием kube-rbac-proxy
и последующего сбора метрик с помощью Prometheus, выполните следующие шаги:
-
Создайте
ServiceAccount
с указанными ниже правами:--- apiVersion: v1 kind: ServiceAccount metadata: name: rbac-proxy-test --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: rbac-proxy-test roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: d8:rbac-proxy subjects: - kind: ServiceAccount name: rbac-proxy-test namespace: default
Обратите внимание, что используется встроенная в Deckhouse ClusterRole
d8:rbac-proxy
. -
Создайте конфигурацию для
kube-rbac-proxy
:--- apiVersion: v1 kind: ConfigMap metadata: name: rbac-proxy-config-test namespace: rbac-proxy-test data: config-file.yaml: |+ authorization: resourceAttributes: namespace: default apiVersion: v1 resource: services subresource: proxy name: rbac-proxy-test
Более подробную информацию по атрибутам можно найти в документации Kubernetes.
-
Создайте
Service
иDeployment
для вашего приложения, гдеkube-rbac-proxy
займет позицию sidecar-контейнера:--- apiVersion: v1 kind: Service metadata: name: rbac-proxy-test labels: prometheus.deckhouse.io/custom-target: rbac-proxy-test spec: ports: - name: https-metrics port: 8443 targetPort: https-metrics selector: app: rbac-proxy-test --- apiVersion: apps/v1 kind: Deployment metadata: name: rbac-proxy-test spec: replicas: 1 selector: matchLabels: app: rbac-proxy-test template: metadata: labels: app: rbac-proxy-test spec: securityContext: runAsUser: 65532 serviceAccountName: rbac-proxy-test containers: - name: kube-rbac-proxy image: quay.io/brancz/kube-rbac-proxy:v0.14.0 args: - "--secure-listen-address=0.0.0.0:8443" - "--upstream=http://127.0.0.1:8081/" - "--config-file=/kube-rbac-proxy/config-file.yaml" - "--logtostderr=true" - "--v=10" ports: - containerPort: 8443 name: https-metrics volumeMounts: - name: config mountPath: /kube-rbac-proxy - name: prometheus-example-app image: quay.io/brancz/prometheus-example-app:v0.1.0 args: - "--bind=127.0.0.1:8081" volumes: - name: config configMap: name: rbac-proxy-config-test
-
Назначьте необходимые права на ресурс для Prometheus:
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: rbac-proxy-test-client rules: - apiGroups: [""] resources: ["services/proxy"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: rbac-proxy-test-client roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: rbac-proxy-test-client subjects: - kind: ServiceAccount name: prometheus namespace: d8-monitoring
После шага 4 метрики вашего приложения должны появиться в Prometheus.
Пример безопасного сбора метрик с приложения, расположенного вне кластера
Предположим, что есть доступный через интернет сервер, на котором работает node-exporter
. По умолчанию node-exporter
слушает на порту 9100
и доступен на всех интерфейсах. Необходимо обеспечить контроль доступа к node-exporter
для безопасного сбора метрик. Ниже приведен пример такой настройки.
Требования:
- Из кластера должен быть доступ к сервису
kube-rbac-proxy
, который запущен на удаленном сервере. - От удаленного сервера должен быть доступ к API-серверу кластера.
Выполните следующие шаги:
-
Создайте
ServiceAccount
с указанными ниже правами:--- apiVersion: v1 kind: ServiceAccount metadata: name: prometheus-external-endpoint-server-01 namespace: d8-service-accounts --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus-external-endpoint rules: - apiGroups: ["authentication.k8s.io"] resources: - tokenreviews verbs: ["create"] - apiGroups: ["authorization.k8s.io"] resources: - subjectaccessreviews verbs: ["create"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-external-endpoint-server-01 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus-external-endpoint subjects: - kind: ServiceAccount name: prometheus-external-endpoint-server-01 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
на удаленном сервере:docker 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 \ --upstream=http://127.0.0.1:9100 --kubeconfig=/config --logtostderr=true --v=10
-
Проверьте, что порт
8443
доступен по внешнему адресу удаленного сервера. -
Создайте в кластере
Service
иEndpoint
, указав в качестве<server_ip_address>
внешний адрес удаленного сервера:--- apiVersion: v1 kind: Service metadata: name: prometheus-external-endpoint-server-01 labels: prometheus.deckhouse.io/custom-target: prometheus-external-endpoint-server-01 spec: ports: - name: https-metrics port: 8443 --- apiVersion: v1 kind: Endpoints metadata: name: prometheus-external-endpoint-server-01 subsets: - addresses: - ip: <server_ip_address> ports: - name: https-metrics port: 8443
Как добавить Alertmanager?
Создайте кастомный ресурс CustomAlertmanager
с типом Internal
.
Пример:
apiVersion: deckhouse.io/v1alpha1
kind: CustomAlertmanager
metadata:
name: webhook
spec:
type: Internal
internal:
route:
groupBy: ['job']
groupWait: 30s
groupInterval: 5m
repeatInterval: 12h
receiver: 'webhook'
receivers:
- name: 'webhook'
webhookConfigs:
- url: 'http://webhookserver:8080/'
Подробно о всех параметрах можно прочитать в описании кастомного ресурса CustomAlertmanager.
Как добавить внешний дополнительный Alertmanager?
Создайте кастомный ресурс CustomAlertmanager
с типом External
, который может указывать на Alertmanager по FQDN или через сервис в Kubernetes-кластере.
Пример FQDN Alertmanager:
apiVersion: deckhouse.io/v1alpha1
kind: CustomAlertmanager
metadata:
name: my-fqdn-alertmanager
spec:
external:
address: https://alertmanager.mycompany.com/myprefix
type: External
Пример Alertmanager с Kubernetes service:
apiVersion: deckhouse.io/v1alpha1
kind: CustomAlertmanager
metadata:
name: my-service-alertmanager
spec:
external:
service:
namespace: myns
name: my-alertmanager
path: /myprefix/
type: External
Подробно о всех параметрах можно прочитать в описании кастомного ресурса CustomAlertmanager.
Как в Alertmanager игнорировать лишние алерты?
Решение сводится к настройке маршрутизации алертов в вашем Alertmanager.
Требования:
- Завести получателя без параметров.
- Смаршрутизировать лишние алерты в этого получателя.
Ниже приведены примеры настройки CustomAlertmanager
.
Чтобы получать только алерты с лейблами service: foo|bar|baz
:
receivers:
# Получатель, определенный без параметров, будет работать как "/dev/null".
- name: blackhole
# Действующий получатель
- name: some-other-receiver
# ...
route:
# receiver по умолчанию.
receiver: blackhole
routes:
# Дочерний маршрут
- matchers:
- matchType: =~
name: service
value: ^(foo|bar|baz)$
receiver: some-other-receiver
Чтобы получать все алерты, кроме DeadMansSwitch
:
receivers:
# Получатель, определенный без параметров, будет работать как "/dev/null".
- name: blackhole
# Действующий получатель.
- name: some-other-receiver
# ...
route:
# receiver по умолчанию.
receiver: some-other-receiver
routes:
# Дочерний маршрут.
- matchers:
- matchType: =
name: alertname
value: DeadMansSwitch
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"
.
Пример:
---
apiVersion: v1
kind: Namespace
metadata:
name: frontend
labels:
prometheus.deckhouse.io/monitor-watcher-enabled: "true"
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
namespace: frontend
labels:
prometheus: main
spec:
selector:
matchLabels:
app: example-app
endpoints:
- port: web
Как настроить Probe для работы с Prometheus?
Добавьте лейбл prometheus: main
к Probe.
Добавьте в пространство имён, в котором находится Probe, лейбл prometheus.deckhouse.io/probe-watcher-enabled: "true"
.
Пример:
---
apiVersion: v1
kind: Namespace
metadata:
name: frontend
labels:
prometheus.deckhouse.io/probe-watcher-enabled: "true"
---
apiVersion: monitoring.coreos.com/v1
kind: Probe
metadata:
labels:
app: prometheus
component: probes
prometheus: main
name: cdn-is-up
namespace: frontend
spec:
interval: 30s
jobName: httpGet
module: http_2xx
prober:
path: /probe
scheme: http
url: blackbox-exporter.blackbox-exporter.svc.cluster.local:9115
targets:
staticConfig:
static:
- https://example.com/status
Как настроить PrometheusRules для работы с Prometheus?
Добавьте в пространство имён, в котором находятся PrometheusRules, лейбл prometheus.deckhouse.io/rules-watcher-enabled: "true"
.
Пример:
---
apiVersion: v1
kind: Namespace
metadata:
name: frontend
labels:
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.
Выполните следующую команду для получения списка алертов в кластере:
kubectl get clusteralerts
Пример вывода:
NAME ALERT SEVERITY AGE LAST RECEIVED STATUS
086551aeee5b5b24 ExtendedMonitoringDeprecatatedAnnotation 4 3h25m 38s firing
226d35c886464d6e ExtendedMonitoringDeprecatatedAnnotation 4 3h25m 38s firing
235d4efba7df6af4 D8SnapshotControllerPodIsNotReady 8 5d4h 44s firing
27464763f0aa857c D8PrometheusOperatorPodIsNotReady 7 5d4h 43s firing
ab17837fffa5e440 DeadMansSwitch 4 5d4h 41s firing
Выполните следующую команду для просмотра конкретного алерта:
kubectl get clusteralerts <ALERT_NAME> -o yaml
Пример:
# kubectl get clusteralerts 235d4efba7df6af4 -o yaml
alert:
description: |
The recommended course of action:
1. Retrieve details of the Deployment: `kubectl -n d8-snapshot-controller describe deploy snapshot-controller`
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`
labels:
pod: snapshot-controller-75bd776d76-xhb2c
prometheus: deckhouse
tier: cluster
name: D8SnapshotControllerPodIsNotReady
severityLevel: "8"
summary: The snapshot-controller Pod is NOT Ready.
apiVersion: deckhouse.io/v1alpha1
kind: ClusterAlert
metadata:
creationTimestamp: "2023-05-15T14:24:08Z"
generation: 1
labels:
app: prometheus
heritage: deckhouse
name: 235d4efba7df6af4
resourceVersion: "36262598"
uid: 817f83e4-d01a-4572-8659-0c0a7b6ca9e7
status:
alertStatus: firing
lastUpdateTime: "2023-05-15T18:10:09Z"
startsAt: "2023-05-10T13:43:09Z"
{% alert level=”info” %}
Присутствие специального алерта DeadMansSwitch
в кластере говорит о работоспособности Prometheus.
{% endalert %}
Как добавить дополнительные эндпоинты в scrape config?
Добавьте в пространство имён, в котором находится ScrapeConfig, лейбл prometheus.deckhouse.io/scrape-configs-watcher-enabled: "true"
.
Пример:
---
apiVersion: v1
kind: Namespace
metadata:
name: frontend
labels:
prometheus.deckhouse.io/scrape-configs-watcher-enabled: "true"
Добавьте ScrapeConfig, который имеет обязательный лейбл prometheus: main
:
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:
name: example-scrape-config
namespace: frontend
labels:
prometheus: main
spec:
honorLabels: true
staticConfigs:
- targets: ['example-app.frontend.svc.{{ .Values.global.discovery.clusterDomain }}.:8080']
relabelings:
- regex: endpoint|namespace|pod|service
action: labeldrop
- targetLabel: scrape_endpoint
replacement: main
- targetLabel: job
replacement: kube-state-metrics
metricsPath: '/metrics'