Как иметь несколько потоков журнала в докере

21

У нас есть приложение, которое записывает три типа журналов в три отдельных файла: журналы доступа, общие журналы приложений и системные журналы. Формат (и цель) этих журналов очень разные. И у нас есть отдельные средства пересылки журналов, которые отправляют их отдельно в нашу централизованную систему ведения журналов.

Основываясь на том, что журналы рассматриваются как принцип потоков событий , мы думаем о переходе от использования файлов к стандартному выводу. Хотя мы знаем о некоторых преимуществах этого подхода, это также означает, что мы получим объединенный поток журналов с различным форматированием, который нам потребуется снова разделить, прежде чем мы сможем отправить их в нашу центральную систему (Kibana / Splunk / и т. д.) или внутри.

Нам интересно, есть ли какие-либо инструменты или рекомендации о том, как мы должны подходить к этой ситуации.

SztupY
источник
4
Я не думаю, что это того стоит. Зачем усерднее работать, чтобы объединить, а затем разделить потоки журналов, просто из-за какого-то «принципа»? Файлы хорошие. Файлы работают. Это звучит слишком сильно. Я бы сказал, может быть, передать все журналы в системный журнал, с разными тегами и т. Д., Но я должен сказать, если кто-то в моей команде предложил это ... Я был бы ... разочарован.
Ассаф Лави
Потому что при использовании файлов есть некоторые другие виды ночных кошмаров управления, особенно если они генерируются из контейнера Docker. Пока что похоже, что недостатки перехода на стандартный вывод перевешивают преимущества нашего
варианта
3
Я не знаю о "ночных кошмарах". Я знаю, что это так, как это было сделано некоторое время назад, и есть много программного обеспечения, которое поможет вам сделать это. Файлы журналов вращаются, читаются с контрольными точками - файл является отличной абстракцией для этого. Я не куплюсь на принцип, который продает мне новые кошмары из-за боязни старых, знакомых шаблонов. Ваши записи в журнале либо записываются в файл, либо обрабатываются в памяти (по крайней мере, до тех пор, пока они перемещаются в контейнере). Удачи в достижении надежности файлов журнала с помощью потоковых сплиттеров и слияний в памяти.
Ассаф Лави
@AssafLavie Вы должны написать это в ответе, который может быть проголосовал. ИМХО, это совершенно обоснованная точка зрения.
Дан
2
Я пришел сюда с тем же вопросом. Простой факт заключается в том, что встроенная функция ведения журнала докера зависит от всего, что происходит с stdout / stderr, следовательно, драйвер ведения журнала и экосистема сторонних инструментов, создаваемых вокруг него, тоже. Я испытываю желание сбросить все свои журналы на том хоста, но я знаю, что мне придется продолжать возвращаться и управлять этим, когда мои контейнеры переходят на k8s или openshift, gke или что-то еще, тогда как если я следую за докером Подход к нему будет намного более плавным. А пока я буду искать ответ на этот законный вопрос
ревень

Ответы:

13

Я все еще ищу подход слияния / разделения, но в то же время этот подход, рекомендованный документацией Kubernetes, кажется разумным решением: используйте контейнер с коляской для каждого из ваших отдельных журналов .

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

Таким образом, каждый из ваших log-sidecar-контейнеров имеет свой собственный docker-log из своего собственного stdout. Будучи отдельными, как это, вы можете использовать стандартные методы докера (и kubernetes, и т. Д.) Для разделения или агрегирования. Вот что говорит страница Kubernetes:

Этот подход позволяет вам отделить несколько потоков журналов от разных частей вашего приложения, некоторые из которых могут не поддерживать запись в stdout или stderr. Логика перенаправления журналов минимальна, так что это вряд ли значительная нагрузка. Кроме того, поскольку stdout и stderr обрабатываются kubelet, вы можете использовать встроенные инструменты, такие как журналы kubectl.

«Отдельные потоки журналов» происходят от встроенных тегов, которые docker применяет к журналам из разных контейнеров, описанных в документации докера здесь:

Опция тега журнала определяет, как форматировать тег, который идентифицирует сообщения журнала контейнера. По умолчанию система использует первые 12 символов идентификатора контейнера. Чтобы переопределить это поведение, укажите параметр тега

Ревень
источник
Стоит упомянуть обратную сторону этого подхода к журналу контейнеров-контейнеров: «Обратите внимание, что, несмотря на низкую загрузку ЦП и памяти, запись журналов в файл и последующая потоковая передача их на стандартный вывод может удвоить использование диска». Интересно, пробует ли кто-нибудь такой подход на практике?
Юсонг
8

Идея объединить их в один поток, чтобы потом разделить их, звучит болезненно. У меня не было причин делать это самому, но вот с чего я начну:

  • Когда вы запустите Docker-контейнер, создайте том, чтобы было легко просматривать / отправлять журналы с хоста.
  • Используйте что-то вроде remote_syslog2 для отправки журналов вашему сборщику журналов

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

bradym
источник
Это решение может быть объединено с именованными каналами, единственная проблема с именованными каналами состоит в том, что они не работают сейчас на всех системах. Они не работают на Mac
Дженс