Աշխատում է համակարգված կոնտեյներով

Մենք երկար ժամանակ հետևում ենք բեռնարկղերում systemd-ի օգտագործման թեմային։ Դեռ 2014 թվականին մեր անվտանգության ինժեներ Դենիել Ուոլշը հոդված է գրել Աշխատում է Docker Container-ի ներսում, իսկ մի երկու տարի անց՝ մեկ ուրիշը, որը կոչվեց Աշխատում է համակարգված ոչ արտոնյալ կոնտեյներով, որում նա հայտարարեց, որ իրավիճակը առանձնապես չի բարելավվել։ Նա, մասնավորապես, գրել է, որ «ցավոք, նույնիսկ երկու տարի անց, եթե գուգլում եք «Docker system», ապա առաջին բանը, որ հայտնվում է, նրա նույն հին հոդվածն է։ Այնպես որ, ժամանակն է ինչ-որ բան փոխելու»: Բացի այդ, մենք արդեն խոսել ենք հակամարտություն Docker-ի և systemd ծրագրավորողների միջև.

Աշխատում է համակարգված կոնտեյներով

Այս հոդվածում մենք ցույց կտանք, թե ինչ է փոխվել ժամանակի ընթացքում և ինչպես կարող է Պոդմանը օգնել մեզ այս հարցում։

Systemd-ը կոնտեյների ներսում գործարկելու բազմաթիվ պատճառներ կան, օրինակ՝

  1. Բազմաֆունկցիոնալ կոնտեյներներ – Շատերը ցանկանում են վիրտուալ մեքենաներից հանել իրենց բազմաֆունկցիոնալ հավելվածները և գործարկել դրանք բեռնարկղերում: Ավելի լավ կլինի, իհարկե, նման հավելվածները բաժանել միկրոծառայությունների, բայց ոչ բոլորը գիտեն, թե ինչպես դա անել, կամ պարզապես ժամանակ չունեն: Հետևաբար, այնպիսի հավելվածներ գործարկելը, ինչպիսիք են systemd-ի կողմից գործարկված ծառայությունները միավորի ֆայլերից, միանգամայն իմաստալից է:
  2. Համակարգված միավորի ֆայլեր – Կոնտեյներների ներսում աշխատող հավելվածների մեծ մասը կառուցված է կոդից, որը նախկինում աշխատում էր վիրտուալ կամ ֆիզիկական մեքենաների վրա: Այս հավելվածներն ունեն միավորի ֆայլ, որը գրվել է այս հավելվածների համար և հասկանում է, թե ինչպես պետք է գործարկվեն: Այսպիսով, դեռ ավելի լավ է ծառայություններ սկսել՝ օգտագործելով աջակցվող մեթոդները, այլ ոչ թե կոտրել ձեր սեփական init ծառայությունը:
  3. Systemd-ը գործընթացների կառավարիչ է: Այն կառավարում է ծառայությունները (անջատում է, վերագործարկում ծառայությունները կամ սպանում զոմբիացման գործընթացները) ավելի լավ, քան ցանկացած այլ գործիք:

Այնուամենայնիվ, կան բազմաթիվ պատճառներ՝ չաշխատելու համակարգված կոնտեյներներում: Հիմնականն այն է, որ systemd/journald-ը վերահսկում է բեռնարկղերի ելքը և նման գործիքները Կուբերնետես կամ OpenShift- ը ակնկալել, որ կոնտեյներները գրեն log ուղղակիորեն stdout-ում և stderr-ում: Հետևաբար, եթե դուք պատրաստվում եք կառավարել բեռնարկղերը վերը նշվածների նման նվագախմբային գործիքների միջոցով, ապա պետք է լրջորեն մտածեք համակարգային վրա հիմնված կոնտեյներների օգտագործման մասին: Բացի այդ, Docker և Moby ծրագրավորողները հաճախ կտրականապես դեմ են եղել բեռնարկղերում systemd-ի օգտագործմանը:

Պոդմանի գալուստը

Ուրախ ենք տեղեկացնել, որ իրավիճակը վերջապես առաջ է շարժվել։ Red Hat-ում կոնտեյներների գործարկման համար պատասխանատու թիմը որոշեց զարգանալ ձեր սեփական կոնտեյների շարժիչը. Նա ստացել է անուն Պոդման և առաջարկում է նույն հրամանի տողի միջերեսը (CLI), ինչ Docker-ը: Եվ գրեթե բոլոր Docker հրամանները կարող են օգտագործվել Podman-ում նույն կերպ։ Մենք հաճախ անցկացնում ենք սեմինարներ, որոնք այժմ կոչվում են Փոխելով Docker-ը Podman-ի, և հենց առաջին սլայդը պահանջում է գրել՝ alias docker=podman։

Շատերն են դա անում։

Ես և իմ 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

Добавить комментарий