/ February 6, 2018/ docker, linux/ 0 comments

A folyamatok Linux alatt faszerkezetbe rendeződnek. Az első indított folyamat az 1-es azonosítót kapja, ezt ‘init’-nek hívjuk. Szülője a rendszermag, a 0-s azonosítójú. Ha az 1-es folyamat meghal, a rendszer elpánikol és újra kell indítani.

Névteret az unshare rendszerhívással hozhatunk létre. Ahogy meghívjuk a folyamatunk az általában üres új névtérben találja magát. Kivétel ez alól a PID névtér, mert itt fork-olni kell a folyamatot, ami után ő lesz az 1-es. Persze “kívülről” nézve egy teljesen más azonosítója is lesz.

Az 1-es számú

Az 1-es számú folyamatnak kiváltságai vannak:

  • nem válaszol alapértelmezetten minden neki küldött jelzésre (például ctrl+c, docker kill)
  • ha egy folyamat meghal a gyermeke előtt, a gyermek szülője az 1-es számú folyamat lesz
  • ha meghal az 1-es, minden más folyamat is vele megy és az egész névtér megy a levesbe

Docker esetén

Docker esetén az entrypoint vagy cmd által megadott folyamat lesz az 1-es. Ez azért kényelmetlen, mert ezt a parancsot általában nem készítették fel arra, hogy ő az 1-es. 

A zombi kaszálás problémája

Ha egy folyamat váratlanul leáll, zombi folyamattá válik. Az operációs rendszer küld a szülőjének egy SIGCHLD jelzést, ő meg a zombi gyereket egy waitpid()-el lekaszálja.

Mi van akkor, ha közben a szülő folyamat eltűnik? A gyerek “árva” lesz. Ekkor az init folyamat “örökbe fogadja”. A zombi viszont továbbra is foglal egy helyet a PID táblában és ha ez a tábla megtelik, az nem jó. Tehát docker esetén ajánlott lenne init rendszert használni.

Az init rendszer

Tehát kell egy olyan rendszer, ami el tud indítani egy másik programot és le tudja kaszálni az örökbe fogadott folyamatokat. Az init rendszer ami eleget tesz a fenti két követelménynek már ott is van a gépen. A neve: bash.

Tehát ezentúl ez helyett:

CMD ["/path-to-your-app"]

írjuk ezt:

CMD ["/bin/bash", "-c", "set -e && /path-to-your-app"]

Megoldottuk a problémát. Kivéve, hogy ha kill jelzést küldünk a bash-nek, ott marad a programunk szülő nélkül és ha épp lemezműveletet végzett, akkor az félbemarad. Docker stop esetén SIGTERM-et kap a bash, ezt el kéne küldenie a programunknak és várni rá hogy az értelmesen reagáljon, majd lekezelni a helyzetet. De ezt nem tudja. Kell mégiscsak egy init rendszer…

A megoldás

Nincs rendes megoldás. Ha zombi folyamatokat látunk a konténerünkben, akkor magunknak kell megoldani a problémát. Ha nem látunk, akkor akár hagyhatjuk is így. Vagy használjuk a baseimage képet a dockerhub-ról.

Share this Post

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.