Модуль 2 · как работает prometheus · сбор метрик
Глава 2.2
Target: куда обращаться
за метриками
Prometheus обращается к приложению за метриками по адресу из своих настроек. В этой главе разобрано, что такое target, из каких частей складывается адрес запроса и что означают слова job и instance. Отдельно разобрано, почему адрес localhost работает на компьютере и не работает в контейнере.
- Категория
- Настройка сбора
- Уровень
- Средний
- Опирается на
- Глава 2.1: части системы; основы Docker
- Результат
- Правильный адрес target для своего окружения
§1Понятие target
В главе 2.1 сервер Prometheus обращался к приложению и забирал у него числа. Чтобы обратиться, нужен адрес, и сервер берёт его из своего списка. Этот список похож на список квартир у контролёра, который снимает показания счётчиков воды: в квартиру, которой нет в списке, контролёр не придёт. Так же Prometheus не опрашивает программу, адреса которой в его списке нет. Одна строка этого списка называется target.
Targetцель сбора · один адрес
Адрес, по которому Prometheus регулярно запрашивает метрики. Обычно один target — это одна запущенная программа.
В настройках target записывают в виде хост:порт, например api:8000 или localhost:8000.
Список хранится в файле настроек prometheus.yml в формате YAML; правила этого формата собраны в главе 2.7. На стенде модуля этот файл занимает восемь строк, и target в нём один.
global: scrape_interval: 15s scrape_timeout: 10s scrape_configs: - job_name: api static_configs: - targets: ['api:8000']
Файл читается сверху вниз. Раздел global задаёт настройки для всех заданий сразу: опрашивать раз в 15 секунд и ждать ответа не дольше 10 секунд. Эти два числа разбирает глава 2.4. Раздел scrape_configs содержит список заданий сбора, на стенде задание одно, и оно названо api. Внутри задания в строке targets записан адрес: хост api и порт 8000.
В файле записано только api:8000. Запрос же уходит на полный адрес, и следующий раздел показывает, откуда берутся остальные его части.
§2Как собирается адрес запроса
На письме внутри города пишут улицу и дом. Страну и город почта подставляет сама, потому что письмо отправлено из этого же города. Адрес target устроен так же: в настройках пишут хост и порт, а начало http:// и конец /metrics Prometheus подставляет сам. Запрос уходит на адрес из трёх частей.
targetsВручную записана только средняя часть. Две другие можно изменить отдельными параметрами задания: протокол — параметром scheme, путь — параметром metrics_path. Путь меняют, когда программа отдаёт метрики по другому адресу. Например, сервисы на Spring Boot отдают их по пути /actuator/prometheus.
Из этого устройства следуют две частые ошибки. Первая — записать в targets полный адрес http://api:8000/metrics. Prometheus такой файл не принимает, и программа проверки promtool check config сообщает: "http://api:8000/metrics" is not a valid hostname. Вторая ошибка — не указать порт. Тогда Prometheus берёт порт по умолчанию: 80 для http и 443 для https. На стенде для target api получился адрес http://api/metrics, а приложение работает на порту 8000, поэтому запрос не прошёл.
Где посмотреть собранный адрес
Собранный адрес виден в веб-интерфейсе Prometheus на странице Status → Target health, в колонке Endpoint. Стрелка рядом с метками раскрывает список Discovered labels.

