Մենք երկար ժամանակ հետևում ենք բեռնարկղերում systemd-ի օգտագործման թեմային։ Դեռ 2014 թվականին մեր անվտանգության ինժեներ Դենիել Ուոլշը հոդված է գրել
Այս հոդվածում մենք ցույց կտանք, թե ինչ է փոխվել ժամանակի ընթացքում և ինչպես կարող է Պոդմանը օգնել մեզ այս հարցում։
Systemd-ը կոնտեյների ներսում գործարկելու բազմաթիվ պատճառներ կան, օրինակ՝
- Բազմաֆունկցիոնալ կոնտեյներներ – Շատերը ցանկանում են վիրտուալ մեքենաներից հանել իրենց բազմաֆունկցիոնալ հավելվածները և գործարկել դրանք բեռնարկղերում: Ավելի լավ կլինի, իհարկե, նման հավելվածները բաժանել միկրոծառայությունների, բայց ոչ բոլորը գիտեն, թե ինչպես դա անել, կամ պարզապես ժամանակ չունեն: Հետևաբար, այնպիսի հավելվածներ գործարկելը, ինչպիսիք են systemd-ի կողմից գործարկված ծառայությունները միավորի ֆայլերից, միանգամայն իմաստալից է:
- Համակարգված միավորի ֆայլեր – Կոնտեյներների ներսում աշխատող հավելվածների մեծ մասը կառուցված է կոդից, որը նախկինում աշխատում էր վիրտուալ կամ ֆիզիկական մեքենաների վրա: Այս հավելվածներն ունեն միավորի ֆայլ, որը գրվել է այս հավելվածների համար և հասկանում է, թե ինչպես պետք է գործարկվեն: Այսպիսով, դեռ ավելի լավ է ծառայություններ սկսել՝ օգտագործելով աջակցվող մեթոդները, այլ ոչ թե կոտրել ձեր սեփական init ծառայությունը:
- Systemd-ը գործընթացների կառավարիչ է: Այն կառավարում է ծառայությունները (անջատում է, վերագործարկում ծառայությունները կամ սպանում զոմբիացման գործընթացները) ավելի լավ, քան ցանկացած այլ գործիք:
Այնուամենայնիվ, կան բազմաթիվ պատճառներ՝ չաշխատելու համակարգված կոնտեյներներում: Հիմնականն այն է, որ systemd/journald-ը վերահսկում է բեռնարկղերի ելքը և նման գործիքները
Պոդմանի գալուստը
Ուրախ ենք տեղեկացնել, որ իրավիճակը վերջապես առաջ է շարժվել։ Red Hat-ում կոնտեյներների գործարկման համար պատասխանատու թիմը որոշեց զարգանալ
Շատերն են դա անում։
Ես և իմ Podman-ը ոչ մի կերպ դեմ չենք համակարգային կոնտեյներներին: Ի վերջո, Systemd-ը ամենահաճախ օգտագործվող Linux init ենթահամակարգն է, և թույլ չտալ, որ այն ճիշտ աշխատի բեռնարկղերում, նշանակում է անտեսել, թե ինչպես են հազարավոր մարդիկ սովոր բեռնարկղեր գործարկել:
Podman-ը գիտի, թե ինչ պետք է անի, որպեսզի systemd-ը ճիշտ աշխատի կոնտեյներով: Դրան անհրաժեշտ են այնպիսի բաներ, ինչպիսիք են tmpfs-ի տեղադրումը /run-ի և /tmp-ի վրա: Նա սիրում է միացված լինել «կոնտեյներացված» միջավայրը և ակնկալում է գրելու թույլտվություններ cgroup գրացուցակի իր մասում և /var/log/journald պանակում:
Երբ դուք գործարկում եք կոնտեյներ, որտեղ առաջին հրամանը init կամ systemd է, Podman-ը ավտոմատ կերպով կարգավորում է tmpfs-ը և Cgroups-ը՝ ապահովելու, որ systemd-ը սկսվում է առանց խնդիրների: Այս ավտոմատ գործարկման ռեժիմն արգելափակելու համար օգտագործեք --systemd=false տարբերակը: Խնդրում ենք նկատի ունենալ, որ Podman-ն օգտագործում է միայն systemd ռեժիմը, երբ տեսնում է, որ պետք է գործարկել systemd կամ init հրամանը:
Ահա մի հատված ձեռնարկից.
մարդ podman վազում
...–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 true
Այժմ նայեք, թե ինչ տեսք ունի Dockerfile-ը Podman-ի միջոցով systemd-ը կոնտեյներով գործարկելու համար.
# 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-ը systemd միավորի ֆայլերում
Եթե բեռնարկղերը պետք է գործարկվեն, երբ համակարգը բեռնաթափվի, ապա դուք կարող եք պարզապես տեղադրել համապատասխան Podman հրամանները systemd միավորի ֆայլի մեջ, որը կսկսի ծառայությունը և կվերահսկի այն: Podman-ն օգտագործում է ստանդարտ fork-exec մոդելը: Այլ կերպ ասած, կոնտեյներային գործընթացները Podman գործընթացի երեխաներ են, ուստի systemd-ը կարող է հեշտությամբ վերահսկել դրանք:
Docker-ն օգտագործում է հաճախորդ-սերվերի մոդել, իսկ Docker CLI հրամանները կարող են տեղադրվել նաև անմիջապես միավորի ֆայլում: Այնուամենայնիվ, երբ Docker հաճախորդը միանում է Docker daemon-ին, այն (հաճախորդը) դառնում է մեկ այլ գործընթաց, որը կառավարում է stdin-ը և stdout-ը: Իր հերթին, systemd-ը գաղափար չունի Docker հաճախորդի և կոնտեյների միջև կապի մասին, որն աշխատում է Docker daemon-ի հսկողության տակ, և, հետևաբար, այս մոդելի շրջանակներում systemd-ը հիմնովին չի կարող վերահսկել ծառայությունը:
Համակարգի ակտիվացում վարդակից
Podman-ը ճիշտ է վարում վարդակի միջոցով ակտիվացումը: Քանի որ Podman-ն օգտագործում է fork-exec մոդելը, այն կարող է փոխանցել վարդակը իր երեխայի կոնտեյների գործընթացներին: Docker-ը չի կարող դա անել, քանի որ օգտագործում է հաճախորդ-սերվեր մոդել:
Varlink ծառայությունը, որը Podman-ն օգտագործում է հեռավոր հաճախորդների հետ կոնտեյներների հետ հաղորդակցվելու համար, իրականում ակտիվանում է վարդակից: Cockpit-podman փաթեթը, որը գրված է Node.js-ով և հանդիսանում է cockpit նախագծի մաս, թույլ է տալիս մարդկանց շփվել Podman կոնտեյներների հետ վեբ ինտերֆեյսի միջոցով: Վեբ-դեյմոնը, որն աշխատում է cockpit-podman-ը, հաղորդագրություններ է ուղարկում varlink վարդակից, որը համակարգված է լսում: Systemd-ն այնուհետև ակտիվացնում է Podman ծրագիրը՝ հաղորդագրություններ ստանալու և բեռնարկղերի կառավարումը սկսելու համար: Systemd-ը վարդակից ակտիվացնելը վերացնում է հեռավոր API-ների ներդրման ժամանակ անընդհատ գործող դեյմոնի անհրաժեշտությունը:
Բացի այդ, մենք մշակում ենք մեկ այլ Podman հաճախորդ, որը կոչվում է podman-remote, որն իրականացնում է նույն Podman CLI-ն, բայց կոչում է varlink՝ կոնտեյներներ գործարկելու համար: Podman-remote-ը կարող է աշխատել SSH նիստերի վերևում, ինչը թույլ է տալիս ապահով կերպով փոխազդել տարբեր մեքենաների բեռնարկղերի հետ: Ժամանակի ընթացքում մենք նախատեսում ենք հնարավորություն տալ podman-remote-ին աջակցել MacOS-ին և Windows-ին Linux-ի հետ մեկտեղ, որպեսզի այդ հարթակներում մշակողները կարողանան գործարկել Linux վիրտուալ մեքենա՝ Podman varlink-ով և ունենալ լիարժեք փորձ, որ կոնտեյներները աշխատում են տեղական մեքենայի վրա:
SD_NOTIFY
Systemd-ը թույլ է տալիս հետաձգել օժանդակ ծառայությունների գործարկումը մինչև նրանց պահանջվող կոնտեյներային ծառայության մեկնարկը: Podman-ը կարող է փոխանցել SD_NOTIFY վարդակը կոնտեյներացված ծառայությանը, որպեսզի ծառայությունը տեղեկացնի համակարգին, որ այն պատրաստ է աշխատել: Եվ կրկին, Docker-ը, որն օգտագործում է հաճախորդ-սերվերի մոդել, չի կարող դա անել:
Պլաններում
Մենք նախատեսում ենք ավելացնել «podman generate systemd CONTAINERID» հրամանը, որը կստեղծի systemd միավոր ֆայլ՝ նշված կոնկրետ կոնտեյների կառավարման համար: Սա պետք է աշխատի և՛ արմատական, և՛ առանց արմատների ռեժիմներում անարտոնյալ բեռնարկղերի համար: Մենք նույնիսկ տեսել ենք OCI-ի հետ համատեղելի systemd-nspawn գործարկման ժամանակի հարցում:
Ամփոփում
Համակարգված կոնտեյներով աշխատելը հասկանալի անհրաժեշտություն է: Եվ Podman-ի շնորհիվ մենք վերջապես ունենք կոնտեյների գործարկման ժամանակ, որը չի հակասում systemd-ին, բայց հեշտացնում է այն օգտագործելը:
Source: www.habr.com