School

← To the program

Зачем наблюдаемость: сигналы, мониторинг и observability

Lesson from the course “Курс подготовки DevOps-инженеров”

Хронометраж: занятие 60 минут — теория 30 минут, практика 30 минут. Домашняя работа: 1–2 часа.

Кратко о чём урок: Метрики, логи, трассировки, профили — что каким вопросам отвечает; разница между «известными» проверками и исследованием неизвестной проблемы; стоимость наблюдаемости и что мониторить в первую очередь. observability, золотые сигналы, и что наше приложение уже излучает, а чего ему не хватает.


1. Что изучаем

После урока вы сможете:

  • различать три сигнала наблюдаемости — метрики, логи, трейсы — и понимать, на какой вопрос отвечает каждый;
  • объяснять разницу между мониторингом (известные вопросы) и observability (новые вопросы);
  • называть золотые сигналы и понимать, зачем именно они;
  • определять по приложению, что оно уже излучает, а что нужно добавить;
  • видеть план блока: как из «сервис жив/мёртв» вырасти до «почему он медленный и где именно».

2. Зачем это нужно и где применяется

Kubernetes из блоков 13–14 отвечает на вопрос «работает ли под» (пробы, 13.10) и сам чинит упавшее. Но когда сервис работает и при этом медленный, или ошибается на части запросов, или тормозит из-за соседа по узлу — оркестратор об этом молчит. Ответы на такие вопросы даёт наблюдаемость. Это фундамент эксплуатации: без неё авария разбирается наугад, а SLO (16.10) невозможно ни измерить, ни защитить.

Ситуации, из-за которых существует этот урок и весь блок:

  • «Сервис "зелёный", а пользователи жалуются на тормоза» — нужны метрики задержки;
  • «Упал один запрос из тысячи — какой и почему?» — нужны логи и трейсы;
  • «Запрос идёт через пять сервисов, где потерялось время?» — нужна распределённая трассировка;
  • «Дашбордов сто, а на вопрос в аварии ни один не отвечает» — разница мониторинга и observability;
  • «Что вообще мерить в первую очередь?» — золотые сигналы.

3. Теория (30 минут)

Файлы для работы: blocks/16-observability/examples/16.01-observability-concepts/

Стенд: kind (kindest/node:v1.37.0) из блоков 13–14 плюс учебное приложение course-k8s-app:1. Урок обзорный: он не ставит стек наблюдаемости (это уроки 16.02+), а показывает на приложении, какие сигналы уже есть, а каких нет. Воспроизведение — lab-signals.sh.

3.1. Три сигнала: метрики, логи, трейсы

Наблюдаемость стоит на трёх видах телеметрии, и каждый отвечает на свой вопрос:

  • метрики — числа во времени: сколько запросов, какая задержка, сколько ошибок, насколько занята память. Дёшевы в хранении, годятся для дашбордов и алертов, но агрегированы: по метрике видно что происходит, но не с каким именно запросом;
  • логи — записи о событиях: «пришёл такой-то запрос», «вот такая ошибка». Подробны и конкретны, но их много и по ним трудно увидеть тенденцию;
  • трейсы — путь одного запроса через систему: где сколько времени заняло, через какие сервисы прошёл. Отвечают на вопрос «где именно медленно» там, где метрики показывают только «медленно в целом».

Ни один сигнал не заменяет другой: метрика говорит, что доля ошибок выросла; лог показывает, что это за ошибка; трейс — на каком шаге цепочки она возникла. Весь блок 16 — это по сути три инструмента под три сигнала: Prometheus для метрик (16.02–16.06), Loki/ELK для логов (16.07), OpenTelemetry с Jaeger/Tempo для трейсов (16.08).

