Назад | Перейти на главную страницу

Докер: запустить Cronjob для другого контейнера

Я ищу лучшие практики по запуску cronjobs для моего контейнера php fpm.

Прямо сейчас работает:

Теперь мне бы хотелось, чтобы еще один контейнер работал под названием «Контейнер Cronjob», который выполнял бы сценарий в моем контейнере PHP FPM (мне нужны некоторые зависимости PHP).

Итак, три возможных решения:

1.) Запуск собственного контейнера

Я хотел бы использовать это решение!

Было бы хорошо иметь контейнер с CRON, где я могу (каким-то образом) вызвать docker exec в моем контейнере php fpm ... Или есть другой способ.

2.) Запуск CRON внутри контейнера PHP

Это было бы нормально, но это не лучшая практика. Я мог бы запустить второй процесс в моем контейнере php fpm под управлением cron. Это сработает, но я не уверен, стоит ли вам работать с докером именно с этим.

3.) Запуск хостов Cron

Это было бы жестоко. Мне нужно было бы найти processID и containerID заданного пути, а затем запустить docker exec. Но это более или менее мой последний путь ... И я ненавижу управлять cronjobs без развертывания.

Так какой же здесь лучший подход?

Хорошего дня,

Bastian

Я написал демон, который наблюдает за контейнерами и планирует для них задания, определенные в их метаданных. Это ближе всего к вашему 1) решению. Пример:

version: '2'

services:
  wordpress:
    image: wordpress
  mysql:
    image: mariadb
    volumes:
      - ./database_dumps:/dumps
    labels:
      deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
      deck-chores.dump.interval: daily

Также возможна «классическая» конфигурация cron.

Вот документы, вот репозиторий изображений.

Запустите cron в другом контейнере или даже на хосте, но запустите скрипт через php-fpm (например, cron будет "завиваться" или что-то в этом роде скрипт PHP).

Убедитесь, что вы защищаете такую ​​настройку токеном безопасности, сетевыми ограничениями и т. Д. Улучшение может заключаться в наличии отдельного пула php-fpm с динамическими процессами, который может порождать максимум один процесс. Этот пул будет доступен только для cron. Это также может принести пользу своим собственным индивидуальным настройкам, таким как большее время выполнения, больше или меньше памяти и т. Д.

P.S .: Можно использовать что-то вроде этот вызывать скрипт прямо в контейнере FPM, а не проходить через nginx.

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

Сам Cron можно установить и запустить на переднем плане (cron -f), что упрощает установку в контейнер. Чтобы получить доступ к другим контейнерам, вы, скорее всего, установите докер в тот же контейнер для клиентского интерфейса командной строки (не для запуска демона). Затем для доступа к среде хоста докеров наиболее распространенным решением является привязка монтирования сокета докера (-v /var/run/docker.sock:/var/run/docker.sock). Единственная проблема заключается в том, что вам нужно настроить docker gid внутри вашего контейнера в соответствии с gid хоста, а затем добавить пользователей внутри контейнера в группу docker.

Это означает, что эти пользователи имеют тот же доступ, что и любой пользователь докера на хосте, например доступ на корневом уровне, поэтому вам нужно либо полностью доверять отправляющему их пользователю, либо ограничивать команды, которые они могут запускать, с помощью какого-либо эквивалента sudo. Другой недостаток заключается в том, что это менее переносимо, и администраторы, осведомленные о безопасности, вряд ли одобрят запуск ваших контейнеров в своих системах.

Вернуться к варианту B очень просто с помощью такого инструмента, как supervisord. Хотя это не идеальный вариант «один процесс на контейнер», это не совсем анти-шаблон, поскольку он объединяет весь ваш контейнер и зависимости и устраняет любые риски безопасности для хоста.

Независимо от того, выберете ли вы первый или второй вариант, зависит от вашей среды, от того, кто отправляет задания, в скольких контейнерах должны быть отправлены задания против самих себя и т. Д. Если это администратор, отправляющий задания для большого количества контейнеров, то контейнер cron делает смысл. Но если вы разработчик приложения, которому необходимо включить запланированное задание с вашим приложением в виде пакета, выберите второй вариант.

Я пытался добиться чего-то подобного.

Моя первоначальная идея заключалась в том, чтобы запускать cron-задания из отдельных cron контейнер и фактически выполнить их в другом контейнере (php) т.е. иметь один crontab запись для каждого docker run -i t $containerName $scriptName ... команда, запускающая другой сценарий в пределах php контейнер

Подход не очень хорош из-за недостатков @BMitch также упоминает. Также я не очень люблю устанавливать docker в контейнер.

Хочу предложить другое решение, подходящее под ваш # 1 категория: можно запустить php-fpm прямо. Хотя это не самое элегантное решение в мире, оно предлагает преимущества:

  1. Безопасность - нет специального или привилегированного доступа, просто используйте хост и порт (например, php-host:9000), который уже открыт для nginx из виртуальной сети докеров
  2. Имея cron управление отделено от php контейнер - чтобы не повредить масштабирование
  3. Фактически используя cron для злых задач - просто посадите crontab и будет сделано вместо того, чтобы повторно реализовать cron через различные другие библиотеки
  4. Выполнение скрипта не происходит nginx, поэтому никто не может запускать их напрямую через веб-сервер, вам не нужно реализовывать аутентификацию или подобные механизмы.
  5. Еще меньше проблем с разрешениями. Моя предыдущая докеризация cron имела cron установлен в другом php контейнер и общий доступ к базе кода с использованием томов. Это было эффективно, но с разрешениями нужно было обращаться осторожно, так как кеши, DI, журналы и т. Д. Должны быть доступны и доступны для записи как веб-серверу, так и cron пользователь. Такой подход устраняет проблему

Единственный недостаток, с которым я столкнулся до сих пор, заключается в том, что первая строка с hashbang (#!/usr/local/bin/php) рассматривается как фактический вывод, и выдается предупреждение PHP об уже отправленных заголовках (Cannot modify header information - headers already sent by ...) - удаление хэшбэга исправляет это.

Как на самом деле это сделать?

  1. Возьмите чистый контейнер, например alpine:3.7
  2. Установить apk-cron и fcgi (информация о пакете)
  3. Запустите что-то вроде:
SCRIPT_FILENAME=/docroot/scripts/cron/example-script.php \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect php-fpm:9000

изнутри crontab.

Больше информации по теме: Прямое подключение к PHP-FPM