Pagpapatakbo ng systemd sa isang lalagyan

Matagal na naming sinusubaybayan ang paksa ng paggamit ng systemd sa mga container. Noong 2014, sumulat ng artikulo ang aming security engineer na si Daniel Walsh Pagpapatakbo ng systemd sa loob ng isang Docker Container, at makalipas ang ilang taon - isa pa, na tinawag Tumatakbo sa systemd sa isang hindi privileged na lalagyan, kung saan sinabi niya na hindi gaanong bumuti ang sitwasyon. Sa partikular, isinulat niya na "sa kasamaang-palad, kahit na makalipas ang dalawang taon, kung google mo ang "Docker system", ang unang bagay na lumalabas ay ang kanyang parehong lumang artikulo. Kaya oras na para baguhin ang isang bagay." Bilang karagdagan, napag-usapan na natin salungatan sa pagitan ng Docker at mga systemd developer.

Pagpapatakbo ng systemd sa isang lalagyan

Sa artikulong ito ipapakita namin kung ano ang nagbago sa paglipas ng panahon at kung paano kami matutulungan ng Podman sa bagay na ito.

Maraming dahilan para patakbuhin ang systemd sa loob ng isang container, gaya ng:

  1. Mga lalagyan ng maraming serbisyo – gustong ilabas ng maraming tao ang kanilang mga multi-service na application mula sa mga virtual machine at patakbuhin ang mga ito sa mga container. Mas mainam, siyempre, na hatiin ang mga naturang application sa mga microservice, ngunit hindi alam ng lahat kung paano ito gagawin o wala pang oras. Samakatuwid, ang pagpapatakbo ng mga application tulad ng mga serbisyong inilunsad ng systemd mula sa mga file ng unit ay may perpektong kahulugan.
  2. Systemd Unit Files – Karamihan sa mga application na tumatakbo sa loob ng mga container ay binuo mula sa code na dating tumakbo sa virtual o pisikal na mga makina. Ang mga application na ito ay may isang unit file na isinulat para sa mga application na ito at nauunawaan kung paano sila dapat ilunsad. Kaya mas mainam pa rin na simulan ang mga serbisyo gamit ang mga sinusuportahang pamamaraan, sa halip na i-hack ang sarili mong serbisyo sa init.
  3. Ang Systemd ay isang tagapamahala ng proseso. Nagsasagawa ito ng pamamahala ng serbisyo (pagsara, pag-restart ng mga serbisyo, o pagpatay sa mga proseso ng zombie) nang mas mahusay kaysa sa anumang iba pang tool.

Iyon ay sinabi, maraming mga dahilan upang hindi patakbuhin ang systemd sa mga lalagyan. Ang pangunahing isa ay kinokontrol ng systemd/journald ang output ng mga lalagyan, at mga tool tulad ng Kubernetes o openshift asahan ang mga lalagyan na direktang magsulat ng log sa stdout at stderr. Samakatuwid, kung mamamahala ka ng mga container sa pamamagitan ng mga tool sa orkestrasyon tulad ng mga nabanggit sa itaas, dapat mong seryosong isaalang-alang ang paggamit ng mga systemd-based na container. Bilang karagdagan, ang mga developer ng Docker at Moby ay madalas na tutol sa paggamit ng systemd sa mga container.

Ang Pagdating ng Podman

Ikinalulugod naming iulat na sa wakas ay umusad na ang sitwasyon. Ang koponan na responsable para sa pagpapatakbo ng mga lalagyan sa Red Hat ay nagpasya na bumuo sarili mong container engine. May pangalan siya podman at nag-aalok ng parehong command line interface (CLI) bilang Docker. At halos lahat ng Docker command ay maaaring gamitin sa Podman sa parehong paraan. Madalas kaming magsagawa ng mga seminar, na ngayon ay tinatawag na Ang pagpapalit ng Docker sa Podman, at ang pinakaunang slide ay nangangailangan ng pagsulat: alias docker=podman.

Maraming tao ang gumagawa nito.

