Контейнерде системаны иштетүү

Биз системаны контейнерлерде колдонуу темасын көптөн бери байкап келебиз. 2014-жылы биздин коопсуздук инженери Дэниел Уолш макала жазган Докер контейнеринин ичинде системаны иштетүү, жана бир-эки жылдан кийин - деп аталган дагы бир Системаны артыкчылыктуу эмес контейнерде иштетүү, анда ал абал анча жакшырбаганын билдирди. Атап айтканда, ал мындай деп жазган: "Тилекке каршы, эки жыл өткөндөн кийин, эгер сиз Google Docker системасына кирсеңиз, биринчи кезекте анын эски макаласы чыгат. Демек, бир нерсени өзгөртүүгө убакыт келди." Мындан тышкары, биз буга чейин сүйлөштүк Docker менен системалык иштеп чыгуучулардын ортосундагы конфликт.

Контейнерде системаны иштетүү

Бул макалада биз убакыттын өтүшү менен эмне өзгөргөнүн жана Podman бул маселеде бизге кантип жардам бере аларын көрсөтөбүз.

Системаны контейнердин ичинде иштетүүнүн көптөгөн себептери бар, мисалы:

  1. Мультисервис контейнерлери – Көптөгөн адамдар өздөрүнүн мульти-сервистик тиркемелерин виртуалдык машиналардан чыгарып, контейнерлерде иштетүүнү каалашат. Албетте, мындай тиркемелерди микросервистерге бөлүү жакшы болмок, бирок муну кантип жасоону баары эле биле бербейт же жөн эле убактысы жок. Ошондуктан, системалык файлдардан система тарабынан ишке киргизилген кызматтар сыяктуу тиркемелерди иштетүү толук мааниге ээ.
  2. Системалык бирдиктин файлдары – Контейнерлердин ичинде иштеген колдонмолордун көбү мурда виртуалдык же физикалык машиналарда иштеген коддон түзүлөт. Бул тиркемелерде бул колдонмолор үчүн жазылган жана аларды кантип ишке киргизүү керектигин түшүнгөн бирдик файлы бар. Андыктан, өзүңүздүн баштапкы кызматыңызды бузуп алгандан көрө, колдоого алынган ыкмаларды колдонуу менен кызматтарды баштаганыңыз жакшы.
  3. Systemd процесс менеджери болуп саналат. Ал башка куралдарга караганда кызматтарды жакшы башкарат (өчөт, кызматтарды өчүрөт же зомби процесстерин өлтүрөт).

Айтор, контейнерлерде systemd иштетпөөнүн көптөгөн себептери бар. Эң негизгиси, systemd/journald контейнерлердин жана куралдардын чыгышын көзөмөлдөйт Kubernetes же openshift контейнерлердин журналды түз stdout жана stderrге жазышын күтүңүз. Ошондуктан, эгерде сиз контейнерлерди жогоруда айтылгандар сыяктуу оркестрлөө куралдары аркылуу башкара турган болсоңуз, анда сиз системага негизделген контейнерлерди колдонууну ойлонушуңуз керек. Кошумчалай кетсек, Docker жана Moby иштеп чыгуучулары көбүнчө контейнерлерде systemd колдонууга катуу каршы болушкан.

Подмандын келиши

Кырдаал акыры алга жылды деп кубануу менен кабарлайбыз. Red Hat контейнерлерин иштетүү үчүн жооптуу команда иштеп чыгууну чечти өз контейнер мотору. Ал ат алды Подман жана Docker сыяктуу эле буйрук сабынын интерфейсин (CLI) сунуштайт. Жана дээрлик бардык Docker буйруктары Podmanда ушундай эле колдонулушу мүмкүн. Биз көп учурда семинарларды өткөрүп жатабыз, алар азыр деп аталат Докерди Подманга өзгөртүү, жана эң биринчи слайд жазууну талап кылат: лакап ат docker=podman.

Көптөр муну жасайт.