У сигналов разная цена, и это определяет, как их применять. Метрики дёшевы: число во времени занимает мало места, поэтому их держат долго и по ним строят алерты — но у метрики есть кардинальность (число уникальных комбинаций меток), и если в метку положить, скажем, идентификатор пользователя, ряд взорвётся и хранилище не выдержит (это подробно в 16.02). Логи дороги по объёму: их пишут много, поэтому хранят недолго и структурируют, чтобы искать (16.07). Трейсы дороги по накладным расходам на каждый запрос, поэтому их обычно сэмплируют — сохраняют не все, а долю (16.08). Отсюда типичная связка: по дешёвым метрикам замечают проблему и поднимают алерт, по логам находят конкретную запись, по трейсу — место в цепочке; а чтобы переходить между ними, сигналы связывают общими идентификаторами (trace-id в логе, exemplar у метрики).

3.2. Мониторинг против observability

Эти слова часто путают, а разница практическая. Мониторинг — это заранее заданные проверки и дашборды: вы решаете, что измерять, и следите за известными показателями. Google SRE определяет его как «Collecting, processing, aggregating, and displaying real-time quantitative data about a system, such as query counts and types, error counts and types, processing times, and server lifetimes». Пробы из 13.10 — это мониторинг: заранее известный вопрос «жив ли под».

Observability — свойство системы, позволяющее задавать новые вопросы, которые вы не предусмотрели заранее. Определение OpenTelemetry: «Observability lets you understand a system from the outside by letting you ask questions about that system without knowing its inner workings». Разница в том, какие вопросы вы можете задать. Мониторинг отвечает на известные вопросы («загрузка ЦП выше 80 %?»); observability позволяет ответить на новые («почему именно эти запросы от этого клиента стали медленными после вчерашнего релиза?») — если система излучает достаточно сигналов. Отсюда практический вывод: сто дашбордов — это мониторинг; возможность в аварии докопаться до причины, которую никто не предвидел, — observability. Одно не заменяет другое: мониторинг ловит известные беды дёшево, а observability нужна тогда, когда беда новая.

Ещё одна частая путаница: «три сигнала» и observability — не одно и то же. Наличие метрик, логов и трейсов — это необходимое условие, а не сама observability: можно собирать все три сигнала и всё равно не мочь ответить на новый вопрос, если метрики без нужных меток, логи без структуры, а трейсы не доходят через все сервисы. Observability — это свойство ответить на непредвиденный вопрос, и три сигнала лишь дают материал для ответа. Поэтому весь блок — не «поставить три инструмента», а научиться излучать и связывать сигналы так, чтобы по ним можно было задавать вопросы, которых вы заранее не писали.

3.3. Золотые сигналы: с чего начинать

Мерить можно бесконечно, поэтому есть проверенная отправная точка — четыре золотых сигнала из книги Google SRE. Дословно:

  • Latency — «The time it takes to service a request» (время обслуживания запроса);
  • Traffic — «A measure of how much demand is being placed on your system» (сколько нагрузки);
  • Errors — «The rate of requests that fail, either explicitly (e.g., HTTP 500s), implicitly …, or by policy» (доля неуспешных запросов);
  • Saturation — «How "full" your service is» (насколько сервис заполнен).

Смысл в том, что эти четыре величины покрывают большинство пользовательских проблем: если latency, трафик, ошибки и насыщение в норме — снаружи сервис почти наверняка здоров. Родственные сокращения пришли, потому что золотые сигналы удобно применять с двух сторон. RED — Rate (частота запросов), Errors (доля ошибок), Duration (задержка) — смотрит на сервис со стороны запроса: как его видит пользователь. USE — Utilization (загрузка), Saturation (насыщение, длина очереди), Errors — смотрит на ресурс (ЦП, память, диск, сеть): не упёрлись ли мы в предел. Они дополняют друг друга: RED говорит, что пользователю плохо, USE — не потому ли, что кончился какой-то ресурс. Практический порядок: сначала завести RED на каждый сервис и USE на каждый ресурс, и только потом добавлять специфические метрики под конкретные вопросы.

Начинают с золотых сигналов, а не с «померяем всё», по той же причине, по которой дашборд на сто графиков бесполезен в аварии: избыток показателей не ускоряет поиск причины, а замедляет его, потому что внимание тонет (16.05). Четыре золотых сигнала — это минимальный набор, который отвечает на вопрос «плохо ли пользователю», а всё остальное добавляют, когда появился конкретный вопрос, на который эти четыре не отвечают.

