Systeemi toimii säiliössä

Olemme seuranneet systemd:n ​​käyttöä konteissa jo pitkään. Vuonna 2014 turvallisuusinsinöörimme Daniel Walsh kirjoitti artikkelin Järjestelmä toimii Docker Containerissa, ja pari vuotta myöhemmin - toinen, jota kutsuttiin Toimii järjestelmässä ei-etuoikeutetussa säiliössä, jossa hän totesi, ettei tilanne ollut juurikaan parantunut. Erityisesti hän kirjoitti, että "valitettavasti jopa kaksi vuotta myöhemmin, jos googlettaa "Docker system", ensimmäinen asia, joka tulee esiin, on hänen sama vanha artikkeli. Joten on aika muuttaa jotain." Lisäksi olemme jo puhuneet ristiriita Dockerin ja järjestelmäkehittäjien välillä.

Systeemi toimii säiliössä

Tässä artikkelissa näytämme, mikä on muuttunut ajan myötä ja kuinka Podman voi auttaa meitä tässä asiassa.

On monia syitä ajaa systemd säilössä, kuten:

  1. Monipalvelukontit – Monet ihmiset haluavat vetää monipalvelusovelluksensa virtuaalikoneen ulkopuolelle ja käyttää niitä konteissa. Olisi tietysti parempi jakaa tällaiset sovellukset mikropalveluihin, mutta kaikki eivät vielä osaa tehdä tätä tai heillä ei yksinkertaisesti ole aikaa. Siksi tällaisten sovellusten suorittaminen yksikkötiedostoista systemd:n ​​käynnistäminä palveluina on täysin järkevää.
  2. Järjestelmän yksikkötiedostot – Suurin osa konteissa pyörivistä sovelluksista on rakennettu koodista, joka on aiemmin toiminut virtuaalisilla tai fyysisillä koneilla. Näillä sovelluksilla on yksikkötiedosto, joka on kirjoitettu näitä sovelluksia varten ja ymmärtää, kuinka ne pitäisi käynnistää. Joten on silti parempi aloittaa palvelut tuetuilla menetelmillä sen sijaan, että hakkeroitaisi omaa aloituspalveluasi.
  3. Systemd on prosessipäällikkö. Se hallitsee palveluita (sammuttaa, käynnistää palvelut uudelleen tai tappaa zombie-prosessit) paremmin kuin mikään muu työkalu.

Siitä huolimatta, on monia syitä olla käyttämättä systemdiä konteissa. Tärkein niistä on, että systemd/journald ohjaa konttien ja työkalujen, kuten esim Kubernetes tai OpenShift oletetaan, että säilöt kirjoittavat lokin suoraan stdout- ja stderr-tiedostoihin. Siksi, jos aiot hallita säilöjä yllämainittujen kaltaisten orkestrointityökalujen avulla, sinun tulee vakavasti harkita systemd-pohjaisten säiliöiden käyttöä. Lisäksi Docker- ja Moby-kehittäjät ovat usein vastustaneet jyrkästi systemd:n ​​käyttöä konteissa.

Podmanin tulo

Olemme iloisia voidessamme kertoa, että tilanne on vihdoin mennyt eteenpäin. Red Hatin konttien pyörittämisestä vastaava tiimi päätti kehittää oma konttimoottori. Hän sai nimen podman ja tarjoaa saman komentoriviliittymän (CLI) kuin Docker. Ja melkein kaikkia Docker-komentoja voidaan käyttää Podmanissa samalla tavalla. Järjestämme usein seminaareja, joita nykyään kutsutaan ns Dockerin vaihtaminen Podmaniksi, ja aivan ensimmäinen dia vaatii kirjoittamista: alias docker=podman.

Monet ihmiset tekevät juuri niin.

Podmanini ja minä emme ole millään tavalla systemd-pohjaisia ​​säiliöitä vastaan. Loppujen lopuksi Systemd on yleisimmin käytetty Linuxin init-alijärjestelmä, ja jos sen ei anneta toimia kunnolla säilöissä, jätetään huomiotta, kuinka tuhannet ihmiset ovat tottuneet käyttämään säiliöitä.

Podman tietää, mitä tehdä, jotta järjestelmä toimisi kunnolla säiliössä. Se vaatii esimerkiksi tmpfs:n asentamisen /run- ja /tmp-tiedostoihin. Hän pitää "säilötyn" ympäristön käytöstä ja odottaa kirjoitusoikeuksia cgroup-hakemiston osaansa ja /var/log/journald-kansioon.

Kun käynnistät säilön, jossa ensimmäinen komento on init tai systemd, Podman määrittää automaattisesti tmpfs- ja Cgroups-asetukset varmistaakseen, että systemd käynnistyy ilman ongelmia. Voit estää tämän automaattisen käynnistystilan valitsemalla --systemd=false. Huomaa, että Podman käyttää systemd-tilaa vain, kun se näkee, että sen on suoritettava systemd- tai init-komento.

Tässä ote ohjeesta:

mies podman juokse
...

–systemd=true|false

Säilön ajaminen systemd-tilassa. Oletuksena käytössä.

Jos suoritat systemd- tai init-komennon säilön sisällä, Podman määrittää tmpfs-liitoskohdat seuraaviin hakemistoihin:

/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal

Myös oletuspysäytyssignaali on SIGRTMIN+3.

Kaikki tämä mahdollistaa systemd:n ​​käytön suljetussa säiliössä ilman muutoksia.

HUOMAUTUS: systemd yrittää kirjoittaa cgroup-tiedostojärjestelmään. SELinux kuitenkin estää säilöjä tekemästä tätä oletuksena. Ota kirjoittaminen käyttöön ottamalla käyttöön container_manage_cgroup boolean-parametri:

