Жүйені контейнерде іске қосу

Біз контейнерлерде systemd пайдалану тақырыбын көптен бері қадағалап келеміз. 2014 жылы біздің қауіпсіздік инженері Дэниел Уолш мақала жазды Docker контейнерінде systemd іске қосу, ал бірнеше жылдан кейін - басқа, деп аталды Артықшылықсыз контейнерде systemd іске қосылуы, онда ол жағдайдың айтарлықтай жақсармағанын айтты. Атап айтқанда, ол «өкінішке орай, екі жылдан кейін де, егер сіз «Docker жүйесі» google-ді іздесеңіз, бірінші оның сол ескі мақаласы шығады деп жазды. Сондықтан бір нәрсені өзгерту уақыты келді ». Сонымен қатар, біз қазірдің өзінде айттық Docker және жүйелік әзірлеушілер арасындағы қақтығыс.

Жүйені контейнерде іске қосу

Бұл мақалада біз уақыт өте келе не өзгергенін және Подманның бұл мәселеде бізге қалай көмектесе алатынын көрсетеміз.

Контейнер ішінде systemd іске қосудың көптеген себептері бар, мысалы:

  1. Көп қызмет көрсету контейнерлері – көптеген адамдар өздерінің мультисервистік қосымшаларын виртуалды машиналардан шығарып, контейнерлерде іске қосқысы келеді. Әрине, мұндай қосымшаларды микросервистерге бөлу жақсы болар еді, бірақ мұны қалай жасау керектігін бәрі бірдей біле бермейді немесе жай ғана уақыт жоқ. Сондықтан, бірлік файлдарынан systemd іске қосқан қызметтер сияқты қолданбаларды іске қосу өте мағыналы.
  2. Жүйелік блок файлдары – Контейнерлерде жұмыс істейтін қолданбалардың көпшілігі бұрын виртуалды немесе физикалық машиналарда жұмыс істейтін кодтан құрастырылған. Бұл қолданбаларда осы қолданбалар үшін жазылған және оларды қалай іске қосу керектігін түсінетін бірлік файлы бар. Сондықтан өзіңіздің бастапқы қызметіңізді бұзбай, қолдау көрсетілетін әдістерді пайдаланып қызметтерді бастағаныңыз жөн.
  3. Systemd - процесс менеджері. Ол қызметтерді (өшіреді, қызметтерді қайта іске қосады немесе зомби процестерін өлтіреді) кез келген басқа құралға қарағанда жақсы басқарады.

Айта кетейік, контейнерлерде systemd іске қосылмаудың көптеген себептері бар. Ең бастысы, systemd/journald контейнерлер мен құралдардың шығысын басқарады Kubernetes немесе openshift контейнерлердің журналды stdout және stderr-ге тікелей жазуын күтіңіз. Сондықтан, егер сіз жоғарыда аталған сияқты оркестрлік құралдар арқылы контейнерлерді басқарғыңыз келсе, жүйелік негізіндегі контейнерлерді пайдалануды мұқият қарастырған жөн. Сонымен қатар, Docker және Moby әзірлеушілері контейнерлерде systemd қолдануға жиі қарсы болды.

Подманның келуі

Жағдай ақыры алға жылжығанын хабарлауға қуаныштымыз. Red Hat-те контейнерлерді басқаруға жауапты топ әзірлеуге шешім қабылдады өзіңіздің контейнерлік қозғалтқышыңыз. Ол есім алды Подман және Docker сияқты бірдей пәрмен жолы интерфейсін (CLI) ұсынады. Және барлық дерлік Docker пәрмендерін Podman-да бірдей қолдануға болады. Біз жиі семинарлар өткіземіз, олар қазір аталады Доккерді Подманға өзгерту, және ең бірінші слайд жазуды талап етеді: бүркеншік ат docker=podman.

Көптеген адамдар мұны істейді.

