Docker a Cron

4. srpna 2020

K napsání tohoto článku mě přiměla zkušenost s projekty, které používají Docker, ale ne tak jak by se mělo.
Dostal jsem se například k projektu, kde po restartu serveru projekt neběžel a krom jiných problémů neběžel cron. Nebo jiný projekt, kde Cron spouštěl nefunkční úlohy, ale nikdo se o tom nedozvěděl.

Docker a služby

Docker je kontejnerová virtualizace. A při jeho použití zároveň sebe-dokumentujete projekt. Aby se využila síla a výhody kontejnerové virtualizace: dohled, nezávislost, upravitelnost, horizontální škálování, je potřeba, aby v každém kontejneru běžel pouze jeden hlavní program (služba). Program může mít více vláken nebo procesů. Můžete se třeba jednorázově do kontejnery přihlásit a spustit další programy, ale právě ten hlavní program je sledován zdali běží.
Následně můžete spouštěním identických kontejnerů i aplikaci horizontálně škálovat a dosáhnout tak většího výkonu aplikace.
Situace kdy tedy krom hlavního programu v kontejneru běží ještě další služba (například cron) je tedy špatně.

Docker image

Předpřipravené základní image spouští právě jednu službu. Ano, jde upravit image, aby krom hlavního programu se automaticky spouštěli i další (např cron), když ale druhodný program nepoběží o problému se běhové prostředí (docker, docker swarm, kubernetes) nedozví, tedy ani vy pokud aplikaci nebo kontejner neupravíte jinak.
Ale hlavně právě takto sleduje běh kontejnerů běhové prostředí - například Kubernetes. Také daný návrh řešení vám nespíš neumožní škálovat bez dalších úprav.
Ano najdou se usecase, kdy je vhodné pustit cron ve stejném kontejneru, ale to bude případ závislý na specifičnosti aplikace/projektu.

Co je to Cron

Pod pojmem Cron lidi chápou pravidelné spouštění programů nebo zápis konfigurace typický pro Cron. Implementačně je Cron program, který se automaticky spouští po startu v unixových systémech, neustále běží a sám pak dle zadané konfigurace spouští pravidelně dané úlohy.

Jak spouštět cron úlohy v dockeru?

Pro provoz cronu v Dockeru je tedy třeba mít Cron nainstalovaný, spuštěný a zadat mu konfiguraci.

Při zprovoznění cronu v dockeru, můžeme vyjít z libovolného image buď základního nebo již nějakého, kde máte potřebné komponenty. Do toho image doinstalujete cron a nakonfigurujete docker image tak, aby cron spouštěl.

Dále nahraďte soubor /etc/crontab vaši vlastní konfigurací pro cron.

Dockerfile pro cron, který vychází ze základního image Debianu, může vypadat takto:

FROM debian:buster
MAINTAINER Bc. Josef Jebavý

#cron
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections \
 && apt-get update && apt install cron curl wget jq -y && apt-get clean

# dalsi komponenty

COPY crontab /etc/crontab
CMD [ "/usr/sbin/cron","-f","-L /dev/stdout" ]

Výsledkem je image, z kterého spustíte kontejner, v němž poběží cron, který je nezávislý na ostatních službách/aplikací. Při pádu cronu se o pádu dozvíte a typicky v kubernetes bude daný kontejner automaticky restartován.
Výsledné seskupené komponent aplikace pak bude, že v mnoha samostatných kontejnerech můžou běžet různé části aplikace, některé i vícekrát a vedle toho jeden jediný samostatný kontejner s cronem.

Konfigurační soubor pro cron můžete také připojovat při startu kontejneru. To se hodí například pokud by jste potřebovali konfiguraci ladit na vývojovém prostředí, protože pak nemusíte neustále buildit a spouštět nový kontejner.

Příklad cron souboru:

# crontab copy to docker
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

PHP7=/usr/bin/php7.2
PHP5=/usr/bin/php5.6
# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etcocron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

* *    * * *   root    date >> /var/www/html/log/cron-test.txt

1,31 * * * * root ( ${PHP5} /var/www/html/cron/10-update.php) >> /var/www/html/log/cron.log 2>&1

Řešení na míru

Protože programátor je odborník na vývoj softwaru, tak přípravu kontejnerů a návrh běhového produkčního prostředí by jste měli nechat na odborníky z oblasti Linuxu a dockeru.

Články na podobné téma

Operační systém GNU/Linux
Jak začít správně používat Docker
Příprava linuxového serveru pro běh webové aplikaci v jazyce Python
Jak řešit špatný výkon sdílených souborů u Dockeru
GitLab - nástroj na správu, verzování, CI/CD a vedení projektů
Instalace Linuxu na dedikovaný server HPE ProLiant DL320e
Jak provést zátěžový test webové aplikace
Proč používat filesystém JFS
Jak bootovat z 4TB disku s GTP pomocí UEFI
Jak nainstalovat operační systém Magei Linux bez DVD mechaniky
Souborový systém Btrfs
Raspberry PI
Jak zprovoznit vzdálené přehrávání přes síť na televizi s DLNA
Upgrade Mandriva Linuxu za běhu
Poznámky ke GNU/Linux
WINE - spouštíme programy pro Windous pod Linuxem
Yocto Project: Build vlastního operačního sytému pro embedded zařízení
Lenovo ThinkPad X1 Carbon: zprovoznění LTE modemu EM7544
Docker a Cron
Virtualizace Proxmox