Veikia sistemingai konteineryje

Systemd naudojimo konteineriuose temą sekėme jau seniai. 2014 m. mūsų saugumo inžinierius Danielis Walshas parašė straipsnį Sistema veikia Docker konteineryje, o po poros metų – kitą, kuri vadinosi Sistema veikia neprivilegijuotoje talpykloje, kuriame jis teigė, kad padėtis nelabai pagerėjo. Visų pirma, jis rašė, kad „deja, net po dvejų metų, jei paieškote „Docker system“, pirmas dalykas, kuris pasirodo, yra jo senas straipsnis. Taigi laikas ką nors pakeisti“. Be to, mes jau kalbėjome apie konfliktas tarp Docker ir sistemos kūrėjų.

Veikia sistemingai konteineryje

Š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:

  1. 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.
  2. 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ą.
  3. 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 Kubernetes arba „OpenShift“ tikimasi, kad konteineriai įrašys žurnalą tiesiai į stdout ir stderr. Todėl, jei ketinate tvarkyti konteinerius naudodami orkestravimo įrankius, tokius kaip pirmiau minėtieji, turėtumėte rimtai apsvarstyti galimybę naudoti sisteminius konteinerius. Be to, „Docker“ ir „Moby“ kūrėjai dažnai griežtai priešinosi „systemd“ naudojimui konteineriuose.

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 savo konteinerio variklį. Jis gavo vardą Podmanas ir siūlo tą pačią komandų eilutės sąsają (CLI) kaip ir Docker. Ir beveik visos „Docker“ komandos „Podman“ gali būti naudojamos vienodai. Dažnai vedame seminarus, kurie dabar vadinami Docker keitimas į Podman, o pati pirmoji skaidrė ragina rašyti: slapyvardis docker=podman.

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. straipsnis.)

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

Добавить комментарий