В раскрытом списке стоят служебные метки. Их имена начинаются с двух подчёркиваний. В них Prometheus хранит части адреса и настройки опроса: __scheme__ — протокол, __address__ — хост и порт, __metrics_path__ — путь, __scrape_interval__ и __scrape_timeout__ — частоту опроса и время ожидания. Служебные метки нужны только до начала опроса, в сохранённые данные они не попадают.
В сохранённых данных остаются две обычные метки: job и instance. На снимке они стоят над служебными, и следующий раздел объясняет, что они означают.
§3Job и instance
На стенде программа одна, но в настоящей работе один сервис запускают в нескольких копиях. Копии делят между собой нагрузку, и если одна остановится, остальные продолжат работать. У каждой копии свой адрес, поэтому для Prometheus это разные target. Чтобы не потерять связь между ними, нужны два уровня названий: одно для сервиса в целом и одно для каждой копии.
У сети одно название и несколько точек по разным адресам. Выручку считают по всей сети или по одной точке.
Job — название сервиса. Instance — одна копия по своему адресу. Запросы считают по всему сервису или по одной копии.
Instance и jobэкземпляр и задание
Instance — один адрес, с которого собираются метрики. Обычно это одна запущенная программа. Метка instance равна её адресу хост:порт.
Job — группа instance с одним назначением, например все копии одного сервиса. Метка job равна названию задания job_name.
Документация Prometheus показывает это на примере сервиса api-server, запущенного в четырёх копиях на двух машинах. В файле настроек это одно задание с четырьмя адресами.
- job_name: api-server static_configs: - targets: - '1.2.3.4:5670' - '1.2.3.4:5671' - '5.6.7.8:5670' - '5.6.7.8:5671'
На схеме те же четыре адреса разложены по машинам.
instance="1.2.3.4:5670"
instance="1.2.3.4:5671"
instance="5.6.7.8:5670"
instance="5.6.7.8:5671"
На каждой машине работают две программы на разных портах. Поэтому instance — это хост и порт вместе: одного хоста для различения программ недостаточно. Каждое число каждой копии получит метку job="api-server" и свою метку instance. По этим меткам запрос складывает значения всего сервиса или выбирает одну копию.
На стенде модуля всё проще: в задании api один instance, api:8000. Все target одного задания в интерфейсе называются scrape pool, и на странице Target health они показаны одним блоком.

