Blog

  • Početna
  • Objave
docker_load_average

Nakon što smo cron zadatke prebacili u Docker kontejnere, primijetili smo značajno preopterećenje poslužitelja. Broj i logika zadataka nisu se promijenili – promijenjen je samo način izvođenja. To nas je navelo na dublju analizu uzroka.

Identifikacija uzroka

Prvi korak bio je postaviti nadzor korištenja resursa po procesima. Pokrenuli smo process-exporter i napravili posebnu nadzornu ploču. Pokušali smo razlikovati izvore opterećenja:

  1. Python procesi
  2. docker-compose procesi
  3. Procesi povezani s Docker shimom

Podaci su pokazali da su Python procesi odgovorni za najveći dio opterećenja. Docker procesi nisu stvarali značajan overhead. No ostalo je pitanje – zašto se opterećenje pojavilo tek nakon prelaska na Docker-based cronove?

Postavljanje hipoteza

Sumnjali smo na dvije glavne stvari:

  • process-exporter možda ima prenisku frekvenciju uzorkovanja, ili sam generira preveliko opterećenje (obilazi cijeli /proc, koji može imati preko 5000 PID-ova tijekom burstova)
  • Način pokretanja Docker kontejnera može prikriti stvarni overhead: kontejner se priprema pomoću runc init, a zatim slijedi više pripremnih koraka prije pokretanja stvarne naredbe. Takvi prolazni resursni skokovi mogu biti nevidljivi standardnim monitoringom.

Prethodna cron konfiguracija

Prije optimizacije, cron zadaci su se pokretali ovako:

docker-compose run --rm app python script.py arguments

Svaki zadatak je stvorio novi kontejner koji se nakon izvršavanja odmah briše.

Optimizacija

Uveli smo jedan trajni pozadinski kontejner koji ostaje aktivan:

docker-compose run --rm -d --name cron-runner app bash -c "while :; do sleep 60; done"

Zatim smo promijenili cron da koristi docker exec za pokretanje naredbi unutar postojećeg kontejnera:

docker exec cron-runner python script.py arguments

Rezultati

Prosječno opterećenje (Load Average)

Nakon prelaska na docker exec, prosječno opterećenje značajno je palo. Na grafikonu od 11. ožujka 2025. (06:00–22:00) vidi se jasan pad nakon ~15:50 kada je promjena uvedena.

CPU korištenje

CPU opterećenje postalo je izraženije u kraćim, intenzivnijim skokovima, umjesto širokih i blagih valova. To znači učinkovitije korištenje procesora.

Smanjenje IO

Primijećeno je i smanjenje diskovnog IO između 14:00 i 18:00 istoga dana.

Analiza

Overhead nije uzrokovao sam Docker, već nepravilno korištenje Dockera. Svaki docker-compose run pokreće:

  • novi runc proces
  • kreira namespace
  • montira slojeve preko overlayfs
  • forka i konfigurira kontejner
  • konačno, pokreće ciljani exec naredbu

Ti koraci troše značajne resurse prije nego što stvarna naredba uopće započne.

Zaključak

Ako nakon dockerizacije cron zadataka primijetite neočekivana opterećenja poslužitelja, izbjegavajte pokretanje zasebnog kontejnera za svaki zadatak. Umjesto toga, koristite trajni kontejner i docker exec. Time se značajno smanjuje overhead i poboljšava učinkovitost CPU-a i IO-a.

Preporučeno čitanje