Настройка сбора телеметрии Nginx в Kubernetes
Вы настроите веб-сервер Nginx в кластере Kubernetes и передадите его метрики и логи в Monium. В инструкции для разворачивания кластера используется сервис Managed Service for Kubernetes, но вы можете использовать любой ваш кластер Kubernetes.
Чтобы настроить сбор телеметрии веб-сервера в кластере:
- Настройте кластер Kubernetes.
- Настройте аутентификацию — создайте сервисный аккаунт и API-ключ для отправки данных в Monium.
- Установите и настройте Nginx — разверните веб-сервер с экспортером метрик.
- Установите OpenTelemetry Collector — настройте сбор и отправку метрик.
- Просмотрите метрики в Monium.
- Настройте сбор логов.
- Просмотрите логи в Monium.
- Настройте дополнительные метрики по логам.
- Создайте дашборд и алерты.
Перед началом работы
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость ресурсов для работы с Monium входит:
- Плата за использование мастера Managed Service for Kubernetes — тарифы Managed Service for Kubernetes.
- Плата за вычислительные ресурсы и диски группы узлов Managed Service for Kubernetes — тарифы Yandex Compute Cloud.
- Плата за использование Monium — тарифы Monium.
Настройка кластера
-
Создайте кластер Kubernetes.
-
Установите kubectl
и настройте его на работу с созданным кластером.
Настройка аутентификации
На этом шаге вам нужно получить и сохранить API-ключ и идентификатор каталога, которые используются на шаге настройки OpenTelemetry Collector.
-
Создайте сервисный аккаунт с ролью
monium.telemetry.writer:- Перейдите в сервис Identity and Access Management.
- Нажмите кнопку Создать сервисный аккаунт.
- Введите имя сервисного аккаунта, например,
monium-ca. - Нажмите
Добавить роль и выберитеmonium.telemetry.writer. - Нажмите Создать.
-
Создайте API-ключ с областью действия
yc.monium.telemetry.write:- Выберите в списке созданный сервисный аккаунт.
- Нажмите кнопку
Создать новый ключ и выберите пункт Создать API-ключ. - В поле Область действия выберите
yc.monium.telemetry.write. - Нажмите кнопку Создать.
-
Скопируйте API-ключ и сохраните его в безопасном месте, он понадобится дальше.
-
Скопируйте идентификатор каталога, в котором создан кластер и сервисный аккаунт. Для этого вверху нажмите название каталога и в списке напротив нужного каталога нажмите
→ Копировать ID.
Установка и настройка Nginx
-
Создайте файл с конфигурацией веб-сервера и HTML-страницей Nginx:
configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config namespace: nginx-demo data: nginx.conf: | server { listen 80; root /usr/share/nginx/html; index index.html; ssi on; ssi_types text/html; ssi_last_modified on; location / { try_files $uri $uri/ =404; } location /nginx_status { stub_status; access_log off; allow 127.0.0.1; deny all; } } index.html: | <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Nginx Demo</title> <style> body { font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Arial,sans-serif; background:#0b1020; color:#e6edf3; margin:0; } .wrap { max-width: 900px; margin: 80px auto; padding: 0 20px; } .card { background:#111a33; border:1px solid rgba(255,255,255,.08); border-radius: 16px; padding: 28px; box-shadow: 0 10px 30px rgba(0,0,0,.35); } h1 { margin:0 0 10px; font-size: 28px; } p { margin: 8px 0; color:#b7c3d0; } code { background: rgba(255,255,255,.06); padding: 2px 6px; border-radius: 8px; } .ok { display:inline-block; margin-top:14px; padding:8px 12px; border-radius: 999px; background: rgba(56,189,248,.12); border:1px solid rgba(56,189,248,.35); color:#7dd3fc; } .grid { display:grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 18px; } .mini { background: rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.06); border-radius: 14px; padding: 14px; } .mini b { color:#e6edf3; } @media (max-width: 700px) { .grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="wrap"> <div class="card"> <h1>🚀 Nginx is serving this page</h1> <p>This is a simple demo page served from a Kubernetes pod.</p> <div class="ok">Status: OK</div> <div class="grid"> <div class="mini"> <p><b>Endpoint:</b> <code>/</code></p> <p>Static HTML from <code>/usr/share/nginx/html/index.html</code></p> </div> <div class="mini"> <p><b>Metrics:</b> <code>/metrics</code> (exporter)</p> <p>Nginx stub status: <code>/nginx_status</code> (localhost-only)</p> </div> </div> <!-- New grid section: runtime pod info --> <div class="grid" style="margin-top:18px;"> <div class="mini"> <p><b>Pod (hostname):</b></p> <p><code><!--# echo var="hostname" --></code></p> </div> <div class="mini"> <p><b>Pod IP:</b></p> <p><code><!--# echo var="server_addr" --></code></p> </div> <div class="mini"> <p><b>Client IP:</b></p> <p><code><!--# echo var="remote_addr" --></code></p> </div> <div class="mini"> <p><b>Request time:</b></p> <p><code><!--# echo var="time_local" --></code></p> </div> </div> <p style="margin-top:18px;"> Refresh the page to see load balancing between pods. </p> <p style="margin-top:18px;"> If you see this page via LoadBalancer/Ingress — publishing works. </p> </div> </div> </body> </html> -
Создайте файл для управления запуском и масштабированием подов с Nginx.
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-server namespace: nginx-demo labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:stable ports: - name: http containerPort: 80 volumeMounts: - name: nginx-config mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf - name: nginx-config mountPath: /usr/share/nginx/html/index.html subPath: index.html - name: nginx-exporter image: nginx/nginx-prometheus-exporter:0.10.0 args: - -nginx.scrape-uri=http://localhost/nginx_status ports: - name: metrics containerPort: 9113 resources: limits: memory: 128Mi cpu: 500m volumes: - name: nginx-config configMap: name: nginx-configДля мониторинга Nginx в Kubernetes потребуется экспортер (nginx-exporter), который преобразует внутреннюю статистику Nginx в формат для OpenTelemetry Collector.
В файле
deployment.yamlэкспортер добавлен в виде сайдкара:- name: nginx-exporter image: nginx/nginx-prometheus-exporter:0.10.0 args: - -nginx.scrape-uri=http://localhost/nginx_status ports: - name: metrics containerPort: 9113 resources: limits: memory: 128Mi cpu: 500mКаждый под приложения Nginx будет содержать в себе два контейнера:
nginxиnginx-exporter. -
Создайте файл с параметрами доступа к Nginx:
services.yaml
apiVersion: v1 kind: Service metadata: name: nginx-web namespace: nginx-demo labels: app: nginx spec: externalTrafficPolicy: Local type: LoadBalancer selector: app: nginx ports: - name: http port: 80 targetPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-metrics namespace: nginx-demo labels: app: nginx spec: selector: app: nginx ports: - name: metrics port: 9113 targetPort: metrics -
Разверните Nginx:
kubectl create namespace nginx-demo kubectl apply -f configmap.yaml kubectl apply -f deployment.yaml kubectl apply -f services.yaml -
Проверьте, что приложение запустилось:
kubectl get service -n nginx-demo nginx-webРезультат:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-web LoadBalancer 10.96.238.139 158.260.329.4 80:32761/TCP 104s -
Откройте в браузере адрес, указанный в столбце
EXTERNAL-IP. Например:http://158.260.329.4. Должна быть показана HTML-страница из файлаconfigmap.yaml.Страница веб-сервера Nginx

Установка и настройка OpenTelemetry Collector
На этом шаге вы установите OpenTelemetry Collector Contrib
-
Создайте файл для установки OpenTelemetry Collector и отправки метрик в Monium:
otel-config.yaml
--- apiVersion: v1 kind: Secret metadata: name: monium-secrets namespace: nginx-demo stringData: MONIUM_API_KEY: '<API-ключ>' --- apiVersion: v1 kind: ConfigMap metadata: name: otel-collector-conf namespace: nginx-demo labels: app: opentelemetry component: otel-collector-conf data: otel-collector-config: | receivers: prometheus: config: scrape_configs: - job_name: "nginx" scrape_interval: 15s kubernetes_sd_configs: - role: pod namespaces: names: - nginx-demo relabel_configs: - source_labels: [__meta_kubernetes_namespace] action: keep regex: nginx-demo - source_labels: [__meta_kubernetes_pod_label_app] action: keep regex: nginx - source_labels: [__meta_kubernetes_pod_container_port_name] action: keep regex: metrics - source_labels: [__meta_kubernetes_pod_name] target_label: pod - source_labels: [__meta_kubernetes_namespace] target_label: namespace processors: batch: timeout: 5s send_batch_size: 1024 memory_limiter: limit_mib: 1500 spike_limit_mib: 512 check_interval: 5s resource: attributes: - key: service.name value: nginx action: upsert - key: service.namespace value: nginx-demo action: upsert exporters: otlp/monium: compression: none endpoint: ingest.monium.yandex.cloud:443 headers: Authorization: Api-Key ${env:MONIUM_API_KEY} x-monium-project: folder__<идентификатор_каталога> debug: verbosity: basic extensions: zpages: {} service: extensions: [zpages] pipelines: metrics: receivers: [prometheus] processors: [memory_limiter, resource, batch] exporters: [otlp/monium, debug] --- apiVersion: v1 kind: Service metadata: name: otel-collector namespace: nginx-demo labels: app: opentelemetry component: otel-collector spec: ports: - name: otlp-grpc port: 4317 protocol: TCP targetPort: 4317 - name: otlp-http port: 4318 protocol: TCP targetPort: 4318 - name: metrics port: 8888 selector: component: otel-collector --- apiVersion: apps/v1 kind: Deployment metadata: name: otel-collector namespace: nginx-demo labels: app: opentelemetry component: otel-collector spec: selector: matchLabels: app: opentelemetry component: otel-collector replicas: 1 template: metadata: labels: app: opentelemetry component: otel-collector spec: serviceAccountName: otel-collector containers: - command: - "/otelcol-contrib" - "--config=/conf/otel-collector-config.yaml" image: otel/opentelemetry-collector-contrib:latest name: otel-collector resources: limits: cpu: 1 memory: 2Gi requests: cpu: 200m memory: 400Mi ports: - containerPort: 55679 - containerPort: 4317 - containerPort: 4318 - containerPort: 8888 env: - name: MY_POD_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.podIP - name: GOMEMLIMIT value: 1600MiB - name: MONIUM_API_KEY valueFrom: secretKeyRef: name: monium-secrets key: MONIUM_API_KEY volumeMounts: - name: otel-collector-config-vol mountPath: /conf volumes: - name: otel-collector-config-vol configMap: name: otel-collector-conf items: - key: otel-collector-config path: otel-collector-config.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: otel-collector namespace: nginx-demo --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: otel-collector-discovery namespace: nginx-demo rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: otel-collector-discovery namespace: nginx-demo subjects: - kind: ServiceAccount name: otel-collector namespace: nginx-demo roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: otel-collector-discoveryВ этом файле подставьте свои значения
<API-ключ>и<идентификатор_каталога>, сохраненные на шаге Настройка аутентификации. -
Установите OTel Collector и начните отправку метрик:
kubectl apply -f otel-config.yaml -
Проверьте, что появился новый под
otel-collector:kubectl get pods --namespace nginx-demoРезультат:
NAME READY STATUS RESTARTS AGE nginx-server-949d9f98b-kzlrd 2/2 Running 0 2d2h nginx-server-949d9f98b-ngtsp 2/2 Running 0 2d2h nginx-server-949d9f98b-tclvh 2/2 Running 0 2d2h otel-collector-6cd848c59d-k6g2p 1/1 Running 0 12s
Просмотр метрик в Monium
-
На главной странице Monium
слева выберите Метрики. -
В строке запроса последовательно выберите:
project=folder__<идентификатор_каталога>;cluster=default;service=nginx;name=nginx_up.
Для запроса можно использовать текстовый режим. Для этого нажмите кнопку
и введите запрос текстом:`project=folder__<идентификатор_каталога>; cluster=default; service=nginx; name=nginx_up`.Метрика показывает статус доступности Nginx:
1— доступен,0— недоступен. Агрегированное значение равно3по количеству подов. -
Нажмите Выполнить запрос.
Подробнее о работе с метриками.
Если данные не появились в Monium, см. раздел Устранение неполадок при поставке данных.
Комбинируя различные метрики в запросах, вы можете определять, справляется ли веб-сервер с текущей нагрузкой, есть ли отброшенные соединения из-за нехватки ресурсов, как быстро обрабатываются запросы.
Количество активных соединений
Чтобы оценить количество активных соединений, для метрики name укажите значение:
nginx_connections_accepted— количество принятых соединений с момента запуска Nginx. Используется для отслеживания общей нагрузки.nginx_connections_reading— количество соединений, из которых Nginx читает запросы клиентов. Показывает активность входящих запросов.nginx_connections_writing— количество соединений, в которые Nginx отправляет ответы клиентам. Показывает активность исходящих ответов.
Количество необработанных соединений
Чтобы оценить количество соединений, которые Nginx не обрабатывает, используются метрики:
nginx_connections_accepted— количество принятых соединений.nginx_connections_handled— количество обработанных соединений.
Разница между обработанными и принятыми соединениями покажет количество соединений, которые были приняты, но не были корректно обработаны Nginx.
Создайте три запроса: Запрос A — для метрики nginx_connections_accepted, Запрос B — для метрики nginx_connections_handled, Запрос C — для вычисления разницы между метриками. Чтобы создать дополнительный запрос, нажмите кнопку Добавить запрос.
-
Запрос A:
`project=folder__<идентификатор_каталога>; cluster=default; service=nginx; name=nginx_connections_accepted`. -
Запрос B:
`project=folder__<идентификатор_каталога>; cluster=default; service=nginx; name=nginx_connections_handled`. -
Запрос C: в строке запроса введите
A - B.
График необработанных запросов

Чтобы отображать на графике только результирующий запрос, рядом с запросами A и B нажмите
В тестовом примере необработанных соединений нет, поэтому в запросе C все значения нулевые. Для реальных систем эти значения удобно отображать в виде отношения (A - B) / A — доля соединений, которые Nginx принял, но не обработал. На этот показатель можно завести алерт, который будет уведомлять, например, когда доля отброшенных соединений больше 5%.
Настройка сбора логов
-
Создайте новый файл конфигурации для сбора логов:
otel-config-logs.yaml
--- apiVersion: v1 kind: Secret metadata: name: monium-secrets namespace: nginx-demo stringData: MONIUM_API_KEY: '<API_ключ>' --- apiVersion: v1 kind: ConfigMap metadata: name: otel-collector-conf namespace: nginx-demo labels: app: opentelemetry component: otel-collector-conf data: otel-collector-config: | receivers: prometheus: config: scrape_configs: - job_name: "nginx" scrape_interval: 15s kubernetes_sd_configs: - role: pod namespaces: names: - nginx-demo relabel_configs: - source_labels: [__meta_kubernetes_namespace] action: keep regex: nginx-demo - source_labels: [__meta_kubernetes_pod_label_app] action: keep regex: nginx - source_labels: [__meta_kubernetes_pod_container_port_name] action: keep regex: metrics - source_labels: [__meta_kubernetes_pod_name] target_label: pod - source_labels: [__meta_kubernetes_namespace] target_label: namespace filelog: include: - /var/log/pods/nginx-demo_nginx-server-*/nginx/*.log operators: - type: container id: container-parser processors: batch: timeout: 5s send_batch_size: 1024 memory_limiter: limit_mib: 1500 spike_limit_mib: 512 check_interval: 5s resource: attributes: - key: service.name value: nginx action: upsert - key: service.namespace value: nginx-demo action: upsert exporters: otlp/monium: compression: none endpoint: ingest.monium.yandex.cloud:443 headers: Authorization: Api-Key ${env:MONIUM_API_KEY} x-monium-project: folder__<идентификатор_каталога> debug: verbosity: basic extensions: zpages: {} service: extensions: [zpages] pipelines: metrics: receivers: [prometheus] processors: [memory_limiter, resource, batch] exporters: [otlp/monium, debug] logs: receivers: [filelog] processors: [memory_limiter, resource, batch] exporters: [otlp/monium, debug] --- apiVersion: v1 kind: Service metadata: name: otel-collector namespace: nginx-demo labels: app: opentelemetry component: otel-collector spec: ports: - name: otlp-grpc port: 4317 protocol: TCP targetPort: 4317 - name: otlp-http port: 4318 protocol: TCP targetPort: 4318 - name: metrics port: 8888 selector: component: otel-collector --- apiVersion: apps/v1 kind: DaemonSet metadata: name: otel-collector namespace: nginx-demo labels: app: opentelemetry component: otel-collector spec: selector: matchLabels: app: opentelemetry component: otel-collector template: metadata: labels: app: opentelemetry component: otel-collector spec: serviceAccountName: otel-collector containers: - command: - "/otelcol-contrib" - "--config=/conf/otel-collector-config.yaml" image: otel/opentelemetry-collector-contrib:latest name: otel-collector resources: limits: cpu: 1 memory: 2Gi requests: cpu: 200m memory: 400Mi ports: - containerPort: 55679 - containerPort: 4317 - containerPort: 4318 - containerPort: 8888 env: - name: MY_POD_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.podIP - name: GOMEMLIMIT value: 1600MiB - name: MONIUM_API_KEY valueFrom: secretKeyRef: name: monium-secrets key: MONIUM_API_KEY volumeMounts: - name: otel-collector-config-vol mountPath: /conf - name: varlogpods mountPath: /var/log/pods readOnly: true volumes: - name: otel-collector-config-vol configMap: name: otel-collector-conf items: - key: otel-collector-config path: otel-collector-config.yaml - name: varlogpods hostPath: path: /var/log/pods --- apiVersion: v1 kind: ServiceAccount metadata: name: otel-collector namespace: nginx-demo --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: otel-collector-discovery namespace: nginx-demo rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: otel-collector-discovery namespace: nginx-demo subjects: - kind: ServiceAccount name: otel-collector namespace: nginx-demo roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: otel-collector-discoveryВ этом файле добавлен блок с ресивером:
filelog: include: - /var/log/pods/nginx-demo_nginx-server-*/nginx/*.log operators: - type: container id: container-parserА также маршрут (
pipeline) для сбора логов и параметры монтирования (volumeMounts,volumes) для доступа к логам подов. -
Удалите прежний файл конфигурации и примените новый:
kubectl delete -f otel-config.yaml kubectl apply -f otel-config-logs.yaml
Просмотр логов в Monium
-
На главной странице Monium
слева выберите Логи. -
В строке запроса выберите:
project=folder__<идентификатор_каталога>;service=nginx.
-
Нажмите Выполнить запрос.
Пример страницы с логами Nginx

Подробнее о работе с логами.
Настройка сбора метрик из логов
Помимо стандартных метрик, которые Nginx отправляет через экспортер Prometheus, OTel Collector позволяет извлекать дополнительные метрики из логов приложения. Например, подсчитывать количество HTTP-ответов с разными кодами статуса.
Для получения этих метрик создайте и примените новый файл конфигурации:
otel-config-metrics.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: monium-secrets
namespace: nginx-demo
stringData:
MONIUM_API_KEY: "<API_ключ>"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-conf
namespace: nginx-demo
labels:
app: opentelemetry
component: otel-collector-conf
data:
otel-collector-config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: "nginx"
scrape_interval: 15s
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- nginx-demo
relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
action: keep
regex: nginx-demo
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: nginx
- source_labels: [__meta_kubernetes_pod_container_port_name]
action: keep
regex: metrics
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
filelog:
include:
- /var/log/pods/nginx-demo_nginx-server-*/nginx/*.log
operators:
- type: container
id: container-parser
- type: regex_parser
id: nginx-access
parse_from: body
regex: '^(?P<remote_addr>\S+) - (?P<remote_user>\S+) \[(?P<time_local>[^\]]+)\] "(?P<method>\S+) (?P<target>\S+) (?P<protocol>[^"]+)" (?P<status>\d{3}) (?P<body_bytes_sent>\d+)'
processors:
batch:
timeout: 5s
send_batch_size: 1024
memory_limiter:
limit_mib: 1500
spike_limit_mib: 512
check_interval: 5s
resource:
attributes:
- key: service.name
value: nginx
action: upsert
- key: service.namespace
value: nginx-demo
action: upsert
connectors:
count/nginx:
logs:
nginx_http_2xx_total:
description: nginx 2xx responses
conditions:
- 'IsMatch(attributes["status"], "^2..$")'
nginx_http_4xx_total:
description: nginx 4xx responses
conditions:
- 'IsMatch(attributes["status"], "^4..$")'
nginx_http_5xx_total:
description: nginx 5xx responses
conditions:
- 'IsMatch(attributes["status"], "^5..$")'
exporters:
otlp/monium:
compression: none
endpoint: ingest.monium.yandex.cloud:443
headers:
Authorization: Api-Key ${env:MONIUM_API_KEY}
x-monium-project: folder__<идентификатор_каталога>
debug:
verbosity: basic
extensions:
zpages: {}
service:
extensions: [zpages]
pipelines:
metrics:
receivers: [prometheus]
processors: [memory_limiter, resource, batch]
exporters: [otlp/monium, debug]
logs:
receivers: [filelog]
processors: [memory_limiter, resource, batch]
exporters: [count/nginx, otlp/monium, debug]
metrics/logs:
receivers: [count/nginx]
processors: [memory_limiter, resource, batch]
exporters: [otlp/monium, debug]
---
apiVersion: v1
kind: Service
metadata:
name: otel-collector
namespace: nginx-demo
labels:
app: opentelemetry
component: otel-collector
spec:
ports:
- name: otlp-grpc
port: 4317
protocol: TCP
targetPort: 4317
- name: otlp-http
port: 4318
protocol: TCP
targetPort: 4318
- name: metrics
port: 8888
selector:
component: otel-collector
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector
namespace: nginx-demo
labels:
app: opentelemetry
component: otel-collector
spec:
selector:
matchLabels:
app: opentelemetry
component: otel-collector
template:
metadata:
labels:
app: opentelemetry
component: otel-collector
spec:
serviceAccountName: otel-collector
containers:
- command:
- "/otelcol-contrib"
- "--config=/conf/otel-collector-config.yaml"
image: otel/opentelemetry-collector-contrib:0.147.0
name: otel-collector
resources:
limits:
cpu: 1
memory: 2Gi
requests:
cpu: 200m
memory: 400Mi
ports:
- containerPort: 55679
- containerPort: 4317
- containerPort: 4318
- containerPort: 8888
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: GOMEMLIMIT
value: 1600MiB
- name: MONIUM_API_KEY
valueFrom:
secretKeyRef:
name: monium-secrets
key: MONIUM_API_KEY
volumeMounts:
- name: otel-collector-config-vol
mountPath: /conf
- name: varlogpods
mountPath: /var/log/pods
readOnly: true
volumes:
- name: otel-collector-config-vol
configMap:
name: otel-collector-conf
items:
- key: otel-collector-config
path: otel-collector-config.yaml
- name: varlogpods
hostPath:
path: /var/log/pods
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: otel-collector
namespace: nginx-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: otel-collector-discovery
namespace: nginx-demo
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: otel-collector-discovery
namespace: nginx-demo
subjects:
- kind: ServiceAccount
name: otel-collector
namespace: nginx-demo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: otel-collector-discovery
В этой конфигурации есть следующие дополнения:
-
Извлечение данных из логов.
В блок
filelogдобавлен операторregex_parser, который будет извлекать из строки access-лога Nginx нужные поля (метод запроса, URL, HTTP-код ответа и другие):filelog: include: - /var/log/pods/nginx-demo_nginx-server-*/nginx/*.log operators: - type: container id: container-parser - type: regex_parser id: nginx-access parse_from: body regex: '^(?P<remote_addr>\S+) - (?P<remote_user>\S+) \[(?P<time_local>[^\]]+)\] "(?P<method>\S+) (?P<target>\S+) (?P<protocol>[^"]+)" (?P<status>\d{3}) (?P<body_bytes_sent>\d+)'Этот оператор извлечет из каждой строки лога поле
status(HTTP-код ответа), которое будем использовать для создания метрик. -
Создание метрик из логов.
Добавлен коннектор
countдля подсчета количества записей в логах по заданным условиям. В примере подсчитываются ответы с кодами2xx,4xxи5xx:connectors: count/nginx: logs: nginx_http_2xx_total: description: Количество успешных ответов (2xx) conditions: - 'IsMatch(attributes["status"], "^2..$")' nginx_http_4xx_total: description: Количество клиентских ошибок (4xx) conditions: - 'IsMatch(attributes["status"], "^4..$")' nginx_http_5xx_total: description: Количество серверных ошибок (5xx) conditions: - 'IsMatch(attributes["status"], "^5..$")' -
Настройка маршрутов (pipelines).
Добавлен pipeline
metrics/logs, который будет получать метрики от коннектораcount/nginxи отправлять их в Monium вместе с остальными метриками:service: extensions: [zpages] pipelines: metrics: receivers: [prometheus] processors: [memory_limiter, resource, batch] exporters: [otlp/monium, debug] logs: receivers: [filelog] processors: [memory_limiter, resource, batch] exporters: [count/nginx, otlp/monium, debug] metrics/logs: receivers: [count/nginx] processors: [memory_limiter, resource, batch] exporters: [otlp/monium, debug]
После применения конфигурации в Monium будут доступны новые метрики:
nginx_http_2xx_total— количество успешных ответов.nginx_http_4xx_total— количество клиентских ошибок.nginx_http_5xx_total— количество серверных ошибок.
Пример страницы с метриками Nginx, собранным по логам

Эти метрики полезны для мониторинга качества обслуживания и выявления проблем. Например, резкий рост 5xx ошибок может указывать на сбой в приложении.
Создание дашборда и алертов
Для постоянного мониторинга состояния Nginx создайте дашборд с ключевыми метриками и настройте алерты для оповещения о проблемах.
Для Nginx рекомендуется добавить на дашборд графики с метриками:
nginx_connections_accepted— количество принятых соединений с момента запуска.nginx_connections_active— количество активных соединений в данный момент.nginx_connections_handled— количество обработанных соединений.nginx_connections_reading— количество соединений, из которых Nginx читает запросы.nginx_connections_waiting— количество соединений в режиме ожидания.nginx_connections_writing— количество соединений, в которые Nginx отправляет ответы.nginx_requests_total— общее количество обработанных запросов.nginx_http_2xx_total— количество успешных ответов (код 2xx).nginx_http_4xx_total— количество клиентских ошибок (код 4xx).nginx_http_5xx_total— количество серверных ошибок (код 5xx).
Для уведомления о критических ситуациях рекомендуются алерты:
-
Рост серверных ошибок — увеличение
nginx_http_5xx_total.Условие срабатывания: значение больше
10в течение пяти минут. -
Рост клиентских ошибок — увеличение
nginx_http_4xx_total.Условие срабатывания: значение больше
50в течение пяти минут. -
Необработанные соединения — разница между принятыми и обработанными соединениями.
Условие срабатывания: значение больше
0в течение пяти минут.
Пороговые значения и временные интервалы настраивайте в соответствии с требованиями вашего приложения.