api на стенде: один instance, состояние UPАдрес api:8000 пока записан без объяснения. Следующий раздел объясняет, почему на стенде записан он, а привычный localhost не работает.
§4Адрес зависит от места Prometheus
Приложение стенда открывается в браузере по адресу localhost:8020. Кажется, что тот же адрес подойдёт и для Prometheus. На стенде он не подходит. Причина в том, что слово localhost означает разное в зависимости от того, кто его читает.
Записка «зайди в квартиру 5» ведёт в разные квартиры. Жилец первого дома придёт в квартиру 5 своего дома, жилец второго дома — в квартиру 5 своего.
Слово localhost означает «тот компьютер, на котором я запущен». Для программы на компьютере это компьютер. Для программы в контейнере это её собственный контейнер.
У каждого контейнера Docker своя сеть: свой localhost и свои порты. На стенде контейнеров два, приложение и Prometheus. Они описаны в файле compose.yaml и объединены в одну сеть Docker Compose. Внутри этой сети контейнеры находят друг друга по именам сервисов, поэтому приложение доступно по имени api.
Браузер и терминал работают здесь. Приложение открывается как localhost:8020, Prometheus — как localhost:9092.
Приложение работает на порту 8000. Адрес внутри сети: api:8000.
Сервер работает на порту 9090. Его localhost — этот контейнер.
По схеме видно, почему у одного приложения два адреса. Строка ports: ['127.0.0.1:8020:8000'] в compose.yaml открывает порт 8000 контейнера на компьютере под номером 8020, и этим адресом пользуется браузер. Prometheus находится внутри сети и обращается к приложению напрямую: по имени api и внутреннему порту 8000. Если записать ему localhost:8000, он обратится к собственному контейнеру, где на этом порту ничего не работает.
Какой адрес работает из какого места
Это рассуждение можно проверить для других сочетаний. В блоке ниже выберите, где запущен Prometheus и какой адрес записан в настройках. Результаты с пометкой «проверено» получены на стенде.
Все сочетания сводятся к одному правилу: адрес target записывают таким, каким он доступен из места, где запущен Prometheus. Если Prometheus работает в одной сети Compose с приложением, это имя сервиса и внутренний порт: api:8000. Если он запущен на компьютере без Docker, это порт, открытый на компьютере: localhost:8020. Если он работает в контейнере вне сети приложения, это имя компьютера, видимое из контейнера: host.docker.internal:8020.
На стенде адрес один, и он записан вручную. Следующий раздел показывает, что делают, когда адресов много и они меняются.
§5Откуда берётся список target
В маленькой фирме список сотрудников пишут на листе бумаги. В большой компании люди приходят и уходят каждый день, и список берут из системы отдела кадров. Со списком target так же. Когда программ мало и адреса постоянные, их записывают в файл вручную: на стенде это параметр static_configs. Когда копии сервиса появляются и исчезают каждые несколько минут, вручную список не поддержать, и его берут из внешней системы.
Автоматическое получение списка называется service discovery — обнаружение сервисов. Источников несколько, и для каждого есть свой параметр задания. Параметр file_sd_configs читает адреса из файлов, которые пишет другая программа. Параметр dns_sd_configs берёт их из записей DNS, kubernetes_sd_configs — из Kubernetes, а параметры вида consul_sd_configs и ec2_sd_configs — из реестра сервисов или облака. Результат у всех способов одинаковый: список target со служебными метками из §2.
Своя метка для target
Вместе с адресом в настройках можно записать постоянную метку. Она появится на всех числах этого target. Например, метка env со значением dev отмечает, что программа работает в среде разработки, и потом по ней отбирают ряды в запросах.
static_configs: - targets: ['api:8000'] labels: env: dev
Подробнее: изменение меток до опроса
Внешняя система может добавить свои служебные метки. Например, Kubernetes добавляет __meta_kubernetes_pod_name с именем пода. До начала опроса метки можно изменить правилами relabel_configs: переименовать, скопировать в обычную метку или исключить target из списка. После этого все метки с __ удаляются.
Метки теперь приходят из двух мест: часть записывает приложение, часть добавляет Prometheus. Последний раздел разбирает случай, когда их имена совпали.
§6Метки target и метки приложения
Приложение записывает свои метки в ответе: в главе 2.1 это были method и status. Prometheus добавляет свои: job, instance и метки из параметра labels. Обычно эти наборы не пересекаются. Но иногда приложение отдаёт метку с именем job или instance, и тогда у одного числа оказываются две метки с одним именем. Сохранить можно только одну.
Похожая ситуация бывает с посылкой. На коробке уже есть наклейка магазина с адресом, и служба доставки должна наклеить свою. Она либо оставляет старую наклейку рядом с пометкой, либо оставляет её единственной и свою не клеит. В Prometheus этот выбор делает параметр задания honor_labels.
Оба варианта проверены на стенде. Программа отдаёт одно число с метками job="nightly-report" и instance="worker-7", и её опрашивают два задания с разными значениями параметра.
Голубые плашки — метки из ответа программы. Оранжевые — метки, которые добавил Prometheus.
При значении по умолчанию под именами job и instance сохранены метки Prometheus, а метки приложения получили приставку exported_. Метки приложения сохранены, и видно, откуда пришло каждое значение. При honor_labels: true под этими именами сохранены метки приложения, а меток Prometheus на числе нет.
Поэтому для обычного приложения параметр оставляют выключенным. Его включают для программ, которые передают чужие метрики. Пример — Pushgateway из главы 2.5: он хранит числа других программ, и метки job и instance в его ответе описывают эти программы.
§7Проверьте себя
Вопрос 1Prometheus и приложение запущены в одной сети Compose, сервис приложения называется api, порт внутри контейнера 8000, на компьютере открыт как 8020. Какой target записать?
Этот адрес работает с компьютера. Внутри контейнера Prometheus localhost — сам контейнер, на стенде ошибка
connection refused.Верно. Контейнеры одной сети находят друг друга по имени сервиса, а внутри сети доступен порт контейнера 8000.
В
targetsпишут только хост и порт. Протокол и путь задаются параметрамиschemeиmetrics_path.
Вопрос 2Какой будет метка instance у чисел target api:8000, если её не задавать?
Верно. По умолчанию
instanceравна адресу изtargets.Полный адрес в метки не записывается. Он виден только в колонке Endpoint на странице Target health.
Prometheus записывает адрес так, как он указан в настройках.
Вопрос 3Приложение отдаёт число с меткой job="worker", задание называется api, honor_labels не указан. Какие метки получит число?
Так будет с
honor_labels: true. По умолчанию под именемjobсохраняется метка Prometheus.Верно. Метка приложения сохраняется с приставкой
exported_.Ошибки нет: выбор определяет параметр
honor_labels.
Вопрос 4Чем job отличается от instance?
Instance — это хост и порт вместе. Job к адресам не привязан.
Верно. Так эти понятия определены в документации Prometheus.
Обе метки ставит Prometheus:
jobиз названия задания,instanceиз адреса target.
- Prometheus. Jobs and instances — prometheus.io/docs/concepts/jobs_instances
- Prometheus. Configuration: scrape_config, static_config, relabel_config — prometheus.io/docs/prometheus/latest/configuration/configuration
- Docker. Networking in Compose — docs.docker.com/compose/how-tos/networking
- Стенд модуля: Prometheus 3.5.0, Docker Desktop; опыты с адресами и honor_labels выполнены 29.09.2026