Менің Подман екеуміз жүйелік негізіндегі контейнерлерге қарсы емеспіз. Өйткені, Systemd - ең жиі қолданылатын Linux init ішкі жүйесі және оның контейнерлерде дұрыс жұмыс істеуіне мүмкіндік бермеу мыңдаған адамдардың контейнерлерді іске қосуға қалай үйренгенін елемеу дегенді білдіреді.

Подман systemd контейнерде дұрыс жұмыс істеуі үшін не істеу керектігін біледі. Оған tmpf файлдарын /run және /tmp орнату сияқты нәрселер қажет. Ол "контейнерленген" ортаның қосылғанын ұнатады және топ каталогының өз бөлігіне және /var/log/journald қалтасына жазу рұқсаттарын күтеді.

Бірінші пәрмені init немесе systemd болатын контейнерді іске қосқан кезде, Podman жүйесі жүйенің ақаусыз іске қосылуын қамтамасыз ету үшін tmpf және Cgroups файлдарын автоматты түрде конфигурациялайды. Бұл автоматты іске қосу режимін блоктау үшін --systemd=false опциясын пайдаланыңыз. Podman тек systemd немесе init пәрменін іске қосу қажет екенін көргенде systemd режимін пайдаланатынын ескеріңіз.

Міне, нұсқаулықтан үзінді:

адам подман жүгіреді
...

–systemd=true|false

Контейнерді systemd режимінде іске қосу. Әдепкі бойынша қосылған.

Контейнер ішінде systemd немесе init пәрменін іске қоссаңыз, Podman келесі каталогтарда tmpfs орнату нүктелерін конфигурациялайды:

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

Сондай-ақ әдепкі тоқтату сигналы SIGRTMIN+3 болады.

Мұның бәрі systemd-ге ешқандай өзгертулерсіз жабық контейнерде жұмыс істеуге мүмкіндік береді.

ЕСКЕРТПЕ: systemd cgroup файлдық жүйесіне жазу әрекетін жасайды. Дегенмен, SELinux әдепкі бойынша контейнерлердің мұны істеуіне жол бермейді. Жазуды қосу үшін container_manage_cgroup логикалық параметрін қосыңыз:

setsebool -P container_manage_cgroup шын

Енді Podman көмегімен контейнерде systemd іске қосу үшін Dockerfile қалай көрінетінін қараңыз:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Осымен болды.

Енді біз контейнерді жинаймыз:

# podman build -t systemd .

SELinux жүйесіне systemd жүйесіне Cgroups конфигурациясын өзгертуге рұқсат беруін айтамыз:

# setsebool -P container_manage_cgroup true

Айтпақшы, көптеген адамдар бұл қадамды ұмытып кетеді. Бақытымызға орай, бұл тек бір рет жасалуы керек және жүйені қайта жүктегеннен кейін параметр сақталады.

Енді біз контейнерді бастаймыз:

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

Міне, қызмет жұмыс істеп тұр:

$ curl localhost

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

…

</html>

ЕСКЕРТПЕ: Мұны Docker қолданбасында қолданбаңыз! Демон арқылы мұндай контейнерлерді іске қосу үшін сіз әлі де бубен билеуіңіз керек. (Мұның барлығы Docker жүйесінде үздіксіз жұмыс істеуі үшін қосымша өрістер мен бумалар қажет болады немесе ол артықшылықты контейнерде іске қосылуы керек. Толық ақпаратты қараңыз. мақала.)

Podman және systemd туралы тағы бірнеше керемет нәрсе

Podman жүйелік блок файлдарында Docker-ге қарағанда жақсы жұмыс істейді

Жүйе жүктелген кезде контейнерлерді іске қосу қажет болса, қызметті іске қосатын және оны бақылайтын жүйелік блок файлына сәйкес Podman пәрмендерін енгізуге болады. Подман стандартты fork-exec үлгісін пайдаланады. Басқаша айтқанда, контейнерлік процестер Podman процесінің балалары болып табылады, сондықтан systemd оларды оңай бақылай алады.

