Systemd naudojimo konteineriuose temą sekėme jau seniai. 2014 m. mūsų saugumo inžinierius Danielis Walshas parašė straipsnį
Šiame straipsnyje parodysime, kas pasikeitė laikui bėgant ir kaip „Podman“ gali mums padėti šiuo klausimu.
Yra daug priežasčių, kodėl sistemą reikia paleisti konteineryje, pavyzdžiui:
- Daugiafunkciniai konteineriai – Daugelis žmonių nori išimti savo kelių paslaugų programas iš virtualių mašinų ir paleisti jas konteineriuose. Žinoma, būtų geriau tokias programas suskaidyti į mikropaslaugas, tačiau dar ne visi žino, kaip tai padaryti, arba tiesiog neturi laiko. Todėl paleisti tokias programas kaip paslaugas, kurias systemd paleido iš vienetinių failų, yra visiškai prasminga.
- Sisteminio vieneto failai – Dauguma konteineriuose veikiančių programų yra sukurtos iš kodo, kuris anksčiau buvo paleistas virtualiose arba fizinėse mašinose. Šios programos turi vienetinį failą, kuris buvo parašytas šioms programoms ir supranta, kaip jas reikia paleisti. Taigi vis tiek geriau pradėti paslaugas naudojant palaikomus metodus, o ne įsilaužti į savo pradinę paslaugą.
- Systemd yra procesų valdytojas. Jis valdo paslaugas (išsijungia, iš naujo paleidžia paslaugas arba naikina zombių procesus) geriau nei bet kuris kitas įrankis.
Tai reiškia, kad yra daug priežasčių neleisti sistemos konteineriuose. Pagrindinis iš jų yra tas, kad systemd/journald kontroliuoja konteinerių išvestį ir tokius įrankius
Podmano atėjimas
Džiaugiamės galėdami pranešti, kad padėtis pagaliau pajudėjo į priekį. Komanda, atsakinga už „Red Hat“ konteinerių eksploatavimą, nusprendė kurti
Daugelis žmonių tai daro.
Mano „Podman“ ir aš jokiu būdu neprieštaraujame sisteminiams konteineriams. Juk „Systemd“ yra dažniausiai naudojama „Linux init“ posistemė, o neleidus jai tinkamai veikti konteineriuose reiškia ignoruoti, kaip tūkstančiai žmonių yra įpratę naudoti konteinerius.
„Podman“ žino, ką daryti, kad sistema tinkamai veiktų konteineryje. Tam reikia tokių dalykų kaip tmpfs prijungimas prie /run ir /tmp. Jai patinka, kad būtų įjungta „konteinerių“ aplinka ir ji tikisi rašymo teisių į savo cgroup katalogo dalį ir aplanką /var/log/journald.
Kai paleidžiate konteinerį, kuriame pirmoji komanda yra init arba systemd, „Podman“ automatiškai sukonfigūruoja tmpfs ir Cgroups, kad užtikrintų, jog „systemd“ būtų paleista be problemų. Norėdami užblokuoti šį automatinio paleidimo režimą, naudokite parinktį --systemd=false. Atminkite, kad Podman naudoja systemd režimą tik tada, kai mato, kad reikia paleisti systemd arba init komandą.
Čia yra ištrauka iš vadovo:
vyras podman paleisti
...–systemd=true|false
Konteinerio paleidimas sisteminiu režimu. Įjungta pagal numatytuosius nustatymus.
Jei konteineryje paleisite komandą systemd arba init, Podman sukonfigūruos tmpfs prijungimo taškus šiuose kataloguose:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Taip pat numatytasis sustabdymo signalas bus SIGRTMIN+3.
Visa tai leidžia sistemai veikti uždarame konteineryje be jokių pakeitimų.
PASTABA: systemd bando rašyti į cgroup failų sistemą. Tačiau SELinux neleidžia konteineriams to padaryti pagal numatytuosius nustatymus. Norėdami įjungti rašymą, įgalinkite loginį parametrą container_manage_cgroup:
setsebool -P container_manage_cgroup true
Dabar pažiūrėkite, kaip atrodo „Dockerfile“, kai sistema veikia konteineryje naudojant „Podman“:
# cat Dockerfile
FROM fedora
RUN dnf -y install httpd; dnf clean all; systemctl enable httpd
EXPOSE 80
CMD [ "/sbin/init" ]
Tai viskas.
Dabar mes surenkame konteinerį:
# podman build -t systemd .
Mes nurodome SELinux leisti systemd modifikuoti Cgroups konfigūraciją:
# setsebool -P container_manage_cgroup true
Beje, daugelis žmonių pamiršta apie šį žingsnį. Laimei, tai reikia padaryti tik vieną kartą, o nustatymas išsaugomas iš naujo paleidus sistemą.
Dabar mes tiesiog pradedame konteinerį:
# podman run -ti -p 80:80 systemd
systemd 239 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid)
Detected virtualization container-other.
Detected architecture x86-64.
Welcome to Fedora 29 (Container Image)!
Set hostname to <1b51b684bc99>.
Failed to install release agent, ignoring: Read-only file system
File /usr/lib/systemd/system/systemd-journald.service:26 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.
Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)
[ OK ] Listening on initctl Compatibility Named Pipe.
[ OK ] Listening on Journal Socket (/dev/log).
[ OK ] Started Forward Password Requests to Wall Directory Watch.
[ OK ] Started Dispatch Password Requests to Console Directory Watch.
[ OK ] Reached target Slices.
…
[ OK ] Started The Apache HTTP Server.
Viskas, paslauga veikia:
$ curl localhost
<html xml_lang="en" lang="en">
…
</html>
PASTABA: nebandykite to „Docker“! Ten vis tiek reikia šokti su tamburinu, kad paleistumėte tokius konteinerius per demoną. (Kad visa tai veiktų sklandžiai Docker, reikės papildomų laukų ir paketų arba jis turės būti paleistas privilegijuotoje talpykloje. Daugiau informacijos žr.
Dar keletas įdomių dalykų apie „Podman“ ir „systemd“.
„Podman“ veikia geriau nei „Docker“ sistemos vienetų failuose
Jei konteinerius reikia paleisti, kai sistema paleidžiama, galite tiesiog įterpti atitinkamas Podman komandas į systemd unit failą, kuris paleis paslaugą ir ją stebės. „Podman“ naudoja standartinį „fork-exec“ modelį. Kitaip tariant, konteinerių procesai yra Podman proceso vaikai, todėl systemd gali lengvai juos stebėti.
„Docker“ naudoja kliento-serverio modelį, o „Docker“ CLI komandos taip pat gali būti dedamos tiesiai į vieneto failą. Tačiau kai „Docker“ klientas prisijungia prie „Docker“ demono, jis (klientas) tampa tik dar vienu proceso apdorojimo stdin ir stdout. Savo ruožtu „systemd“ neturi supratimo apie ryšį tarp „Docker“ kliento ir konteinerio, kurį valdo „Docker“ demonas, todėl šiame modelyje „systemd“ iš esmės negali stebėti paslaugos.
Sistemos aktyvinimas per lizdą
„Podman“ tinkamai tvarko aktyvavimą per lizdą. Kadangi „Podman“ naudoja „fork-exec“ modelį, jis gali persiųsti lizdą savo antriniams konteinerio procesams. „Docker“ to padaryti negali, nes naudoja kliento-serverio modelį.
Varlink paslauga, kurią Podman naudoja bendravimui su nuotoliniais klientais į konteinerius, iš tikrųjų suaktyvinama per lizdą. Cockpit-podman paketas, parašytas Node.js ir yra kabinos projekto dalis, leidžia žmonėms bendrauti su Podman konteineriais per žiniatinklio sąsają. Žiniatinklio demonas, kuriame veikia „cockpit-podman“, siunčia pranešimus į „varlink“ lizdą, kurio sistema klausosi. Tada „Systemd“ suaktyvina „Podman“ programą, kad gautų pranešimus ir pradėtų tvarkyti konteinerius. Suaktyvinus systemd per lizdą, diegiant nuotolines API nereikia nuolat veikiančio demono.
Be to, kuriame kitą „Podman“ klientą, vadinamą „podman-remote“, kuris įdiegia tą patį „Podman“ CLI, bet iškviečia varlink, kad paleistų konteinerius. „Podman-remote“ gali veikti virš SSH seansų, todėl galite saugiai bendrauti su skirtingų įrenginių konteineriais. Laikui bėgant planuojame įgalinti „podman-remote“ palaikyti „MacOS“ ir „Windows“ kartu su „Linux“, kad tų platformų kūrėjai galėtų paleisti „Linux“ virtualią mašiną su „Podman varlink“ ir naudotis visapusiška patirtimi, kad konteineriai veikia vietiniame kompiuteryje.
SD_NOTIFY
„Systemd“ leidžia atidėti pagalbinių paslaugų paleidimą, kol prasidės joms reikalinga konteinerinė paslauga. „Podman“ gali persiųsti SD_NOTIFY lizdą į konteinerinę paslaugą, kad paslauga praneštų sistemai, kad ji yra paruošta veikti. Ir vėl, Docker, kuris naudoja kliento-serverio modelį, negali to padaryti.
Planuose
Planuojame pridėti komandą podman generuoti systemd CONTAINERID, kuri sugeneruos systemd vieneto failą konkrečiam nurodytam konteineriui valdyti. Tai turėtų veikti tiek šakniniu, tiek bešakniu režimu neprivilegijuotiems konteineriams. Netgi matėme užklausą dėl su OCI suderinamo systemd-nspawn vykdymo laiko.
išvada
Sistemos veikimas konteineryje yra suprantamas poreikis. Ir „Podman“ dėka pagaliau turime konteinerio vykdymo laiką, kuris neprieštarauja „systemd“, bet leidžia jį lengvai naudoti.
Šaltinis: www.habr.com