Системийг контейнерт ажиллуулж байна

Бид systemd-г контейнерт ашиглах сэдвийг удаан хугацаанд мөрдөж ирсэн. 2014 онд манай хамгаалалтын инженер Даниел Уолш нийтлэл бичсэн Docker контейнер дотор systemd-г ажиллуулж байна, мөн хэдэн жилийн дараа - өөр гэж нэрлэдэг байсан Systemd-г давуу эрхгүй контейнерт ажиллуулж байна, үүнд тэрээр нөхцөл байдал төдийлөн сайжраагүй гэж мэдэгдэв. Тэр тусмаа "Харамсалтай нь, хоёр жилийн дараа ч гэсэн та "Docker system"-ийг google-ээр хайвал хамгийн түрүүнд түүний хуучин нийтлэл гарч ирдэг. Тиймээс ямар нэг зүйлийг өөрчлөх цаг болжээ." Үүнээс гадна бид аль хэдийн ярьсан Docker болон systemd хөгжүүлэгчид хоорондын зөрчил.

Системийг контейнерт ажиллуулж байна

Энэ нийтлэлд бид цаг хугацааны явцад юу өөрчлөгдсөн, Подман энэ асуудалд хэрхэн тусалж болохыг харуулах болно.

Системийг контейнер дотор ажиллуулах олон шалтгаан бий, тухайлбал:

  1. Олон үйлчилгээтэй контейнер - Олон хүмүүс виртуал машинаас олон үйлчилгээтэй програмуудаа татаж аваад контейнерт ажиллуулахыг хүсдэг. Мэдээжийн хэрэг, ийм програмуудыг микро үйлчилгээ болгон задлах нь дээр байх болно, гэхдээ хүн бүр үүнийг хэрхэн хийхийг мэддэггүй эсвэл зүгээр л цаг зав байдаггүй. Иймд нэг төрлийн файлаас systemd-ийн эхлүүлсэн үйлчилгээ гэх мэт програмуудыг ажиллуулах нь туйлын утга учиртай юм.
  2. Системийн нэгжийн файлууд – Контейнер дотор ажилладаг ихэнх программууд нь өмнө нь виртуал эсвэл физик машин дээр ажиллаж байсан кодоос бүтээгдсэн байдаг. Эдгээр програмууд нь эдгээр програмуудад зориулж бичсэн нэгж файлтай бөгөөд тэдгээрийг хэрхэн эхлүүлэхийг ойлгодог. Тиймээс өөрийн init үйлчилгээг хакердахын оронд дэмжигдсэн аргуудыг ашиглан үйлчилгээг эхлүүлэх нь дээр хэвээр байна.
  3. Systemd бол процессын менежер юм. Энэ нь бусад хэрэгслээс илүү үйлчилгээг (унтраах, дахин эхлүүлэх эсвэл зомби процессыг устгах) удирддаг.

Системд системийг контейнерт ажиллуулахгүй байх олон шалтгаан бий. Гол нь systemd/journald нь савны гаралт, гэх мэт хэрэгслүүдийг хянадаг явдал юм Kubernetes буюу нээлттэй ээлж Контейнер stdout болон stderr руу шууд лог бичихийг хүлээж байна. Тиймээс, хэрэв та дээр дурдсан шиг зохион байгуулалтын хэрэгслээр контейнеруудыг удирдах гэж байгаа бол системд суурилсан контейнер ашиглах талаар нухацтай бодож үзэх хэрэгтэй. Нэмж дурдахад Docker болон Moby хөгжүүлэгчид systemd-ийг контейнерт ашиглахыг эрс эсэргүүцдэг.

Подманы ирэлт

Нөхцөл байдал эцэстээ урагшилсныг дуулгахад таатай байна. Red Hat-д контейнер ажиллуулах үүрэгтэй баг хөгжүүлэхээр шийджээ өөрийн чингэлэг хөдөлгүүр. Тэр нэр авсан Подман мөн Docker-тэй ижил командын мөрийн интерфейсийг (CLI) санал болгодог. Бараг бүх Docker командуудыг Podman-д ижил аргаар ашиглаж болно. Бид ихэвчлэн семинар зохион байгуулдаг бөгөөд үүнийг одоо гэж нэрлэдэг Docker-ыг Podman болгон сольж байна, мөн хамгийн эхний слайд бичихийг дууддаг: alias docker=podman.

Олон хүмүүс үүнийг хийдэг.

Миний Подман бид хоёр системд суурилсан контейнеруудын эсрэг ямар ч арга байхгүй. Эцсийн эцэст Systemd бол хамгийн түгээмэл хэрэглэгддэг Linux init дэд систем бөгөөд үүнийг саванд зөв ажиллуулахыг зөвшөөрөхгүй байгаа нь олон мянган хүмүүс контейнер ажиллуулж дассан гэдгийг үл тоомсорлодог гэсэн үг юм.