Ang aking Podman at ako ay hindi sa anumang paraan laban sa systemd-based na mga lalagyan. Pagkatapos ng lahat, ang Systemd ay ang pinakakaraniwang ginagamit na Linux init subsystem, at ang hindi pagpayag na gumana ito nang maayos sa mga lalagyan ay nangangahulugan ng pagbabalewala sa kung paano nakasanayan ang libu-libong tao sa pagpapatakbo ng mga lalagyan.

Alam ni Podman kung ano ang gagawin para gumana nang maayos ang systemd sa isang lalagyan. Kailangan nito ng mga bagay tulad ng pag-mount ng tmpfs sa /run at /tmp. Gusto niyang paganahin ang "containerized" na kapaligiran at inaasahan ang mga pahintulot sa pagsulat sa kanyang bahagi ng direktoryo ng cgroup at sa folder na /var/log/journald.

Kapag nagsimula ka ng isang lalagyan kung saan ang unang command ay init o systemd, awtomatikong kino-configure ng Podman ang tmpfs at Cgroups upang matiyak na ang systemd ay magsisimula nang walang problema. Upang harangan ang auto launch mode na ito, gamitin ang --systemd=false na opsyon. Pakitandaan na ang Podman ay gumagamit lamang ng systemd mode kapag nakita nitong kailangan nitong magpatakbo ng systemd o init na utos.

Narito ang isang sipi mula sa manwal:

lalaki podman tumakbo
...

–systemd=true|false

Pagpapatakbo ng container sa systemd mode. Pinagana bilang default.

Kung magpapatakbo ka ng systemd o init na command sa loob ng isang container, iko-configure ng Podman ang mga tmpfs mount point sa mga sumusunod na direktoryo:

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

Gayundin ang default na stop signal ay SIGRTMIN+3.

Ang lahat ng ito ay nagpapahintulot sa systemd na tumakbo sa isang saradong lalagyan nang walang anumang mga pagbabago.

TANDAAN: sinusubukan ng systemd na magsulat sa cgroup filesystem. Gayunpaman, pinipigilan ng SELinux ang mga lalagyan na gawin ito bilang default. Upang paganahin ang pagsusulat, paganahin ang container_manage_cgroup boolean parameter:

setsebool -P container_manage_cgroup true

Ngayon tingnan kung ano ang hitsura ng Dockerfile para sa pagpapatakbo ng systemd sa isang lalagyan gamit ang Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Yun lang

Ngayon tinitipon namin ang lalagyan:

# podman build -t systemd .

Sinasabi namin sa SELinux na payagan ang systemd na baguhin ang configuration ng Cgroups:

# setsebool -P container_manage_cgroup true

Maraming mga tao, sa pamamagitan ng paraan, kalimutan ang tungkol sa hakbang na ito. Sa kabutihang palad, ito ay kailangan lamang gawin nang isang beses at ang setting ay nai-save pagkatapos i-reboot ang system.

Ngayon lang namin simulan ang lalagyan:

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

Iyon lang, gumagana at tumatakbo ang serbisyo:

$ curl localhost

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

…

</html>

TANDAAN: Huwag subukan ito sa Docker! Doon kailangan mo pang sumayaw gamit ang tamburin para ilunsad ang mga ganitong uri ng lalagyan sa pamamagitan ng daemon. (Kailanganin ang mga karagdagang field at package para magawa itong lahat ng maayos sa Docker, o kakailanganin itong patakbuhin sa isang privileged container. Para sa mga detalye, tingnan ang Artikulo.)

Ang ilang higit pang mga cool na bagay tungkol sa Podman at systemd

Mas mahusay na gumagana ang Podman kaysa sa Docker sa mga systemd unit file

Kung kailangang simulan ang mga lalagyan kapag nag-boot ang system, maaari mo lamang ipasok ang naaangkop na mga command ng Podman sa systemd unit file, na magsisimula sa serbisyo at susubaybayan ito. Ginagamit ng Podman ang karaniwang modelo ng fork-exec. Sa madaling salita, ang mga proseso ng container ay mga anak ng proseso ng Podman, kaya madaling masubaybayan ng systemd ang mga ito.

