Docker logolás, hibakeresés

Szerző: Ványi Albert |

A docker konténerekkel kapcsolatos üzemeltetés sarkalatos pontja a hibakeresés. A bejegyzésben végig vezetlek néhány hasznos parancson, mely jól jöhet, ha valami gond van a konténer futtatásával.

Alap eszközök

Futó konténerek lekérdezése:

docker ps

Az összes konténer lekérdezése:

docker ps -a

Futó konténer log:

docker logs 

Ha a hiba jellege olyan, hogy nem tudjuk elindítani a kontainer-t, akkor készíthetünk a konténerből egy image-t. Ezt követően az így létrehozott image-ből indítunk egy konténert, amibe belépve megkereshetjük a hiba logokat, tehát konténerből image:

docker commit 

Ha az előző nem vezet célra, akkor próbálkozhatunk azzal, hogy ki exportáljuk egy tar fájlba a konténert, így az archiv állományt megnyitva böngészhetjük a tartalmát:

docker export  > pelda.tar

Megnézhetjük azt is, hogy az alap image-ből indított- és a jelenlegi állapota között milyen differenciák vannak:

docker diff 

Amennyiben tudjuk egy – a konténerben lévő – állomány elérési útját, akkor azt ki is másolhatjuk:

docker cp :/file_path /error.log 

Abban az esetben, ha a yaml fájlban kell változtatnunk valamit, akkor az alábbi utasítással érvényesíthetjük a változtatást:

docker-compose build
docker-compos up -d

Az alábbi utasítással magáról a konténerről kaphatunk információt:

docker inspect 

Belépés futó konténerbe, ha van benne bash, vagy sh:

docker exec -ti  /bin/bash

Haladó hibakeresés

Ha a logok átnézésével nem boldogulunk, haladóbb eszközöket is igénybe vehetünk. A kernel és az egyes eszközök között zajló rendszerhívásokat le lehet kérni. Ennek eszköze a strace parancsal. Ilyen rendszerhívás lehet például amikor a php egy állományt: megnyit, olvas, vagy ír. A strace parancs használatához tudnunk kell a megfigyelni kívánt rendszerhívás process id-jét. Ezt az alábbi paranccsal kereshetjük meg, mely az aktuális rendszerhívásokat adja:

ps auwfx

A kimenet bonyolult lehet és sok- számunkra nem releváns információt is tartalmaz. Ahhoz, hogy szűkítsük a kört a megfigyelni kívánt konténer aktuális rendszerhívásait is lekérdezhetjük:

docker top 

A strace parancs -p kapcsolója után adjuk meg a process id-t. Az alábbi script segítségével csak a számunkra fontos információkhoz juthatunk:

strace $(ps auwfx | grep php-fpm | awk '{print $2}' | xargs -i echo -n " -p {}")

Alapértelmezésben a srting információt kasztolja a strace ahhoz, hogy a hosszabb kimenetet láthassuk, használjuk a -s kapcsolót:

sstrace -s 999 $(ps auwfx | grep php-fpm | awk '{print $2}' | xargs -i echo -n " -p {}")

A -f kapcsoló alkalmazásával a szolgáltatás által – menet közben – indított új folyamatokat is követi. További lehetőség a -trace szűrő, mellyel az egyes rendszerhívásokra korlátozhatjuk a kimenetet:

strace -s 999 -f -trace=open,write,read $(docker top  | grep php-fpm | awk ` {print $2}` | xargs -i echo -n " -p {})"

Ha kíváncsiak vagyunk hogy mit is jelent a write hívás, a man 2-ből tudhatjuk meg, így láthatjuk, hogy ez a függvény milyen paraméterekkel dolgozik.:

man 2 write

Ha meg akarjuk tudni, hogy egy szálban milyen descriptorok vannak nyitva:

ls -la /proc/fd

Konténer belső folyamatai

Eddig a konténeren kívül – a gazdagép és a konténer között – tudtuk használni a strace -t. Hogyan tudnánk ezt belől megtenni?

Hálózati forgalom megfigyelése, ahol a “-x” csomagtartalmat mutat:

tcpdump -i eth0 port 9000 -x

A fast-cgi sokkal olvashatóbb a tcpflow-al:

tcpflow -i eth0 -c port 9000

A docker konténerrel kapcsolatos történések lekérése:

docker history <image-név>

Syslog szerverhez történő csatolása a konténer naplózásához. A beállítást a yaml fájlban lehet megadni, lássunk egy példát:

apache:
[...]
logging:
   driver: syslog
   options:
    syslog-address: "udp://logs3.papertrailapp.com:15516" #csak példa
	tag: "{{.Name}/{.ID}}"
#A logging: bejegyzést minde olyan konténernél specifikálni kell, ahol el kívánjuk
#küldeni a logokat a külső szerver felé.
#A tag megadása opcionális, a fenti példával a kontér neve is elküldésre kerül.
#A tag megadása nélkül csak a container id-t látjuk a logokban.
  depends_on:
   - php
[...]

Megjegyzés: Ingyenes külső log szervert is használhatunk papertrailapp.com. Regisztráció után használhatjuk a szolgáltatást.

Másik megoldás lehet a logspout, ami egy image. Minta szerint kell specifikálni, majd miután elindítjuk a belőle létrehozott konténert, az gyűjti be a további konténerek logjait és küldi tovább a külső szerver felé.