Podman systemd-г саванд зөв ажиллуулахын тулд юу хийхээ мэддэг. Үүнд /run болон /tmp дээр tmpfs холбох гэх мэт зүйлс хэрэгтэй. Тэрээр "контейнержүүлсэн" орчинг идэвхжүүлэх дуртай бөгөөд бүлгийн лавлах хэсэг болон /var/log/journald хавтас руу бичих зөвшөөрлийг хүлээж байна.

Эхний команд нь init эсвэл systemd байгаа контейнерийг эхлүүлэх үед Podman нь системд асуудалгүй эхлэхийн тулд tmpfs болон Cgroups-ийг автоматаар тохируулдаг. Энэ автомат эхлүүлэх горимыг хаахын тулд --systemd=false сонголтыг ашиглана уу. Podman нь systemd эсвэл init командыг ажиллуулах шаардлагатай үед л systemd горимыг ашигладаг гэдгийг анхаарна уу.

Энд гарын авлагын ишлэл байна:

хүн подман гүйж байна
...

–systemd=true|худал

Системийн горимд контейнер ажиллуулж байна. Өгөгдмөлөөр идэвхжүүлсэн.

Хэрэв та контейнер дотор 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 .

Системд Cgroups тохиргоог өөрчлөхийг зөвшөөрөхийг бид SELinux-д хэлж байна:

# 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 нь залгуураар дамжуулан идэвхжүүлэлтийг зөв зохицуулдаг. Podman нь fork-exec загварыг ашигладаг тул уг залгуурыг хүүхдийн контейнер процесс руу дамжуулах боломжтой. Docker үүнийг хийх боломжгүй, учир нь энэ нь үйлчлүүлэгч-серверийн загварыг ашигладаг.

Podman-ийн алсын үйлчлүүлэгчидтэй чингэлэг рүү холбогдоход ашигладаг varlink үйлчилгээ нь угсралтын шугамаар идэвхждэг. Node.js-д бичигдсэн cockpit-podman багц болон бүхээгийн төслийн нэг хэсэг нь хүмүүст вэб интерфэйсээр дамжуулан Podman контейнеруудтай харилцах боломжийг олгодог. Cockpit-podman ажиллуулдаг вэб дэмон нь системийн сонсдог varlink залгуур руу мессеж илгээдэг. Дараа нь Systemd нь Podman програмыг идэвхжүүлж мессеж хүлээн авч, контейнеруудыг удирдаж эхэлдэг. Systemd-г залгуур дээр идэвхжүүлснээр алсын API-г хэрэгжүүлэхэд байнгын ажиллагаатай дэмон байх шаардлагагүй болно.

Нэмж дурдахад бид podman-remote нэртэй өөр нэг Podman клиентийг хөгжүүлж байгаа бөгөөд энэ нь ижил Podman CLI-г хэрэгжүүлдэг боловч контейнер ажиллуулахын тулд varlink дууддаг. Podman-Remote нь SSH сешн дээр ажиллах боломжтой бөгөөд өөр өөр машин дээрх контейнеруудтай аюулгүйгээр харилцах боломжийг танд олгоно. Цаг хугацаа өнгөрөхөд бид Linux-тай зэрэгцэн MacOS болон Windows-ийг дэмжихийн тулд podman-remote-г идэвхжүүлэхээр төлөвлөж байгаа бөгөөд ингэснээр тэдгээр платформ дээрх хөгжүүлэгчид Podman varlink ажиллаж байгаа Линукс виртуал машиныг ажиллуулж, локал машин дээр контейнер ажиллуулж байх бүрэн туршлагатай болно.

SD_NOTIFY

Systemd нь танд туслах үйлчилгээг эхлүүлэхийг шаардлагатай чингэлэг үйлчилгээ эхлэх хүртэл хойшлуулах боломжийг олгодог. Podman нь SD_NOTIFY залгуурыг чингэлэг үйлчилгээ рүү дамжуулах боломжтой бөгөөд ингэснээр үйлчилгээ нь системд ажиллахад бэлэн болсон тухай мэдэгдэнэ. Дахин хэлэхэд, үйлчлүүлэгч-серверийн загварыг ашигладаг Docker үүнийг хийж чадахгүй.

Төлөвлөгөөнд

Бид тодорхой нэг контейнерийг удирдахын тулд системийн нэгжийн файл үүсгэх podmangener systemd CONTAINERID командыг нэмэхээр төлөвлөж байна. Энэ нь эрх мэдэлгүй контейнеруудад root болон rootless горимд ажиллах ёстой. Бид OCI-тэй нийцтэй systemd-nspawn ажиллах цагийн хүсэлтийг ч харсан.

дүгнэлт

Systemd-г контейнерт ажиллуулах нь ойлгомжтой хэрэгцээ юм. Мөн Podman-ийн ачаар бид эцэст нь systemd-тэй зөрчилддөггүй, гэхдээ ашиглахад хялбар болгосон контейнер ажиллах цагтай болсон.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх