Kuranta systemd en ujo

Ni delonge sekvas la temon pri uzado de systemd en ujoj. Jam en 2014, nia sekureca inĝeniero Daniel Walsh skribis artikolon Running systemd ene de Docker Container, kaj kelkajn jarojn poste - alia, kiu estis nomita Running systemd en ne-privilegia ujo, en kiu li deklaris ke la situacio ne multe pliboniĝis. Precipe, li skribis ke "bedaŭrinde, eĉ du jarojn poste, se vi guglos "Docker-sistemo", la unua afero kiu aperas estas lia sama malnova artikolo. Do estas tempo ŝanĝi ion." Krome, ni jam parolis konflikto inter Docker kaj systemd programistoj.

Kuranta systemd en ujo

En ĉi tiu artikolo ni montros, kio ŝanĝiĝis laŭlonge de la tempo kaj kiel Podman povas helpi nin en ĉi tiu afero.

Estas multaj kialoj por ruli systemd ene de ujo, kiel ekzemple:

  1. Plurservaj ujoj – multaj homoj volas eltiri siajn plurservajn aplikaĵojn el virtualaj maŝinoj kaj ruli ilin en ujoj. Pli bone, kompreneble, rompi tiajn aplikojn en mikroservojn, sed ne ĉiuj ankoraŭ scias kiel fari tion aŭ simple ne havas la tempon. Tial ruli tiajn aplikojn kiel servojn lanĉitajn de systemd el unuopaj dosieroj havas tute sencon.
  2. Systemd Unuaj Dosieroj – Plej multaj aplikaĵoj kurantaj en ujoj estas konstruitaj el kodo, kiu antaŭe funkciis per virtualaj aŭ fizikaj maŝinoj. Ĉi tiuj aplikoj havas unuodosieron, kiu estis skribita por ĉi tiuj aplikoj kaj komprenas kiel ili devus esti lanĉitaj. Do estas ankoraŭ pli bone komenci servojn uzante subtenatajn metodojn, prefere ol haki vian propran init-servon.
  3. Systemd estas procezmanaĝero. Ĝi administras servojn (malŝaltas, rekomencas servojn aŭ mortigas zombiajn procezojn) pli bone ol iu ajn alia ilo.

Dirite, estas multaj kialoj por ne ruli systemd en ujoj. La ĉefa estas, ke systemd/journald kontrolas la eliron de ujoj, kaj iloj kiel Kubernetojmalferma deĵoro atendi ke ujoj skribu log rekte al stdout kaj stderr. Sekve, se vi intencas administri ujojn per orkestraj iloj kiel tiuj supre menciitaj, vi devas serioze pripensi uzi sistem-bazitajn ujojn. Aldone, programistoj de Docker kaj Moby ofte forte kontraŭis uzi systemd en ujoj.

La Veno de Podman

Ni ĝojas raporti, ke la situacio finfine antaŭeniris. La teamo respondeca pri kurado de ujoj ĉe Red Hat decidis disvolvi via propra kontenera motoro. Li ricevis nomon podman kaj ofertas la saman komandlinian interfacon (CLI) kiel Docker. Kaj preskaŭ ĉiuj Docker-komandoj povas esti uzataj en Podman same. Ni ofte faras seminariojn, kiuj nun estas nomitaj Ŝanĝante Docker al Podman, kaj la unua diapozitivo postulas skribon: kaŝnomo docker=podman.

Multaj homoj faras ĉi tion.

Mia Podman kaj mi neniel kontraŭas sistem-bazitajn ujojn. Post ĉio, Systemd estas la plej ofte uzata Linukso init-subsistemo, kaj ne permesi ĝin funkcii ĝuste en ujoj signifas ignori kiel miloj da homoj kutimas ruli ujojn.

Podman scias kion fari por ke systemd funkciu ĝuste en ujo. Ĝi bezonas aferojn kiel munti tmpfs sur /run kaj /tmp. Ŝi ŝatas havi la "enhavigitan" medion ebligita kaj atendas skribi permesojn al sia parto de la dosierujo cgroup kaj al la dosierujo /var/log/journald.

Kiam vi lanĉas ujon en kiu la unua komando estas init aŭ systemd, Podman aŭtomate agordas tmpfs kaj Cgroups por certigi, ke systemd komenciĝas sen problemoj. Por bloki ĉi tiun aŭtomatan lanĉan reĝimon, uzu la opcion --systemd=false. Bonvolu noti, ke Podman nur uzas systemd-reĝimon kiam ĝi vidas, ke ĝi bezonas ruli systemd aŭ init-komandon.

Jen eltiraĵo de la manlibro:

viro podman kuri
...

–systemd=vera|malvera

Ruli ujon en systemd-reĝimo. Ebligita defaŭlte.

Se vi rulas systemd aŭ init komandon ene de ujo, Podman agordos tmpfs-muntpunktojn en la sekvaj dosierujoj:

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

Ankaŭ la defaŭlta haltsignalo estos SIGRTMIN+3.

Ĉio ĉi permesas al systemd funkcii en fermita ujo sen iuj modifoj.

