Payments переехал в Kubernetes. Под упал, появился новый, а файл внутри старого контейнера уже недоступен. Логи не должны жить столько же, сколько процесс. Как уборщик на каждом этаже забирает бумаги из всех комнат, агент на каждом узле собирает stdout всех контейнеров этого узла.
Один агент на узел
DaemonSet
запускает Filebeat, Fluent Bit или другой агент на подходящих worker-узлах. Deployment с одной репликой не прочитает локальные файлы на остальных узлах. Sidecar нужен для особого приложения, но плодить сборщик рядом с каждым контейнером без причины дороже.
Маршрут:
приложение → stdout/stderr → container runtime → файлы узла
→ агент DaemonSet → обработка → Elasticsearch → Kibana
Агенту нужны read-only mounts каталогов логов узла и состояние прогресса чтения. Потеря registry может вызвать повторную отправку, а ранняя ротация файлов во время недоступности приёмника потерю хвоста. Короткоживущий pod не гарантирует долгую жизнь его файлов.
Современный Filebeat
Для Filebeat 9 используют filestream и container parser, а не устаревший input type: container, который отключён по умолчанию начиная с 9.0:
filebeat.inputs:
- type: filestream
id: kubernetes-containers
prospector.scanner.symlinks: true
paths: ['/var/log/containers/*.log']
parsers:
- container:
stream: all
format: auto
processors:
- add_kubernetes_metadata:
host: ${NODE_NAME}
output.logstash:
hosts: ['logstash:5044']
Это фрагмент конфигурации реального агента, не готовый manifest развёртывания. NODE_NAME передают через Downward API, каталог логов монтируют с узла; для processor нужны service account и ограниченные права чтения метаданных Kubernetes. Сертификаты и выход добавляют по правилам безопасности.
Две оболочки одной записи
CRI-строка содержит время runtime, поток stdout или stderr, признак полной/частичной строки и полезный текст. Внутри полезного текста может быть ещё JSON приложения. Сначала снимают оболочку контейнера, затем разбирают JSON; обратный порядок пытается читать дату как JSON.
Ниже Logstash исполняет ручной разбор двух учебных CRI-строк. Он не запускает Kubernetes, не получает метаданные из API и не заменяет container parser: имя pod и namespace здесь фиксированный контекст примера.
Первая запись получила время и app.message, вторая помечена partial_line. Разбор первой полной строки не реализует сборку CRI-фрагментов: в реальном агенте этой работой занимается container parser. Не объявляй каждый P сломанным JSON и не выбрасывай его до сборки.
Что такое EFK
EFK
меняет сборщик и обработку, не обязан менять схему ECS, хранение и Discover. Filebeat → Elasticsearch → Kibana это другой вариант, не расшифровка буквы F.
Добавляй kubernetes.namespace, kubernetes.pod.name, container.id, версию приложения и окружение. Не делай имя каждого pod отдельным индексом: появятся крошечные шарды. Kubernetes не делает поиск бесплатным и не заменяет ILM. А можно ли заменить сам Elasticsearch, разберём в уроке про OpenSearch.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.