Я пытаюсь запустить cronjob внутри контейнера docker, который вызывает сценарий оболочки.
Вчера я искал по всему интернету и stack overflow, но не смог найти подходящего решения.
Как я могу это сделать?
EDIT:
Я создал (закомментированный) github репозиторий с работающим docker cron контейнером, который вызывает shell скрипт с заданным интервалом.
Вы можете скопировать свой crontab в образ, чтобы контейнер, запущенный из этого образа, выполнил задание.
См. "Запуск задания cron с помощью Docker" от Julien Boulay в его Ekito/docker-cron
:
Давайте создадим новый файл под названием "
hello-cron
" для описания нашей работы.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
Следующий Dockerfile описывает все шаги по сборке вашего образа
FROM ubuntu:latest
MAINTAINER [email protected]
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
(см. Gaafar's comment и How do I make apt-get
install less noisy?:
apt-get -y install -qq --force-yes cron
тоже может работать)
ИЛИ, убедитесь, что ваше задание само перенаправляет непосредственно в stdout/stderr вместо лог-файла, как описано в hugoShaka's answer:
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Замените последнюю строку Dockerfile на
CMD ["cron", "-f"]
См. также (о cron -f
, то есть о cron "foreground") "docker ubuntu cron -f
не работает"
Соберите и запустите его:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Будьте терпеливы, подождите 2 минуты, и ваша командная строка должна отобразиться:
Hello world
Hello world
Эрик добавляет в комментариях:
Обратите внимание, что
tail
может не отобразить правильный файл, если он создан во время сборки образа.
В этом случае вам нужно создать или коснуться файла во время выполнения контейнера, чтобы tail отобразил правильный файл.
Смотрите "Вывод tail -f
в конце docker CMD
не отображается".
Принятое решение может представлять опасность в производственной среде.
В докер, вы должны выполнять только один процесс в контейнер, потому что если вы Don'т, процесс, который раздвоился и пошел фон не контролируется и может прекратиться без вашего ведома.
Когда вы используете хрон УМК && хвост -Ф /ВАР/лог/хрон.журнал
процесс хрон в основном вилкой для того, чтобы выполнить cron в фоновом режиме, основной процесс завершается и позволяют выполнить tailf в переднем плане. Фоновый процесс хрон мог остановить или не вы выиграли'т уведомления, ваш контейнер будет по-прежнему работать бесшумно и инструмента согласование не перезапустить его.
вы можете избежать этого путем перенаправления напрямую хрон's команды выход в докер
стандартный вывод и стандартный поток ошибок stderr
, которые расположены соответственно вв/proc/1/ФО/1 и в/proc/1/fд/2
.
Используя базовую оболочку, когда вы можете сделать что-то вроде этого :
``
И вашу команду cmd будет : УМК [на"Крона" В, С " Ф" и]
Для тех, кто хочет использовать простой и легкий образ:
FROM alpine:3.6
# copy crontabs for root user
COPY config/cronjobs /etc/crontabs/root
# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]
Где задачи cron это файл, который содержит ваши задачи cron, в таком виде:
* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line
Что @VonC предложил хороший, но я предпочитаю делать все настройки задания cron в одну линию. Это позволит избежать проблем кросс-платформенный, как задача cron и вы Don't нуждаются в отдельном файле хрон.
FROM ubuntu:latest
# Install cron
RUN apt-get -y install cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Setup cron job
RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
После запуска Docker контейнер, вы можете убедиться, если служба cron работает:
# To check if the job is scheduled
docker exec -ti <your-container-id> bash -c "crontab -l"
# To check if the cron service is running
docker exec -ti <your-container-id> bash -c "pgrep cron"
Если вы предпочитаете иметь точки входа вместо cmd, то можно использовать УМК выше
ENTRYPOINT cron start && tail -f /var/log/cron.log
Есть еще один способ сделать это, является использование программа, задача бегуна, который по cron (планировщик) с поддержкой.
Почему ? Иногда, чтобы выполнить задание, вы должны смешать, ваш базовый образ (питон, Ява, nodejs, Ruby и т. д.) С crond. Это означает, что другой образ поддерживать. Таскер избежать этого путем изолирования crond и контейнер. Вы можете просто сосредоточиться на изображении, которое вы хотите выполнить ваши команды, и настроить Tasker, чтобы использовать его.
Здесь `докер-сочинять.в формате YML файл, который будет запускать определенные задачи для вас
version: "2"
services:
tasker:
image: strm/tasker
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
configuration: |
logging:
level:
ROOT: WARN
org.springframework.web: WARN
sh.strm: DEBUG
schedule:
- every: minute
task: hello
- every: minute
task: helloFromPython
- every: minute
task: helloFromNode
tasks:
docker:
- name: hello
image: debian:jessie
script:
- echo Hello world from Tasker
- name: helloFromPython
image: python:3-slim
script:
- python -c 'print("Hello world from python")'
- name: helloFromNode
image: node:8
script:
- node -e 'console.log("Hello from node")'
Там 3 задания, все они будут выполняться каждую минуту (каждую: минуту), и каждый из них будет выполнять скрипт
код, внутри изображения, определенные в разделе изображения
.
Просто запустите `докер-сочинять вверх, и увидишь, как это работает. Вот Таскер РЕПО с полной документацией:
[VonC'С][1] ответ довольно тщательно. Кроме того, я'd хотелось добавить одну вещь, которая помогла мне. Если вы просто хотите выполнить задание без хвостов файл, вы'd быть уговорены для того чтобы просто удалить `&& хвост -Ф /ВАР/лог/хрон.отчет от команды хрон.
Однако это приведет к Docker контейнер, чтобы выйти вскоре после запуска, потому что, когда команду cron завершения настройки думает, что последняя команда завершена, а следовательно убивает контейнера. Этого можно избежать, запустив хрон на переднем плане через хрон -Ф`.
[1]: https://stackoverflow.com/users/6309/vonc на "VonC'ы"и
Я создал образ Docker на основе других ответов, который можно использовать как
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
.
где /path/to/cron
: абсолютный путь к файлу crontab, или вы можете использовать его как основу в Dockerfile:
FROM gaafar/cron
# COPY crontab file in the cron directory
COPY crontab /etc/cron.d/crontab
# Add your commands here
Для справки, изображение находится здесь.
Хотя эта цель выполнения заданий у запущенного процесса в контейнер через окно'интерфейс S метод exec
, это может представлять интерес для вас.
Я'вэ написано демон, который отмечает, контейнеры и графиков работ, определенными в своих метаданных на них. Пример:
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
'классический', хрон-как настройка также возможен.
Здесь представлены документы, здесь'ы репозитория изображения.
Когда вы развернуть свой контейнер на другой хост, просто отметим, что он выиграл'т автоматический запуск каких-либо процессов. Вы должны убедиться, что 'крон' служба работает внутри вашего контейнера. В нашем случае, я использую Supervisord с другими сервисами, чтобы начать обслуживание хрон.
[program:misc]
command=/etc/init.d/cron restart
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/misc-cron.err.log
stdout_logfile=/var/log/misc-cron.out.log
priority=998
Определить cron в специальный контейнер, который выполняет команду через докер exec к вашим услугам.
Это высшее единство, и выполнение скрипта будет иметь доступ к среде переменные, которые вы определили для вашего сервиса.
#docker-compose.yml
version: "3.3"
services:
myservice:
environment:
MSG: i'm being cronjobbed, every minute!
image: alpine
container_name: myservice
command: tail -f /dev/null
cronjobber:
image: docker:edge
volumes:
- /var/run/docker.sock:/var/run/docker.sock
container_name: cronjobber
command: >
sh -c "
echo '* * * * * docker exec myservice printenv | grep MSG' > /etc/crontabs/root
&& crond -f"
Итак, моя проблема была та же. Исправление было изменить команду разделе в докер-сочинять.в формате YML`.
Из
команду: crontab-файл в /etc/crontab-файл && хвост -Ф в /etc/crontab-файл
К
команду: crontab-файл в /etc/crontab-файл
команда: хвост -Ф в /etc/crontab-файл
В Проблема был '&ампер;&ампер;' между командами. После удаления этого было все нормально.
При запуске на некоторых сошел изображений, которые ограничивают доступ с правами root, мне пришлось добавить пользователей к пользователям использовать sudo? и запустить как судо-крон
в
FROM node:8.6.0
RUN apt-get update && apt-get install -y cron sudo
COPY crontab /etc/cron.d/my-cron
RUN chmod 0644 /etc/cron.d/my-cron
RUN touch /var/log/cron.log
# Allow node user to start cron daemon with sudo
RUN echo 'node ALL=NOPASSWD: /usr/sbin/cron' >>/etc/sudoers
ENTRYPOINT sudo cron && tail -f /var/log/cron.log
в
Может, это поможет кому-то
Задания Cron хранятся в /var/spool/cron/crontabs (общее место во всех известных мне дистрибутивах). BTW, Вы можете создать вкладку cron в bash, используя что-то вроде этого:
crontab -l > cronexample
echo "00 09 * * 1-5 echo hello" >> cronexample
crontab cronexample
rm cronexample
Это создаст временный файл с задачей cron, затем запрограммируйте его с помощью crontab. Последняя строка удалит временный файл.
Попробуйте использовать заводные камень, чтобы планировать задачи. Выполните шаги, описанные в этой ссылке.
Вы можете позвонить задач рейка внутри Либ/часы.файл RB, как показано ниже.
every(1.day, 'Import large data from csv files', :at => '5:00') do |job|
`rake 'portal:import_data_from_csv'`
end
Создать отдельный контейнер в докер-сочинять файл & выполните следующую команду внутри контейнера.
command: bundle exec clockwork lib/clock.rb
Самый надежный способ я нашел до сих пор находится в ведении независимой контейнер крон - установить клиент Docker и монтирования докер носок, так что вы можете соединиться с сервером настройки сервера на хост.
Затем просто использовать переменные окружения для каждого задания cron и скрипт ENTRYPOINT, чтобы создать файл /etc/crontab-файл
Вот изображение, которое я создал, используя этот принцип и использовать его в производстве в течение последних 3-4 лет.
https://www.vip-consult.solutions/post/better-docker-cron#content