1. Обзор
Как системные администраторы, мы неизменно сталкиваемся с необходимостью планирования задач. Мы можем добиться этого, используя службы cron
в системах Linux. Кроме того, мы можем включить службы планирования cron
в контейнерных системах.
Теперь в этом руководстве будут рассмотрены два разных способа включения служб cron в контейнерах Docker.
В первом подходе мы встроим службы cron
в образ Docker с помощью Dockerfile, тогда как в другом методе будет показано, как установить службы планирования в контейнере.
2. Службы Cron — использование подхода Dockerfile
Создание образов с помощью Dockerfile
— один из самых простых способов создания образов контейнеров. Итак, как мы это делаем? По сути, Dockerfile
— это простой текстовый файл, содержащий набор инструкций по созданию образа. Нам нужно передать задачу планирования, детали cron
и вызвать службы cron
из Dockerfile
.
2.1. Написание Dockerfile
Давайте быстро рассмотрим пример:
$ tree
.
├── Dockerfile
└── get_date.sh
0 directories, 2 files
Как правило, первая строка Dockerfile
начинается с команды FROM
, которая берет запрошенный образ из настроенного реестра. В нашем случае реестр по умолчанию настроен как DockerHub
. Затем идет MAINTAINER
, который является метаданными для сбора информации об авторе. Инструкция ADD
копирует сценарий get_date.sh
из пути сборки образа хост-компьютера в путь назначения образа.
После копирования сценария в образ сборки инструкция RUN
дает права на выполнение. Более того, инструкция RUN
помогает выполнить любую команду оболочки в качестве нового слоя изображения поверх текущего слоя и фиксирует результаты. RUN
обновляет репозиторий apt
и устанавливает в образ последние службы cron .
Он также выполняет планирование cron
в crontab
.
Наконец, мы запустим службы cron
с помощью инструкции CMD :
$ cat Dockerfile
# Dockerfile to create image with cron services
FROM ubuntu:latest
MAINTAINER foreach.com
# Add the script to the Docker Image
ADD get_date.sh /root/get_date.sh
# Give execution rights on the cron scripts
RUN chmod 0644 /root/get_date.sh
#Install Cron
RUN apt-get update
RUN apt-get -y install cron
# Add the cron job
RUN crontab -l | { cat; echo "* * * * * bash /root/get_date.sh"; } | crontab -
# Run the command on container startup
CMD cron
2.2. Сборка и запуск образа Cron
Как только Dockerfile
будет готов, мы можем собрать образ с помощью команды docker build
. Точка (.) указывает Docker Engine взять Dockerfile
из текущего пути. Команда сборки создает слои Docker для каждой инструкции, заданной в Dockerfile
, для формирования окончательного образа сборки . Типичный результат сборки показан ниже:
$ docker build .
Sending build context to Docker daemon 3.072kB
Step 1/8 : FROM ubuntu:latest
---> ba6acccedd29
Step 2/8 : MAINTAINER foreach.com
---> Using cache
---> e6b3946b2382
Step 3/8 : ADD get_date.sh /root/get_date.sh
---> 4976f058d428
Step 4/8 : RUN chmod 0644 /root/get_date.sh
---> Running in 423a4e9adbab
Removing intermediate container 423a4e9adbab
---> 76d972a082ba
Step 5/8 : RUN apt-get update
---> Running in badc0d84f6ff
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
...
... output truncated ...
...
Removing intermediate container badc0d84f6ff
---> edb8a19b891c
Step 6/8 : RUN apt-get -y install cron
---> Running in efd9b8a67d98
Reading package lists...
Building dependency tree...
...
... output truncated ...
...
Done.
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Removing intermediate container efd9b8a67d98
---> 2b80000d32a1
Step 7/8 : RUN crontab -l | { cat; echo "* * * * * bash /root/get_date.sh"; } | crontab -
---> Running in 1bdd3e0cc877
no crontab for root
Removing intermediate container 1bdd3e0cc877
---> aa7c82aa7c11
Step 8/8 : CMD cron
---> Running in cf2d44873b36
Removing intermediate container cf2d44873b36
---> 8cee091ca87d
Successfully built 8cee091ca87d
Поскольку мы предварительно установили службы cron
в образ и внедрили задачи в crontab
, задание cron
автоматически активируется при запуске контейнера. В качестве альтернативы мы можем запустить контейнер с помощью команды запуска docker
. Впоследствии опция « -it »
запуска docker
помогает попасть в контейнер с приглашением bash.
На приведенном ниже рисунке показано выполнение скрипта get_date.sh
в контейнере с использованием cron
:
$ docker run -it 8cee091ca87d /bin/bash
root@88f5bb1f0a08:/#
root@88f5bb1f0a08:/# date
Mon Nov 15 14:30:21 UTC 2021
root@88f5bb1f0a08:/# ls -ltrh ~/date.out
ls: cannot access '/root/date.out': No such file or directory
root@88f5bb1f0a08:/# ls -ltrh /root/get_date.sh
-rw-r--r-- 1 root root 18 Nov 15 14:20 /root/get_date.sh
root@88f5bb1f0a08:/# crontab -l
* * * * * bash /root/get_date.sh
root@88f5bb1f0a08:/# ls -ltrh ~/date.out
-rw-r--r-- 1 root root 29 Nov 15 14:31 /root/date.out
root@88f5bb1f0a08:/# cat /root/date.out
Mon Nov 15 14:31:01 UTC 2021
3. Службы Cron — подход к работе с контейнерами
Кроме того, мы можем настроить службы cron
в контейнерах Docker для запуска заданий cron .
Итак, каков порядок действий?
Давайте быстро запустим контейнер ubuntu с помощью команды
запуска docker
. Обычно контейнеры представляют собой облегченную ОС, которая не включает службы cron в качестве пакета по умолчанию.
Итак, нам нужно попасть в интерактивную оболочку контейнера и установить службы cron
с помощью команд репозитория apt
:
$ docker run -it ubuntu:latest /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
root@77483fc20fc9:/#
root@77483fc20fc9:/# which cron
root@77483fc20fc9:/# apt update -y
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
...
... output truncated ...
...
All packages are up to date.
root@77483fc20fc9:/# apt upgrade -y
...
... output truncated ...
...
root@77483fc20fc9:/# apt install cron vim -y
Reading package lists... Done
...
... output truncated ...
...
Done.
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
root@77483fc20fc9:/# which cron
/usr/sbin/cron
$ docker cp get_data.sh 77483fc20fc9: /root/get_date.sh
Мы можем использовать команду docker cp
, чтобы скопировать get_date.sh
с хоста в контейнер. crontab -e
редактирует задание cron
с помощью редактора vi .
Приведенная ниже конфигурация cron
запускает скрипт каждую минуту. Кроме того, в выводе указывается временная метка выполнения скрипта:
root@77483fc20fc9:/# export EDITOR=vi
root@77483fc20fc9:/# crontab -e
* * * * * bash /root/get_date.sh
root@77483fc20fc9:/# date
Mon Nov 17 11:15:21 UTC 2021
root@77483fc20fc9:/# ls -ltrh ~/date.out
ls: cannot access '/root/date.out': No such file or directory
root@77483fc20fc9:/# ls -ltrh /root/get_date.sh
-rw-r--r-- 1 root root 18 Nov 17 11:09 /root/get_date.sh
root@77483fc20fc9:/# ls -ltrh ~/date.out
-rw-r--r-- 1 root root 29 Nov 17 11:16 /root/date.out
root@77483fc20fc9:/# cat /root/date.out
Mon Nov 17 11:16:01 UTC 2021
4. Вывод
Подводя итог, мы изучили основы запуска заданий cron
внутри контейнера Docker. Метод использования Dockerfile встраивает в образ cron
- сервисы и задачи , которые автоматически выполняют скрипт в соответствии с конфигурацией cron -расписания.
Хотя cron
можно установить и настроить в работающем контейнере, это всего лишь конструкция времени выполнения, если только мы не создадим образ с помощью docker commit
.
Кроме того, оба варианта имеют свои преимущества в зависимости от наших условий использования.