setsebool -P container_manage_cgroup true

Katso nyt, miltä Dockerfile näyttää, kun systemd ajetaan säilössä Podmanin avulla:

# cat Dockerfile

FROM fedora

RUN dnf -y install httpd; dnf clean all; systemctl enable httpd

EXPOSE 80

CMD [ "/sbin/init" ]

Siinä kaikki.

Nyt kokoamme kontin:

# podman build -t systemd .

Pyydämme SELinuxia sallimaan systemd:n ​​muokata Cgroups-kokoonpanoa:

# setsebool -P container_manage_cgroup true

Muuten, monet ihmiset unohtavat tämän vaiheen. Onneksi tämä täytyy tehdä vain kerran ja asetus tallennetaan järjestelmän uudelleenkäynnistyksen jälkeen.

Nyt aloitamme vain kontin:

# 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.

Siinä kaikki, palvelu on käynnissä:

$ curl localhost

<html  xml_lang="en" lang="en">

…

</html>

HUOMAA: Älä kokeile tätä Dockerissa! Siellä sinun on vielä tanssittava tamburiinilla päästääksesi tällaisia ​​​​säiliöitä demonin läpi. (Lisäkenttiä ja -paketteja tarvitaan, jotta tämä kaikki toimisi saumattomasti Dockerissa, tai se on suoritettava etuoikeutetussa säilössä. Lisätietoja on kohdassa статье.)

Pari muuta hienoa asiaa Podmanista ja systemdistä

Podman toimii paremmin kuin Docker systemd-yksikkötiedostoissa

Jos kontit on käynnistettävä järjestelmän käynnistyessä, voit yksinkertaisesti lisätä asianmukaiset Podman-komennot systemd-yksikkötiedostoon, joka käynnistää palvelun ja valvoo sitä. Podman käyttää tavallista fork-exec-mallia. Toisin sanoen konttiprosessit ovat Podman-prosessin lapsia, joten systemd pystyy helposti valvomaan niitä.

Docker käyttää asiakas-palvelinmallia, ja Dockerin CLI-komennot voidaan sijoittaa myös suoraan yksikkötiedostoon. Kuitenkin, kun Docker-asiakas muodostaa yhteyden Docker-daemoniin, siitä (asiakkaasta) tulee vain toinen prosessinkäsittely stdin ja stdout. Systemdillä ei puolestaan ​​ole aavistustakaan Docker-asiakkaan ja Docker-daemonin hallinnassa toimivan kontin välisestä yhteydestä, joten tässä mallissa systemd ei voi pohjimmiltaan valvoa palvelua.

Järjestelmän aktivointi pistorasian kautta

Podman käsittelee aktivoinnin pistorasian kautta oikein. Koska Podman käyttää fork-exec-mallia, se voi välittää socketin alisäiliöprosesseihinsa. Docker ei voi tehdä tätä, koska se käyttää asiakas-palvelin-mallia.

Varlink-palvelu, jolla Podman kommunikoi etäasiakkaiden kanssa konteihin, aktivoidaan itse asiassa pistorasian kautta. Cockpit-podman-paketti, joka on kirjoitettu Node.js:ssä ja osa ohjaamoprojektia, antaa ihmisille mahdollisuuden olla vuorovaikutuksessa Podman-säiliöiden kanssa verkkokäyttöliittymän kautta. Cockpit-podmania ajava web-daemon lähettää viestejä varlink-liitäntään, jota systemd kuuntelee. Systemd aktivoi sitten Podman-ohjelman vastaanottaakseen viestejä ja aloittaakseen säilöjen hallinnan. Systemd:n ​​aktivointi socketin kautta eliminoi jatkuvasti käynnissä olevan demonin tarpeen etäsovellusliittymiä toteutettaessa.

Lisäksi kehitämme toista Podman-asiakasta nimeltä podman-remote, joka toteuttaa saman Podmanin CLI:n, mutta kutsuu varlinkiä ajamaan säiliöitä. Podman-remote voi toimia SSH-istuntojen päällä, jolloin voit olla turvallisesti vuorovaikutuksessa eri koneiden säiliöiden kanssa. Ajan myötä aiomme ottaa podman-remoten käyttöön MacOS:n ja Windowsin tukemisen Linuxin rinnalla, jotta näiden alustojen kehittäjät voivat käyttää Linux-virtuaalikonetta, jossa on Podman varlink, ja heillä on täysi kokemus siitä, että kontit toimivat paikallisessa koneessa.

SD_NOTIFY

Systemd antaa sinun lykätä apupalvelujen käynnistämistä, kunnes niiden tarvitsema konttipalvelu alkaa. Podman voi välittää SD_NOTIFY-pistokkeen konttipalveluun niin, että palvelu ilmoittaa järjestelmälle, että se on valmis toimimaan. Ja jälleen kerran, Docker, joka käyttää asiakas-palvelin-mallia, ei voi tehdä tätä.

Suunnitelmissa

Aiomme lisätä komennon podman generate systemd CONTAINERID, joka luo systemd-yksikkötiedoston tietyn määritetyn säilön hallitsemiseksi. Tämän pitäisi toimia sekä pääkäyttäjän että juurettomassa tilassa etuoikeutetuissa säilöissä. Olemme jopa nähneet pyynnön OCI-yhteensopivasta systemd-nspawn-ajoajasta.

Johtopäätös

Systemdin ajaminen kontissa on ymmärrettävä tarve. Ja Podmanin ansiosta meillä on vihdoin konttiajoaika, joka ei ole ristiriidassa systemd:n ​​kanssa, mutta tekee siitä helppokäyttöisen.

Lähde: will.com

Lisää kommentti