NOTO: systemd provas skribi al la dosiersistemo cgroup. Tamen SELinux malhelpas ujojn fari tion defaŭlte. Por ebligi skribadon, ebligu la bulean parametron container_manage_cgroup:

setsebool -P container_manage_cgroup vera

Nun rigardu kiel aspektas la Dockerfile por ruli systemd en ujo uzante Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Tio estas ĉio.

Nun ni muntas la ujon:

# podman build -t systemd .

Ni diras al SELinux permesi al systemd modifi la agordon de Cgroups:

# setsebool -P container_manage_cgroup true

Cetere, multaj homoj forgesas pri ĉi tiu paŝo. Feliĉe, ĉi tio nur devas esti farita unufoje kaj la agordo estas konservita post rekomenco de la sistemo.

Nun ni nur komencas la ujon:

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

Jen ĝi, la servo funkcias:

$ curl localhost

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

…

</html>

NOTO: Ne provu ĉi tion sur Docker! Tie vi ankoraŭ bezonas danci per tamburino por lanĉi ĉi tiajn ujojn tra la demono. (Aldonaj kampoj kaj pakaĵoj estos postulataj por ke ĉi tio ĉio funkciu perfekte en Docker, aŭ ĝi devos esti rulita en privilegiita ujo. Por detaloj, vidu artikolo.)

Kelkaj pli bonegaj aferoj pri Podman kaj systemd

Podman funkcias pli bone ol Docker en systemd-unuaj dosieroj

Se ujoj devas esti komencitaj kiam la sistemo ekfunkciigas, tiam vi povas simple enigi la taŭgajn Podman-komandojn en la systemd-unuan dosieron, kiu komencos la servon kaj kontrolos ĝin. Podman uzas la norman fork-ejekutan modelon. Alivorte, ujprocezoj estas infanoj de la Podman-procezo, do systemd povas facile kontroli ilin.

Docker uzas klient-servilan modelon, kaj Docker CLI-komandoj ankaŭ povas esti metitaj rekte en unuodosieron. Tamen, post kiam la Docker-kliento konektas al la Docker-demono, ĝi (la kliento) iĝas nur alia procezo pritraktanta stdin kaj stdout. Siavice, systemd ne havas ideon pri la rilato inter la kliento Docker kaj la ujo, kiu funkcias sub la kontrolo de la demono Docker, kaj tial, ene de ĉi tiu modelo, systemd esence ne povas kontroli la servon.

Aktivigo de systemd per ingo

Podman traktas aktivigon per ingo ĝuste. Ĉar Podman uzas la modelon fork-exec, ĝi povas plusendi la ingon al siaj infanaj ujprocezoj. Docker ne povas fari tion ĉar ĝi uzas modelon de kliento-servilo.

La varlink-servo, kiun Podman uzas por komuniki kun foraj klientoj al ujoj, estas efektive aktivigita per ingo. La cockpit-podman-pakaĵo, skribita en Node.js kaj parto de la piloteja projekto, permesas al homoj interagi kun Podman-ujoj per interreta interfaco. La TTT-demono kuranta cockpit-podman sendas mesaĝojn al varlink-ingo, sur kiu systemd aŭskultas. Systemd tiam aktivigas la programon Podman por ricevi mesaĝojn kaj komenci administri ujojn. Aktivigi systemd super ingo forigas la bezonon de konstante kuranta demono dum efektivigado de foraj APIoj.

Aldone, ni disvolvas alian Podman-klienton nomatan podman-remote, kiu efektivigas la saman Podman CLI sed nomas varlink por ruli ujojn. Podman-remote povas funkcii aldone al SSH-sesioj, permesante vin sekure interagi kun ujoj sur malsamaj maŝinoj. Kun la tempo, ni planas ebligi podman-remote por subteni MacOS kaj Vindozon kune kun Linukso, por ke programistoj sur tiuj platformoj povu ruli Linuksan virtualan maŝinon kun Podman varlink funkcianta kaj havi la plenan sperton, ke ujoj funkcias sur la loka maŝino.

SD_NOTIFY

Systemd permesas prokrasti la lanĉon de helpaj servoj ĝis komenciĝos la kontenerigita servo, kiun ili postulas. Podman povas plusendi la SD_NOTIFY-ingon al la kontenerigita servo por ke la servo sciigas al systemd ke ĝi estas preta funkcii. Kaj denove, Docker, kiu uzas modelon de kliento-servilo, ne povas fari ĉi tion.

En la planoj

Ni planas aldoni la komandon podman generi systemd CONTAINERID, kiu generos systemd-unuan dosieron por administri specifan ujon specifitan. Ĉi tio devus funkcii en ambaŭ radikaj kaj senradikaj reĝimoj por senprivilegiaj ujoj. Ni eĉ vidis peton pri OCI-kongrua systemd-nspawn rultempo.

konkludo

Kuri systemd en ujo estas komprenebla bezono. Kaj danke al Podman, ni finfine havas ujon rultempon, kiu ne konfliktas kun systemd, sed faciligas ĝin.

fonto: www.habr.com

Aldoni komenton