Running systemd yn in kontener

Wy hawwe it ûnderwerp fan it brûken fan systemd yn konteners in lange tiid folge. Werom yn 2014 skreau ús feiligensingenieur Daniel Walsh in artikel Systemd útfiere binnen in Docker Container, en in pear jier letter - in oar, dat waard neamd Running systemd yn in net-privilegearre kontener, wêryn't er stelde dat de sitewaasje net folle ferbettere wie. Benammen skreau hy dat "spitigernôch, sels twa jier letter, as jo "Docker-systeem" googleje, it earste ding dat opkomt is syn itselde âlde artikel. Dus it is tiid om wat te feroarjen." Dêrneist hawwe wy al praat oer konflikt tusken Docker en systemd-ûntwikkelders.

Running systemd yn in kontener

Yn dit artikel sille wy sjen litte wat yn 'e rin fan' e tiid feroare is en hoe't Podman ús kin helpe yn dizze saak.

D'r binne in protte redenen om systemd yn in kontener út te fieren, lykas:

  1. Multiservice konteners - in protte minsken wolle har multi-service-applikaasjes út firtuele masines lûke en se yn konteners útfiere. It soe fansels better wêze om sokke applikaasjes yn mikrotsjinsten te brekken, mar net elkenien wit hoe't dit noch moat of hat gewoan net de tiid. Dêrom is it útfieren fan sokke applikaasjes as tsjinsten lansearre troch systemd fan ienheidsbestannen perfekt sin.
  2. Systemd Unit Files - De measte applikaasjes dy't rinne yn konteners binne boud fan koade dy't earder rûn op firtuele as fysike masines. Dizze applikaasjes hawwe in ienheidsbestân dat is skreaun foar dizze applikaasjes en begrypt hoe't se moatte wurde lansearre. Dat it is noch better om tsjinsten te begjinnen mei stipe metoaden, ynstee fan jo eigen init-tsjinst te hacken.
  3. Systemd is in prosesbehearder. It beheart tsjinsten (útsette, opnij starte tsjinsten, of deadet zombie-prosessen) better dan hokker oar ark.

Dat sei, d'r binne in protte redenen om systemd net yn konteners út te fieren. De wichtichste is dat systemd / journald de útfier fan konteners kontrolearret, en ark lykas Kubernetes of OpenShift ferwachtsje dat konteners log direkt nei stdout en stderr skriuwe. Dêrom, as jo konteners sille beheare fia orkestraasje-ark lykas de hjirboppe neamde, moatte jo serieus beskôgje it brûken fan systemd-basearre konteners. Derneist binne Docker- en Moby-ûntwikkelders faaks sterk tsjin it brûken fan systemd yn konteners.

De komst fan Podman

Wy binne bliid om te melden dat de situaasje einlings foarút is. It team ferantwurdlik foar it útfieren fan konteners by Red Hat besleat te ûntwikkeljen dyn eigen container motor. Hy krige in namme podman en biedt deselde kommandorigelynterface (CLI) as Docker. En hast alle Docker-kommando's kinne op deselde manier brûkt wurde yn Podman. Wy fiere faak seminars, dy't no neamd wurde Docker feroarje nei Podman, en de alderearste dia ropt op om te skriuwen: alias docker=podman.

In protte minsken dogge dit.

Myn Podman en ik binne op gjin inkelde manier tsjin systemd-basearre konteners. Ommers, Systemd is it meast brûkte Linux init-subsysteem, en it net tastean om goed te wurkjen yn konteners betsjut negearje hoe't tûzenen minsken wend binne om konteners te rinnen.

Podman wit wat te dwaan om systemd goed te wurkjen yn in kontener. It hat dingen nedich lykas it montearjen fan tmpfs op /run en /tmp. Se wol de "containerisearre" omjouwing ynskeakele hawwe en ferwachtet skriuwrjochten foar har diel fan 'e cgroup-map en nei de map /var/log/journald.

As jo ​​in kontener begjinne wêryn it earste kommando init of systemd is, konfigurearret Podman automatysk tmpfs en Cgroups om te soargjen dat systemd sûnder problemen begjint. Om dizze automatyske startmodus te blokkearjen, brûk de --systemd=false opsje. Tink derom dat Podman allinich systemd-modus brûkt as it sjocht dat it in systemd- of init-kommando moat útfiere.

Hjir is in úttreksel út de hânlieding:

man podman run
...

–systemd=wier|falsk

It útfieren fan in kontener yn systemd modus. Standert ynskeakele.

As jo ​​​​in systemd- of init-kommando yn in kontener útfiere, sil Podman tmpfs-mountpunten yn 'e folgjende mappen konfigurearje:

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

Ek it standert stopsinjaal sil SIGRTMIN +3 wêze.

Dit alles lit systemd rinne yn in sletten kontener sûnder oanpassingen.

OPMERKING: systemd besiket te skriuwen nei it cgroup-bestânsysteem. SELinux foarkomt lykwols dat konteners dit standert dogge. Om skriuwen ynskeakelje, skeakelje de container_manage_cgroup boolean parameter yn:

setsebool -P container_manage_cgroup wier

Sjoch no hoe't de Dockerfile derút sjocht foar it útfieren fan systemd yn in kontener mei Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Da's alles.

No meitsje wy de kontener gear:

# podman build -t systemd .

Wy fertelle SELinux om systemd de Cgroups-konfiguraasje te feroarjen:

# setsebool -P container_manage_cgroup true

Trouwens, in protte minsken ferjitte dizze stap. Gelokkich hoecht dit mar ien kear te dien en de ynstelling wurdt bewarre nei it herstarten fan it systeem.

No begjinne wy ​​gewoan de kontener:

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

Dat is it, de tsjinst is op en rint:

$ curl localhost

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

…

</html>

OPMERKING: Besykje dit net op Docker! Dêr moatte jo noch mei in tamboerine dûnsje om ditsoarte konteners troch de daemon te lansearjen. (Oanfoljende fjilden en pakketten sille nedich wêze om dit allegear naadloos te wurkjen yn Docker, of it sil moatte wurde útfierd yn in befoarrjochte kontener. Foar details, sjoch artikel.)

In pear mear coole dingen oer Podman en systemd

Podman wurket better dan Docker yn systemd unit triemmen

As konteners moatte wurde begon as it systeem opstart, dan kinne jo gewoan de passende Podman-kommando's ynfoegje yn it systemd-ienheidbestân, dat de tsjinst sil begjinne en it kontrolearje. Podman brûkt it standert fork-exec-model. Mei oare wurden, kontenerprosessen binne bern fan it Podman-proses, dus systemd kin se maklik kontrolearje.

Docker brûkt in client-server-model, en Docker CLI-kommando's kinne ek direkt yn in ienheidsbestân pleatst wurde. As de Docker-kliïnt lykwols ferbynt mei de Docker-daemon, wurdt it (de kliïnt) gewoan in oar proses dat stdin en stdout ferwurket. Op syn beurt hat systemd gjin idee oer de ferbining tusken de Docker-kliïnt en de kontener dy't rint ûnder de kontrôle fan 'e Docker-daemon, en dêrom, binnen dit model, kin systemd yn prinsipe de tsjinst net kontrolearje.

Aktivearje systemd fia socket

Podman behannelet aktivearring fia socket korrekt. Om't Podman it fork-exec-model brûkt, kin it de socket trochstjoere nei syn bernecontainerprosessen. Docker kin dit net dwaan om't it in client-server-model brûkt.

De varlink-tsjinst dy't Podman brûkt om te kommunisearjen mei kliïnten op ôfstân nei konteners is eins aktivearre fia in socket. It cockpit-podman-pakket, skreaun yn Node.js en diel fan it cockpitprojekt, lit minsken ynteraksje mei Podman-konteners fia in webynterface. De web daemon running cockpit-podman stjoert berjochten nei in varlink socket dat systemd harket op. Systemd aktivearret dan it Podman-programma om berjochten te ûntfangen en konteners te begjinnen. It aktivearjen fan systemd oer in socket elimineert de needsaak foar in konstant rinnende daemon by it útfieren fan API's op ôfstân.

Derneist ûntwikkelje wy in oare Podman-kliïnt mei de namme podman-remote, dy't deselde Podman CLI ymplementearret, mar varlink neamt om konteners út te fieren. Podman-remote kin boppe op SSH-sesjes rinne, wêrtroch jo feilich kinne ynteraksje mei konteners op ferskate masines. Yn 'e rin fan' e tiid binne wy ​​fan plan om podman-remote yn te skeakeljen om MacOS en Windows njonken Linux te stypjen, sadat ûntwikkelders op dy platfoarms in Linux firtuele masine mei Podman varlink rinne kinne en de folsleine ûnderfining hawwe dat konteners rinne op 'e lokale masine.

SD_NOTIFY

Systemd lit jo de lansearring fan helptsjinsten útstelle oant de containerisearre tsjinst dy't se nedich binne begjint. Podman kin de SD_NOTIFY-socket trochstjoere nei de kontenerisearre tsjinst, sadat de tsjinst systemd ynformearret dat it klear is om te operearjen. En nochris, Docker, dy't in client-server-model brûkt, kin dit net dwaan.

Yn de plannen

Wy binne fan plan om it kommando ta te foegjen podman generearje systemd CONTAINERID, dy't in systemd ienheidbestân sil generearje om in spesifyk spesifisearre kontener te behearjen. Dit soe moatte wurkje yn sawol root as rootless modus foar unprivileged containers. Wy hawwe sels in fersyk sjoen foar in OCI-kompatibele systemd-nspawn runtime.

konklúzje

Systemd útfiere yn in kontener is in begryplike needsaak. En tank oan Podman hawwe wy einlings in kontener-runtime dy't net yn striid is mei systemd, mar makket it maklik te brûken.

Boarne: www.habr.com

Add a comment