Po přesunu cron úloh do Docker kontejnerů jsme zaznamenali výrazné přetížení serveru. Počet a logika úloh se nezměnily – změnil se jen způsob jejich spouštění. To nás přimělo k hlubšímu zkoumání příčin.
Hledání příčiny
Nejprve jsme nastavili monitoring spotřeby zdrojů podle procesů. Nasadili jsme process-exporter a připravili samostatný dashboard. Snažili jsme se odlišit zdroje zátěže podle:
- Python procesů
- docker-compose procesů
- Procesů spojených s Docker shim
Data ukázala, že hlavním zdrojem zátěže byly Python procesy. Docker procesy samy o sobě velkou zátěž nevytvářely. Otázka ale zůstávala – proč se přetížení objevilo až po přechodu na Docker-based crony?
Formulace hypotéz
Podezírali jsme dvě hlavní příčiny:
process-exportermohl mít příliš nízkou frekvenci vzorkování, nebo sám vytvářel vysokou zátěž (prochází celý/proc, který během burstů může obsahovat přes 5 000 PIDů)- Způsob startu Docker kontejnerů mohl skrývat reálný overhead: kontejner připravuje
runc init, následuje řada systémových operací před spuštěním cílového příkazu. Tyto krátkodobé špičky nemusí být běžným monitoringem zachyceny.
Původní cron konfigurace
Před optimalizací byly cron úlohy spouštěny takto:
docker-compose run --rm app python script.py arguments
Každá úloha vytvořila nový kontejner, který byl po dokončení odstraněn.
Optimalizace
Zavedli jsme perzistentní kontejner běžící na pozadí:
docker-compose run --rm -d --name cron-runner app bash -c "while :; do sleep 60; done"
A změnili jsme cron tak, aby spouštěl příkazy přes docker exec do existujícího kontejneru:
docker exec cron-runner python script.py arguments
Výsledky
Průměrné zatížení
Po přechodu na docker exec průměrné zatížení výrazně kleslo. Na grafu z 11. března 2025 (06:00–22:00) je patrný pokles po ~15:50, kdy došlo ke změně.

Využití CPU
Zátěž CPU se změnila z plošné na „pichlavou“ – vyšší, ale krátké špičky namísto širokých, nízkých vln. To znamená efektivnější využití procesoru.


Pokles IO
Také se snížila zátěž na disk v intervalu 14:00–18:00.

Analýza
Overhead nebyl způsoben samotným Dockerem, ale nesprávným použitím. Každý docker-compose run prováděl:
- nový proces
runc - vytvoření namespace
- mount přes overlayfs
- forkování a konfiguraci
- spuštění cílového příkazu přes
exec
Všechny tyto kroky konzumují systémové prostředky ještě před tím, než dojde ke spuštění samotné úlohy.
Závěr
Pokud zaznamenáte přetížení serveru po dockerizaci cron úloh, zvažte vyhnutí se docker run nebo docker-compose run pro každou jednotlivou úlohu. Místo toho použijte dlouhodobě běžící kontejner a docker exec. Tím se výrazně sníží overhead a zlepší efektivita CPU a IO.