Менин Подман экөөбүз эч кандай системага негизделген контейнерлерге каршы эмеспиз. Анткени, Systemd эң көп колдонулган Linux init подсистемасы жана анын контейнерлерде туура иштешине жол бербөө миңдеген адамдардын контейнерлерди иштетүүгө көнүп калганына көңүл бурбоо дегенди билдирет.

Подман системанын контейнерде туура иштеши үчүн эмне кылуу керектигин билет. Ал /run жана /tmp боюнча tmpfs орнотуу сыяктуу нерселер керек. Ал "контейнерлештирилген" чөйрөнү иштеткенди жакшы көрөт жана анын cgroup каталогунун бир бөлүгүнө жана /var/log/journald папкасына жазуу уруксаттарын күтөт.

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

Бул жерде колдонмодон үзүндү:

адам подман чуркайт
...

–systemd=true|false

Система режиминде контейнерди иштетүү. Демейки боюнча иштетилген.

Эгер сиз контейнердин ичинде 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 true

Эми 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 моделин колдонгондуктан, ал розетканы өзүнүн бала контейнер процесстерине жөнөтө алат. Докер муну кыла албайт, анткени ал кардар-сервер моделин колдонот.

Podman алыскы кардарлар менен контейнерлерге байланышуу үчүн колдонгон varlink кызматы чындыгында розетка аркылуу иштетилген. Node.js жана кабина долбоорунун бөлүгү жазылган Cockpit-podman пакети адамдарга веб-интерфейс аркылуу Podman контейнерлери менен баарлашууга мүмкүндүк берет. Кокпит-подманды иштеткен веб-демон система угуучу varlink розеткасына билдирүүлөрдү жөнөтөт. Андан кийин Systemd билдирүүлөрдү кабыл алуу жана контейнерлерди башкарууну баштоо үчүн Podman программасын иштетет. Системаны розетка аркылуу активдештирүү алыскы API'лерди ишке ашырууда тынымсыз иштеп жаткан демондун зарылдыгын жок кылат.

Кошумчалай кетсек, биз podman-remote деп аталган дагы бир Podman кардарын иштеп жатабыз, ал ошол эле Podman CLIди ишке ашырат, бирок контейнерлерди иштетүү үчүн varlink чакырат. Podman-remote SSH сеанстарынын үстүндө иштей алат, бул сизге ар кандай машиналардагы контейнерлер менен коопсуз иштешүүгө мүмкүндүк берет. Убакыттын өтүшү менен биз Linux менен катар MacOS жана Windows колдоо үчүн podman-remote иштетүүнү пландаштырып жатабыз, ошентип ал платформалардагы иштеп чыгуучулар Podman varlink иштеген Linux виртуалдык машинасын иштетип, контейнерлер жергиликтүү машинада иштеп жаткан толук тажрыйбага ээ болушат.

SD_NOTIFY

Systemd жардамчы кызматтарды ишке киргизүүнү алар талап кылган контейнердик кызмат башталганга чейин кийинкиге калтырууга мүмкүндүк берет. Подман SD_NOTIFY розеткасын контейнерлештирилген кызматка жөнөтө алат, ошентип кызмат системага иштөөгө даяр экендигин кабарлайт. Жана дагы, кардар-сервер моделин колдонгон Docker муну кыла албайт.

Пландарда

Биз podman generation systemd CONTAINERID буйругун кошууну пландап жатабыз, ал белгилүү бир контейнерди башкаруу үчүн системалык бирдик файлын жаратат. Бул артыкчылыксыз контейнерлер үчүн тамыр жана тамырсыз режимдерде иштеши керек. Биз жадакалса OCI менен шайкеш келген системанын иштөө убактысына суроо-талапты көрдүк.

жыйынтыктоо

Системаны контейнерде иштетүү түшүнүктүү муктаждык. Подмандын аркасында, акыры бизде systemd менен карама-каршы келбеген, бирок аны колдонууну жеңилдеткен контейнердин иштөө убактысы бар.

Source: www.habr.com

Комментарий кошуу