Gumagamit ang Docker ng modelo ng client-server, at ang mga command ng Docker CLI ay maaari ding direktang ilagay sa isang unit file. Gayunpaman, kapag ang kliyente ng Docker ay kumonekta sa Docker daemon, ito (ang kliyente) ay magiging isa na lamang na proseso sa paghawak ng stdin at stdout. Sa turn, ang systemd ay walang ideya tungkol sa koneksyon sa pagitan ng Docker client at ng container na tumatakbo sa ilalim ng kontrol ng Docker daemon, at samakatuwid, sa loob ng modelong ito, ang systemd sa panimula ay hindi maaaring masubaybayan ang serbisyo.

Pag-activate ng systemd sa pamamagitan ng socket

Pinangangasiwaan ng Podman ang pag-activate sa pamamagitan ng socket nang tama. Dahil ginagamit ng Podman ang modelong fork-exec, maaari nitong ipasa ang socket sa mga proseso ng child container nito. Hindi ito magagawa ng Docker dahil gumagamit ito ng modelo ng client-server.

Ang serbisyo ng varlink na ginagamit ng Podman upang makipag-ugnayan sa mga malalayong kliyente sa mga lalagyan ay aktwal na isinaaktibo sa pamamagitan ng isang socket. Ang package ng cockpit-podman, na nakasulat sa Node.js at bahagi ng proyekto ng cockpit, ay nagbibigay-daan sa mga tao na makipag-ugnayan sa mga container ng Podman sa pamamagitan ng isang web interface. Ang web daemon na tumatakbo sa cockpit-podman ay nagpapadala ng mga mensahe sa isang varlink socket na pinakikinggan ng systemd. Pagkatapos ay ina-activate ng Systemd ang Podman program para makatanggap ng mga mensahe at magsimulang mamahala ng mga container. Ang pag-activate ng systemd sa isang socket ay nag-aalis ng pangangailangan para sa isang patuloy na tumatakbong daemon kapag nagpapatupad ng mga malalayong API.

Bukod pa rito, bubuo kami ng isa pang Podman client na tinatawag na podman-remote, na nagpapatupad ng parehong Podman CLI ngunit tumatawag sa varlink upang magpatakbo ng mga container. Maaaring tumakbo ang Podman-remote sa ibabaw ng mga session ng SSH, na nagbibigay-daan sa iyong ligtas na makipag-ugnayan sa mga container sa iba't ibang machine. Sa paglipas ng panahon, plano naming paganahin ang podman-remote upang suportahan ang MacOS at Windows kasama ng Linux, upang ang mga developer sa mga platform na iyon ay makapagpatakbo ng isang Linux virtual machine na may Podman varlink na tumatakbo at magkaroon ng buong karanasan na ang mga container ay tumatakbo sa lokal na makina.

SD_NOTIFY

Binibigyang-daan ka ng Systemd na ipagpaliban ang paglulunsad ng mga auxiliary na serbisyo hanggang sa magsimula ang containerized na serbisyo na kailangan nila. Maaaring ipasa ng Podman ang SD_NOTIFY socket sa containerized na serbisyo upang maabisuhan ng serbisyo ang systemd na handa na itong gumana. At muli, hindi ito magagawa ng Docker, na gumagamit ng modelo ng client-server.

Sa mga plano

Plano naming idagdag ang command podman generate systemd CONTAINERID, na bubuo ng systemd unit file para pamahalaan ang isang partikular na container na tinukoy. Dapat itong gumana sa parehong root at rootless na mga mode para sa mga hindi karapat-dapat na lalagyan. Nakakita pa kami ng kahilingan para sa isang OCI-compatible systemd-nspawn runtime.

Konklusyon

Ang pagpapatakbo ng systemd sa isang lalagyan ay isang naiintindihan na pangangailangan. At salamat sa Podman, sa wakas ay mayroon kaming container runtime na hindi sumasalungat sa systemd, ngunit ginagawa itong madaling gamitin.

Pinagmulan: www.habr.com

Magdagdag ng komento