Почему мой контейнер Docker с syslog-ng перезапускается каждые ~1 минуту?

Вопрос или проблема

У меня есть Docker Swarm с различными работающими службами. Я добавил службу syslog-ng OSE, используя https://github.com/linuxserver/docker-syslog-ng. В стеке syslog-ng используется следующий файл docker-compose.yml:

---
services:
  syslog:
    image: registry.local.net/syslog-ng:latest
    ports:
      - 514:514
    volumes:
      - /path/on/host/syslog-ng/config:/config
      - /path/on/host/log:/log
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - LOG_TO_STDOUT=1
#    healthcheck:
#      test: ["CMD-SHELL", "/usr/sbin/syslog-ng-ctl healthcheck -c /config/syslog-ng.ctl || exit 1"]
#      interval: 10s
#      timeout: 2s
#      retries: 3
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
      update_config:
        parallelism: 1
        delay: 10s
    networks:
      syslog:

networks:
  syslog:
    external: true

а вот мой файл syslog-ng.conf:

@version: 4.2
@include "scl.conf"

options {
     chain_hostnames(no);
     flush_lines(0);
     use_dns(no);
     time_reopen(1);
};

source net {
    tcp(ip(0.0.0.0) port(514));
};

template my_log_format {
    template("$MSG\n");
};

filter f_access_log { program("httpd.access") };

destination d_logs {
    file(
        "/log/TEST"
        owner("1000")
        group("1000")
        perm(0664)
        template(my_log_format)
        );
};

log {
    source(net); filter(f_access_log); destination(d_logs);
};

Я настроил службу Apache в Docker Swarm для отправки своих логов в службу syslog-ng, используя logger -T -t httpd.accept -n syslog -P 514 --rfc3164.

Syslog-ng создает настроенный файл логов, получает строки логов от Apache и регулярно добавляет их в настроенный файл логов. Всё, кажется, работает так, как я хочу. Единственная проблема в том, что контейнер Docker syslog-ng продолжает завершать работу и перезапускаться каждые 70-80 секунд. Я пробовал добавить проверку работоспособности (закомментированную выше), но это ничего не изменило. При анализе завершённых контейнеров видно, что все проверки работоспособности проходят до тех пор, пока контейнер не завершится с кодом выхода 137, и журнал Docker завершённых контейнеров не показывает ничего очевидно неправильного.

Текущий лог-файл syslog-ng показывает следующее (за исключением меток времени в начале каждой строки):

Принимаем соединения; addr="AF_INET(0.0.0.0:514)"
syslog-ng запускается; версия='4.8.1'
Принято соединение syslog; fd='14', client="AF_INET(10.0.6.244:37126)", local="AF_INET(0.0.0.0:514)"

За секунды до выхода одного из контейнеров, top внутри контейнера показал следующее:

top - 08:31:26 up 169 дней, 17:44,  0 пользователей, средняя загрузка: 1.13, 1.05, 1.05
Процессов:  15 всего, 1 активный,  14 в ожидании,   0 остановлено,   0 зомби
%Cpu(s): 23.8 us,  1.8 sy,  0.0 ni, 73.9 id,  0.0 wa,  0.2 hi,  0.2 si,  0.0 st 
MiB Mem :   7652.9 всего,    405.8 свободно,   2924.0 использовано,   4968.6 буфер/кэш     
MiB Swap:   8192.0 всего,   7883.4 свободно,    308.6 использовано.   4728.9 доступно память 

ДОПОЛНЕНО: Я думал, что нашёл решение, добавив

    time-reap(30);
    mark-freq(10);

в глобальные опции syslog-ng. Контейнер Docker оставался запущенным почти 5 минут после того, как я сделал это изменение, но теперь он снова завершает работу и перезапускается примерно каждую минуту, даже с этими опциями.

Оказалось, что это было связано с некоторым программным обеспечением безопасности, запущенным на хосте Docker, которое завершало процесс syslog-ng.

Ответ или решение

Причина, по которой ваш контейнер syslog-ng в Docker перезапускается каждые 70-80 секунд, может быть связана с несколькими факторами. Прежде всего, стоит отметить, что exit code 137 указывает на то, что процесс был принудительно завершён системой. Обычно это происходит из-за нехватки памяти, превышения лимитов ресурсов или вмешательства извне, как в вашем случае — программного обеспечения безопасности.

Теоретический аспект

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

  1. Нехватка ресурсов: Контейнеры могут быть остановлены, если они превышают ограничения по памяти или процессору. Выделенные ресурсы могут быть исчерпаны, что приведёт к тому, что Docker принудительно завершит контейнер с кодом 137.

  2. Ограничения процессов и сигналы: Код 137 также может означать, что контейнер завершился из-за сигнала SIGKILL (обычно посылаемого в случае нехватки памяти на хосте).

  3. Внешние вмешательства: Как вы отметили в заключении, внешние процессы, такие как антивирус или другие средства безопасности, могут вмешиваться и завершать процессы Docker, если считают их потенциально опасными.

Примеры и аналогии

Разберёмся на конкретных примерах. Если вы запускаете service syslog-ng без ограничения памяти, его потребление оперативной памяти может выйти за разумные пределы на уровне системы. Например, в высоконагруженных системах или системах с низкими ресурсами, каждый дополнительный процесс может иметь значение. При нехватке свободной памяти система может решить убить определённые процессы, чтобы освободить ресурсы. Обычно это автоматический выбор менее критичных процессов.

Другой возможный случай — конфликты с другими системными процессами. Современные инструменты безопасности могут ошибочно идентифицировать законные процессы как угрозу. Это может быть связано либо с подозрительной сетью действиями (ваш syslog-ng слушает на порту 514, что может быть воспринято как аномальное действие), либо с иными факторами.

Применение и рекомендации

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

  1. Мониторинг ресурсов: Убедитесь, что вашему контейнеру выделено достаточно ресурсов. Это можно сделать с помощью flags в Docker Compose, таких как mem_limit и cpu_shares, чтобы задать конкретные ограничения на использование памяти и процессора.

    services:
     syslog:
       ...
       deploy:
         resources:
           limits:
             memory: 512M
             cpus: '0.50'
  2. Проверка логов и диагностика: Регулярно проверяйте логи не только контейнера, но и самой системы на предмет сообщений, касающихся управления ресурсами. Обратите внимание на то, что некоторые сообщения в системных логах могут указывать более точно, что именно произошло перед остановкой контейнера.

  3. Конфигурация системного ПО безопасности: Когда проблема в ПО безопасности, попытайтесь добавить доверие к контейнеру или исключить его из проверок. Это может потребовать настройки политик совместимости или белых списков для вашего инструмента безопасности.

  4. Обновление программного обеспечения: Убедитесь, что все участки системы, включая сам Docker и контейнеризированные приложения, обновлены до последних версий. Это необходимо для защиты от ошибок и обеспечения стабильности.

  5. Тестирование в изолированной среде: Попробуйте развернуть ваш сетап в более контролируемой среде, например, без стороннего ПО безопасности, чтобы убедиться, что проблема не лежит в конфигурациях или ограничениях контейнера.

Профессиональное настройка и диагностика систем, особенно в контексте контейнеризации, требует внимания к деталям и знания поведения как контейнеризированных приложений, так и самого Docker. Учитывая результаты ваших предыдущих попыток, решением может стать перенастройка или консультация с администратором систем безопасности.

Оцените материал
Добавить комментарий

Капча загружается...