Docker клиент-сервер үлгісін пайдаланады және Docker CLI пәрмендері де бірлік файлында тікелей орналастырылуы мүмкін. Дегенмен, Docker клиенті Docker демонына қосылғаннан кейін ол (клиент) stdin және stdout өңдейтін басқа процесске айналады. Өз кезегінде, systemd Docker клиенті мен Docker демонының басқаруымен жұмыс істейтін контейнер арасындағы байланыс туралы түсінбейді, сондықтан бұл модельде systemd қызметті түбегейлі бақылай алмайды.

Розетка арқылы жүйені белсендіру

Подман розетка арқылы белсендіруді дұрыс басқарады. Podman fork-exec үлгісін пайдаланатындықтан, ол розетканы еншілес контейнер процестеріне жібере алады. Docker мұны істей алмайды, себебі ол клиент-сервер үлгісін пайдаланады.

Podman қашықтағы клиенттермен контейнерлерге байланысу үшін пайдаланатын varlink қызметі шын мәнінде розетка арқылы белсендірілген. Node.js тілінде жазылған кокпит-подман пакеті және кабина жобасының бір бөлігі адамдарға веб-интерфейс арқылы Podman контейнерлерімен өзара әрекеттесуге мүмкіндік береді. Cockpit-podman жұмыс істейтін веб-демон хабарламаларды жүйе тыңдайтын varlink ұясына жібереді. Содан кейін Systemd хабарламаларды қабылдау және контейнерлерді басқаруды бастау үшін Podman бағдарламасын белсендіреді. Розетка арқылы systemd белсендіру қашықтағы API интерфейстерін енгізу кезінде тұрақты жұмыс істейтін демонның қажеттілігін жояды.

Оған қоса, біз бірдей Podman CLI-ді жүзеге асыратын, бірақ контейнерлерді іске қосу үшін varlink шақыратын podman-remote деп аталатын басқа Podman клиентін әзірлеп жатырмыз. Podman-қашықтан басқару құралы SSH сеанстарының үстінде жұмыс істей алады, бұл әртүрлі машиналардағы контейнерлермен қауіпсіз әрекеттесуге мүмкіндік береді. Уақыт өте келе, біз Linux-пен қатар MacOS және Windows жүйесін қолдау үшін podman-қашықтан басқару құралын қосуды жоспарлап отырмыз, осылайша сол платформалардағы әзірлеушілер Podman varlink іске қосылған Linux виртуалды машинасын іске қоса алады және контейнерлер жергілікті құрылғыда жұмыс істейтін толық тәжірибеге ие болады.

SD_NOTIFY

Systemd көмекші қызметтерді іске қосуды олар қажет контейнерлік қызмет басталғанша кейінге қалдыруға мүмкіндік береді. Подман SD_NOTIFY ұясын контейнерлік қызметке жібере алады, осылайша қызмет жүйеге оның жұмыс істеуге дайын екендігі туралы хабарлайды. Тағы да, клиент-сервер үлгісін пайдаланатын Docker мұны істей алмайды.

Жоспарларда

Біз белгілі бір контейнерді басқару үшін жүйелік блок файлын жасайтын podman generator systemd CONTAINERID пәрменін қосуды жоспарлап отырмыз. Бұл артықшылықсыз контейнерлер үшін түбірлік және түбірсіз режимдерде жұмыс істеуі керек. Біз тіпті OCI-үйлесімді systemd-nspawn орындалу уақытына сұранысты көрдік.

қорытынды

Контейнерде systemd іске қосу - түсінікті қажеттілік. Подманның арқасында бізде systemd-ке қайшы келмейтін, бірақ оны пайдалануды жеңілдететін контейнердің жұмыс уақыты бар.

Ақпарат көзі: www.habr.com

пікір қалдыру