У меня есть кластер k3s single node, работающий на машине. У меня пока нет настроенной инфраструктуры журналирования, и я бы оставил это как будущий опыт обучения на данный момент.
На этом k3s я запускаю несколько заданий cron, которые создают журналы для каждого задания в отдельный файл. Я могу наблюдать за ними на /var/log/containers/cron-job-*
хост-машине. Эти журналы исчезают через определенное время (successfulJobsHistoryLimit: 3). Новые экземпляры заданий создают новые файлы журналов.
Я не могу найти простой инструмент, который мог бы следить за каталогом журналов, желательно с шаблоном имени файла, и транслировать/объединять эти небольшие журналы заданий в один файл журнала, включая новые файлы, которые создаются. Я не против, если имя файла потеряется, я просто хочу, чтобы строки журнала оказались в одном файле, служащем архивом всех выполненных заданий.
Что я рассмотрел?
Я мог бы просто добавить скрипт для cat этих файлов и добавления в целевой файл с интервалом, но мне пришлось бы отслеживать, какие файлы уже были вставлены, в случае если задания выйдут из синхронизации или изменится интервал cron. Также я мог бы расширить эту функциональность для подов, которые "долго работают", и в этом случае мне пришлось бы начать отслеживать обновленные строки в журналах.
Все примеры, которые я нашел, имеют дело с отслеживанием в реальном времени на экране, что мне не нужно. Мне нужно многопоточное отслеживание в целевой файл журнала.
Есть идеи? (Я бы также принял какой-нибудь простой пример хука для ведения журналов Kubernetes)
решение1
Я предлагаю одно решение, которое я сейчас для себя выбрал. Это не тот ответ, который я искал, но тот, который, кажется, плывет по течению. Мне все еще интересно, можно ли это сделать с помощью какой-нибудь распространенной команды Unix.
В любом случае, вот что я сделал:
Распространенный способ, кажется, использует инструмент под названиемFluentd, который позволяет собирать журналы из различных источников и переносить их в любое удобное для вас место — своего рода ETL для журналов.
Я решил отправлять логи на сервер syslog, поскольку он у меня уже запущен, но вы можете выбрать любой из плагинов вывода отсюда:Выходные плагины. Также имеется большой набор дополнительных плагинов:Все плагины
Шаг 1
Получите настройку Fluentd с установленным плагином remote_syslog. Он не идет в комплекте с официальным образом docker, но вы можете настроить его самостоятельно.
FROM fluent/fluentd:v1.14.0-1.0
USER root
# https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog
RUN fluent-gem install fluent-plugin-remote_syslog
USER fluent
Создайте образ и поместите его в свой реестр.
Шаг 2
Затем настройте манифест развертывания Fluentd с требованиями тома только для чтения для доступа к журналам pod. Фактические файлы находятся в /var/log/pods/*, а /var/log/containers содержит фактические символические ссылки. Нам нужны фактические файлы. Эти журналы принадлежат root на хост-машине, и простой пользователь Fluent не будет иметь доступа для их чтения. Нам нужно установить некоторые контексты безопасности. Чтобы все заработало, я использовал группу root для fsGroup. Не стесняйтесь копать глубже и находить/комментировать наиболее оптимальное решение для этого с точки зрения безопасности.
apiVersion: apps/v1
kind: Deployment
...
spec:
...
spec:
securityContext:
fsGroup: 0
volumes:
- name: varlogpods-pv
persistentVolumeClaim:
claimName: pvc-var-log-pods
...
containers:
- name: fluentd
image: your/fluentd-image
См. мой полный манифест в этой статье:fluentd-развертывание
Шаг 3
Перед развертыванием вам также необходимо настроить fluent.conf
и описать некоторые правила.
У меня он настроен на соответствие такой строке журнала:
2022-04-26T20:05:00.847016854+03:00 stderr F time="2022-04-26 17:05:00" level=info msg="processing 3 records ..."
Подробнее о плагине tail:хвост
<source>
@type tail
@id in_tail_container_logs
path "/var/log/pods/default_cron-*/*/*.log"
pos_file "/tmp/cron_.log.pos"
read_from_head true
tag cron
<parse>
@type regexp
expression /^(?<logtime>[^ ]*) .* level=(?<level>[^ ]*) msg="(?<message>[^"]*)"$/
time_key logtime
time_format %FT%T.%N%:z
</parse>
</source>
<match cron>
@type remote_syslog
host 172.16.3.10
port 514
protocol udp
severity info
program "fluentd"
hostname "k3sserver"
<buffer>
</buffer>
<format>
@type single_value
message_key message
</format>
</match>
Один важный атрибут конфигурации здесь — read_from_head true
which читает файлы журнала сверху. Это необходимо для этого сценария, поскольку журналы пода вращаются, мы хотим, чтобы Fluentd читал полный журнал пода, а не только несколько строк обновления в конце. Для короткого задания cron файл журнала просто появляется, и tail не будет сообщать о каких-либо начальных строках в нем.
Шаг 4
Поиграйтесь с конфигурацией и попробуйте, попробуйте снова. Не забудьте перезапустить развертывание после обновления конфигурации в configMap.