3.4. Что наше приложение излучает сейчас

Проверено на course-k8s-app:1 (тот же, что весь блок 13): приложение уже даёт логи и пробы, но не даёт метрик и трейсов. В логах видно каждое событие:

версия v1 слушает порт 8080 (готовность через 0 с, доля ошибок 0.00)
запрос "GET /health HTTP/1.1" 200 -
запрос "GET /config HTTP/1.1" 200 -
проба ready объявлена сломанной

То есть сигнал «логи» уже есть — приложение пишет в stdout, а Kubernetes отдаёт это через kubectl logs. Есть и пробы /health и /ready — это мониторинг «жив/готов». А вот метрик нет, и здесь важная тонкость, которую легко пропустить: GET /metrics возвращает 200 — но не потому, что метрики есть, а потому что у приложения общий обработчик отвечает на любой неизвестный путь. Тело ответа — обычный JSON приложения:

$ GET /metrics  →  200
{"host": "app-5d8d8c76df-nl8n6", "version": "v1", "uptime": 270.5}

Это не формат Prometheus (# HELP, # TYPE, имя_метрики значение), и Prometheus, придя на этот адрес, не нашёл бы ни одной метрики. Слов prometheus, metric, trace в исходнике нет вовсе. Значит нет ни метрик (сколько запросов, какая задержка, какова доля ошибок во времени), ни трассировки. Отсюда общий урок, знакомый по всему курсу: код 200 не доказывает, что там нужное — проверять надо содержимое (формат метрик), а не факт ответа. По логам можно постфактум найти конкретную ошибку, но нельзя построить график доли ошибок или задержки — а именно это нужно для золотых сигналов и SLO.

Отсюда план блока как заполнение пробелов: метрики приложению добавляют инструментированием (16.04) и собирают Prometheus (16.02), спрашивают PromQL (16.03), рисуют в Grafana (16.05) и превращают в алерты (16.06); логи структурируют и собирают (16.07); трейсы добавляют через OpenTelemetry (16.08); всё это сводят в кластере (16.09) и привязывают к SLO (16.10). Урок 16.01 фиксирует стартовую точку: «жив/мёртв» у нас есть, «почему медленно и где именно» — ещё нет.

3.5. Сводка: что показали замеры

Утверждение Что показал замер / первоисточник
«мониторинг и observability — одно» мониторинг — известные вопросы (SRE), observability — новые (OTel)
«метрик, логов, трейсов — по вкусу» это три разных сигнала на три разных вопроса, не заменяют друг друга
«мерить надо всё» начинают с четырёх золотых сигналов (SRE): latency, traffic, errors, saturation
«раз есть логи — есть наблюдаемость» у приложения есть логи и пробы, но нет метрик и трейсов
«/metrics ответил 200 — метрики есть» тело — обычный JSON, не формат Prometheus; собирать нечего
«Kubernetes сам всё покажет» оркестратор знает «жив/мёртв» (пробы), но не «медленно/почему»

3.6. Примеры и варианты реализации

Один вопрос — «какие сигналы у меня есть и каких не хватает» — в трёх средах.

Среда Как решается Что нужно иметь
Локальный стенд (kind) посмотреть логи и пробы приложения, увидеть отсутствие метрик/трейсов (пример урока) kind, приложение
VPS / bare-metal те же три сигнала; стек ставится вручную (Prometheus, Loki, Jaeger) серверы
Yandex Cloud часть сигналов даёт сервис (Monitoring, Cloud Logging), часть — свой стек каталог

Локальный стенд. Сигналы и их нехватку видно на приложении без всякого стека — этого достаточно для понимания, что и зачем добавлять дальше.

VPS / bare-metal. Три сигнала те же; разница в том, что весь стек наблюдаемости вы разворачиваете и обслуживаете сами (об этом весь блок).

Yandex Cloud. Облако даёт управляемый мониторинг и сбор логов, но модель та же — метрики, логи, трейсы; выбор между «своим» и «облачным» стеком не меняет, какие вопросы вы задаёте.

4. Практика на занятии (30 минут)

Курс проходят самостоятельно, поэтому каждый шаг говорит, что ввести, зачем, что должно получиться и что делать при неудаче.

Опыты — в 16.01-observability-concepts/. Стенд — kind (kindest/node:v1.37.0) с учебным приложением course-k8s-app:1: свой образ грузится в кластер kind load docker-image, а KUBECONFIG и кэш kubectl пишутся во временный каталог WORK, а не в ~/.kube владельца (14.11). Первый up тянет образ узла из сети — на медленном канале это займёт больше времени, чем указано в шаге. После занятия стенд убирается шагом 4.

Шаг 1 (10 минут). Поднять стенд и посмотреть логи.

  • Что ввести:
cd blocks/16-observability/examples/16.01-observability-concepts
export WORK=/tmp/lab1401-work   # свой путь; держите его в переменной до самого down
./lab-signals.sh up      # поднять kind + приложение
./lab-signals.sh logs    # вызвать запросы и посмотреть логи
  • Зачем: up поднимает однонодовый kind-кластер и разворачивает course-k8s-app:1; logs бьёт по нескольким маршрутам приложения и показывает, что оно пишет в stdout, — это и есть сигнал «логи». WORK нужно экспортировать один раз и не менять: каждый вызов lab-signals.sh — отдельный процесс, и без общей переменной окружения он создаст свой временный kubeconfig, а следующий вызов его не найдёт.
  • Ожидаемый результат: up заканчивается строкой стенд поднят; WORK=...; logs печатает === СИГНАЛ: ЛОГИ (kubectl logs) === и несколько строк вида запрос "GET /health HTTP/1.1" 200 - (пример полного вывода — в теории, раздел 3.4).
  • Если не так: ошибка kubectl про отсутствующий или пустой kubeconfig в logs значит, что WORK не был экспортирован до up — каждый вызов работал со своим временным каталогом; повторите оба вызова с export WORK=..., заданным заранее. Если up долго висит на rollout status — проверьте скорость скачивания образа узла, это не зависание.
  • Ответьте: какие события видно в логах? Что можно узнать по ним постфактум, а что нельзя?

Шаг 2 (10 минут). Чего не хватает.

  • Что ввести:
./lab-signals.sh gaps    # проверить формат /metrics и трассировки
  • Зачем: убедиться, что код 200 у /metrics не означает наличие метрик, и увидеть, что в образе нет ни слова prometheus/trace, ни заголовков traceparent — то есть трассировки тоже нет.
  • Ожидаемый результат: код: 200, тело: {"host": ..., "version": "v1", "uptime": ...} и строка формат Prometheus (# HELP/# TYPE): НЕТ; следом — пояснение, что в образе нет OpenTelemetry-агента и трейсов не будет.
  • Если не так: если WORK снова не тот, что при up, — та же ошибка kubeconfig, что в шаге 1. Если формат внезапно оказался ДА — проверьте, что в кластер загружен именно course-k8s-app:1 (kind load docker-image в up), а не образ с другого урока.
  • Ответьте: почему 200 здесь не значит «метрики есть»? Как по логам построить график доли ошибок за час — и почему это неудобно или невозможно?

Шаг 3 (5 минут). Мониторинг против observability.

  • Что ввести: команд нет — обсуждение по результатам шагов 1–2.
  • Зачем: закрепить разницу между заранее известным вопросом (отвечает проба) и новым вопросом, для которого сигналов пока не хватает.
  • Ожидаемый результат: сформулированный вопрос, на который не отвечает ни одна проба и ни один лог из шага 1 — именно такой вопрос и есть пример observability, а не мониторинга.
  • Если не так: если получившийся вопрос сводится к «жив или мёртв» — это снова мониторинг; нужен вопрос про конкретную, заранее не предусмотренную причину проблемы.
  • Ответьте: проба /ready отвечает «готов/не готов». Какой вопрос она закрывает, а какой — нет? Приведите вопрос, на который не ответить ни пробами, ни логами.

Шаг 4 (5 минут). Уборка.

  • Что ввести:
./lab-signals.sh down
  • Зачем: удалить kind-кластер, сеть kind и временный каталог WORK — иначе кластер и мусор в /tmp остаются после занятия.
  • Ожидаемый результат: строка убрано; kind get clusters больше не показывает l1401, docker network ls — без сети kind.
  • Если не так: если kind delete cluster жалуется на отсутствующий кластер — значит up не завершился успешно; проверьте docker ps -a на остатки узла, уберите вручную (kind delete cluster --name l1401, затем docker network rm kind).

Что обсудить в конце занятия. Сервис отвечает 200 на все пробы, но пользователи говорят «тормозит». С каким сигналом вы пойдёте разбираться и почему не с логами в первую очередь?

5. Домашняя работа (1–2 часа)

Задание. Составьте карту сигналов по заготовке signals-map.md: для учебного приложения (или своего сервиса) опишите, какие из трёх сигналов оно излучает сейчас, а какие нет; для каждого золотого сигнала укажите, можно ли его посчитать по тому, что есть; сформулируйте по одному вопросу, на который отвечает мониторинг, и по одному — на который нужна observability; объясните, чем метрики, логи и трейсы отличаются по назначению.

Критерии приёмки.

  • Названы три сигнала и вопрос, на который отвечает каждый.
  • Для приложения указано, какие сигналы есть, а каких нет (с проверкой по логам/исходнику).
  • Для каждого золотого сигнала сказано, считается ли он по тому, что есть сейчас.
  • Приведён вопрос для мониторинга и вопрос, требующий observability, с объяснением разницы.
  • Объяснено, почему один сигнал не заменяет другой.
  • После работы стенд убран (down).

6. Частые ошибки и подводные камни

Считать логи наблюдаемостью. Симптом: «логи есть, значит всё видно». Причина: по логам не строятся тенденции. Что делать: для золотых сигналов нужны метрики; логи дополняют, а не заменяют.

Путать мониторинг и observability. Симптом: сто дашбордов, а в аварии всё равно гадают. Причина: дашборды отвечают на известные вопросы. Что делать: обеспечить сигналы, чтобы задавать новые вопросы.

Мерить всё подряд. Симптом: дашборд на сто графиков, ни один не помогает. Причина: нет приоритета. Что делать: начать с золотых сигналов (latency, traffic, errors, saturation).

Считать, что оркестратор всё покажет. Симптом: под «зелёный», а сервис медленный. Причина: пробы — это «жив/готов», не «быстро/правильно». Что делать: добавить метрики и трейсы.

Внедрять всё сразу. Симптом: разом ставят Prometheus, Loki, Tempo и тонут. Причина: стек большой. Что делать: по сигналу за раз, начиная с метрик (порядок блока).

7. Проверка усвоения

  1. Какие три сигнала наблюдаемости и на какой вопрос отвечает каждый?
  2. Чем мониторинг отличается от observability? Приведите вопрос для каждого.
  3. Назовите четыре золотых сигнала и почему начинают именно с них.
  4. Что такое RED и USE и когда какой применяют?
  5. Какие сигналы излучает учебное приложение сейчас, а каких нет?
  6. Почему по логам неудобно строить график доли ошибок?
  7. Сервис «зелёный», но медленный — с какого сигнала начнёте?

8. Материалы

  • Google SRE Book: Monitoring Distributed Systems — определение мониторинга и четыре золотых сигнала. На английском.
  • OpenTelemetry: Observability Primer — что такое observability и три сигнала телеметрии. На английском.
  • Google SRE Workbook: Alerting on SLOs — как сигналы связаны с алертами и SLO (пригодится к 16.06 и 16.10). На английском.
  • Уроки 13.10 и 16.10 этого курса — пробы как мониторинг «жив/готов» и SLO как цель, к которой ведёт весь блок.

← Предыдущий: 15.07. Стоимость и эксплуатация облачного кластера · Блок 16 · Следующий: 16.02. Prometheus: модель данных, сбор, service discovery, хранение →

Practice materials

Scripts, cheat sheets and starter files for the lesson tasks. The lesson text is on this page.