Անպայման հիմունքներ, առանց որոնց ձեր գրքույկները կպչուն մակարոնեղենի մի կտոր կլինեն

Ես շատ ակնարկներ եմ անում այլ մարդկանց Ansible կոդի վերաբերյալ և ինքս շատ բան գրում: Սխալների վերլուծության ընթացքում (ինչպես ուրիշների, այնպես էլ իմ սեփական), ինչպես նաև մի շարք հարցազրույցների ընթացքում ես հասկացա Ansible-ի օգտատերերի հիմնական սխալը. նրանք մտնում են բարդ բաների մեջ՝ չյուրացնելով հիմնականը:

Այս համընդհանուր անարդարությունը շտկելու համար ես որոշեցի գրել Ansible-ի ներածություն նրանց համար, ովքեր արդեն գիտեն այն: Զգուշացնում եմ ձեզ, սա մարդկանց վերապատմում չէ, սա վաղուց արդեն շատ տառերով և առանց նկարների:

Ընթերցողի ակնկալվող մակարդակն այն է, որ մի քանի հազար տող յամլա արդեն գրված է, ինչ-որ բան արդեն արտադրվում է, բայց «ինչ-որ կերպ ամեն ինչ ծուռ է»:

Վերնագրեր

Հիմնական սխալը, որը թույլ է տալիս Ansible օգտվողը, այն է, որ չգիտի, թե ինչ է կոչվում ինչ-որ բան: Եթե ​​դուք չգիտեք անունները, չեք կարող հասկանալ, թե ինչ է գրված փաստաթղթերում: Կենդանի օրինակ. հարցազրույցի ժամանակ մի անձ, ով թվում էր, թե ասում է, որ շատ է գրել Ansible-ում, չի կարողացել պատասխանել «ինչ տարրերից է բաղկացած խաղագիրքը» հարցին: Եվ երբ ես առաջարկեցի, որ «սպասելի էր պատասխանը, որ խաղագիրքը բաղկացած է խաղից», հետևեց «մենք դա չենք օգտագործում» պախարակելի մեկնաբանությունը։ Մարդիկ Ansible-ը գրում են փողի համար և չեն օգտագործում խաղը: Նրանք իրականում օգտագործում են այն, բայց չգիտեն, թե դա ինչ է:

Այսպիսով, եկեք սկսենք մի պարզ բանից. ինչ է դա կոչվում: Գուցե դուք գիտեք սա, կամ գուցե չգիտեք, որովհետև ուշադրություն չէիք դարձնում փաստաթղթերը կարդալիս:

ansible-playbook-ը կատարում է խաղագիրքը: Playbook-ը yml/yaml ընդլայնմամբ ֆայլ է, որի ներսում կա այսպիսի բան.

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Մենք արդեն հասկացանք, որ այս ամբողջ ֆայլը խաղագիրք է: Մենք կարող ենք ցույց տալ, թե որտեղ են դերերը և որտեղ են առաջադրանքները: Բայց որտեղ է խաղը: Իսկ ո՞րն է խաղի և դերի կամ խաղային գրքի տարբերությունը:

Այդ ամենը փաստաթղթերում է: Ու կարոտում են։ Սկսնակներ - քանի որ շատ բան կա, և դուք միանգամից չեք հիշի ամեն ինչ: Փորձառու, քանի որ «չնչին բաներ»: Եթե ​​փորձառու եք, վերընթերցեք այս էջերը առնվազն վեց ամիսը մեկ անգամ, և ձեր կոդը կդառնա դասի առաջատար:

Այսպիսով, հիշեք. Playbook-ը ցուցակ է, որը բաղկացած է խաղից և import_playbook.
Սա մեկ պիես է.

- hosts: group1
  roles:
    - role1

և սա նաև մեկ այլ պիես է.

- hosts: group2,group3
  tasks:
    - debug:

Ի՞նչ է խաղը: Ինչու՞ է նա:

Խաղը խաղային գրքի հիմնական տարրն է, քանի որ խաղը և միայն խաղը կապում է դերերի և/կամ առաջադրանքների ցանկը հյուրընկալողների ցանկի հետ, որոնց վրա դրանք պետք է կատարվեն: Փաստաթղթերի խորքում կարող եք հիշատակել delegate_to, տեղային որոնումների պլագիններ, ցանցի-cli-ի հատուկ կարգավորումներ, jump hosts և այլն: Նրանք թույլ են տալիս մի փոքր փոխել առաջադրանքների կատարման վայրը: Բայց, մոռացեք դրա մասին: Այս խելացի տարբերակներից յուրաքանչյուրն ունի շատ կոնկրետ կիրառություն, և դրանք հաստատ համընդհանուր չեն: Իսկ մենք խոսում ենք տարրական բաների մասին, որոնք բոլորը պետք է իմանան ու օգտագործեն։

Եթե ​​ուզում ես «ինչ-որ բան» կատարել «ինչ-որ տեղ», ապա գրում ես պիես: Դեր չէ: Ոչ դեր մոդուլների և պատվիրակների հետ: Դու վերցնում ես ու գրում պիես: Որում hosts դաշտում նշում եք, թե որտեղ է պետք կատարել, իսկ դերերում/առաջադրանքներում՝ ինչ կատարել:

Պարզ, չէ՞: Ինչպե՞ս կարող էր այլ կերպ լինել:

Հատկանշական պահերից մեկը, երբ մարդիկ ցանկություն ունեն դա անել ոչ թե խաղի միջոցով, դա «դերը, որը կարգավորում է ամեն ինչ»: Ես կցանկանայի ունենալ մի դեր, որը կարգավորում է ինչպես առաջին տիպի, այնպես էլ երկրորդ տիպի սերվերները:

Արխետիպային օրինակ է մոնիտորինգը: Ես կցանկանայի ունենալ մոնիտորինգի դեր, որը կկարգավորի մոնիտորինգը: Մոնիտորինգի դերը վերապահված է մոնիտորինգի հյուրընկալողներին (ըստ խաղի): Բայց պարզվում է, որ մոնիտորինգի համար մենք պետք է փաթեթներ հասցնենք հյուրընկալողներին, որոնք մենք վերահսկում ենք։ Ինչու չօգտագործել պատվիրակ: Դուք նաև պետք է կարգավորեք iptable-ները: պատվիրակ? Դուք նաև պետք է գրեք/ուղղեք կոնֆիգուրացիա DBMS-ի համար՝ մոնիտորինգը միացնելու համար: պատվիրակ! Իսկ եթե կրեատիվությունը պակասում է, ապա կարող ես պատվիրակություն կազմել include_role ներդիր հանգույցում՝ օգտագործելով բարդ զտիչ խմբերի ցանկում և ներսում include_role դուք կարող եք ավելին անել delegate_to կրկին. Եվ մենք հեռանում ենք ...

Բարի ցանկությունը՝ ունենալ մեկ մոնիտորինգի դեր, որն «ամեն ինչ անում է», մեզ տանում է դեպի լիակատար դժոխք, որտեղից ամենից հաճախ միայն մեկ ելք կա՝ ամեն ինչ վերաշարադրել զրոյից։

Որտե՞ղ է տեղի ունեցել սխալը այստեղ: Այն պահին, երբ դուք հայտնաբերեցիք, որ X հաղորդավարի վրա «x» առաջադրանքը կատարելու համար դուք պետք է գնայիք Y վարողին և այնտեղ «y» անեիք, դուք պետք է կատարեիք մի պարզ վարժություն՝ գնացեք և գրեք play, որը Y վարողին անում է y: «x»-ին ինչ-որ բան մի ավելացրեք, այլ գրեք զրոյից: Նույնիսկ կոշտ կոդավորված փոփոխականներով:

Թվում է, թե վերևի պարբերություններում ամեն ինչ ճիշտ է ասված։ Բայց սա քո դեպքը չէ։ Քանի որ դուք ցանկանում եք գրել բազմակի օգտագործման կոդ, որը չոր է և գրադարանի նման, և դուք պետք է փնտրեք մեթոդ, թե ինչպես դա անել:

Այստեղ է թաքնվում ևս մեկ լուրջ սխալ. Սխալ, որը շատ նախագծերից հանդուրժելի գրվածից (կարող էր ավելի լավ լինել, բայց ամեն ինչ աշխատում է և հեշտ է ավարտվում) վերածեց մի ամբողջական սարսափի, որը նույնիսկ հեղինակը չի կարող հասկանալ: Աշխատում է, բայց Աստված մի արասցե ինչ-որ բան փոխես։

Սխալն այն է. դերը գրադարանային ֆունկցիա է: Այս անալոգիան այնքան լավ սկիզբ է փչացրել, որ դիտելը պարզապես տխուր է: Դերը գրադարանային գործառույթ չէ: Նա չի կարող հաշվարկներ անել և չի կարող որոշումներ կայացնել խաղի մակարդակի վրա: Հիշեցրու ինձ, թե ինչ որոշումներ է կայացնում խաղը:

Շնորհակալություն, դու ճիշտ ես: Play-ը որոշում է կայացնում (ավելի ճիշտ՝ այն պարունակում է տեղեկատվություն) այն մասին, թե որ առաջադրանքները և դերերը պետք է կատարվեն հյուրընկալողների վրա:

Եթե ​​դուք այս որոշումը պատվիրակում եք որևէ դերի, և նույնիսկ հաշվարկներով, դուք ինքներդ ձեզ (և նրան, ով կփորձի վերլուծել ձեր ծածկագիրը) դատապարտում եք թշվառ գոյության: Դերը չի որոշում, թե որտեղ է այն կատարվում։ Այս որոշումը կայացվում է խաղով։ Դերը անում է այն, ինչ ասում են, որտեղ ասում են:

Ինչու է վտանգավոր Ansible-ում ծրագրավորելը և ինչու է COBOL-ն ավելի լավը, քան Ansible-ը, մենք կխոսենք փոփոխականների և jinja-ի մասին գլխում: Առայժմ ասենք մի բան՝ ձեր յուրաքանչյուր հաշվարկ թողնում է գլոբալ փոփոխականների փոփոխությունների անջնջելի հետք, և դուք ոչինչ չեք կարող անել դրա դեմ: Հենց երկու «հետքերը» հատվեցին, ամեն ինչ վերացավ։

Նշում ճղճիմների համար. դերը, անշուշտ, կարող է ազդել վերահսկողության հոսքի վրա: Ուտել delegate_to և այն ունի ողջամիտ օգտագործում: Ուտել meta: end host/play. Բայց! Հիշո՞ւմ եք, որ մենք սովորեցնում ենք հիմունքները: Մոռացել է delegate_to. Խոսքը ամենապարզ և ամենագեղեցիկ Ansible կոդի մասին է։ Որը հեշտ է կարդալ, հեշտ է գրել, հեշտ է վրիպազերծել, հեշտ է փորձարկել և հեշտ է լրացնել: Այսպիսով, ևս մեկ անգամ.

խաղալ և միայն խաղն է որոշում, թե որ հյուրընկալողներին ինչ է կատարվում:

Այս բաժնում մենք անդրադարձանք խաղի և դերի հակադրությանը: Հիմա եկեք խոսենք առաջադրանքների և դերային հարաբերությունների մասին:

Առաջադրանքներ և դերեր

Մտածեք խաղալ.

- hosts: somegroup
  pre_tasks:
    - some_tasks1:
  roles:
     - role1
     - role2
  post_tasks:
     - some_task2:
     - some_task3:

Եկեք ասենք, որ դուք պետք է անեք հիմար: Եվ կարծես թե foo: name=foobar state=present. Որտեղ գրեմ սա? նախապես? գրառում? Դեր ստեղծե՞լ:

...Իսկ ո՞ւր գնացին առաջադրանքները։

Մենք նորից սկսում ենք հիմունքներից՝ խաղային սարքից: Եթե ​​դուք լողում եք այս հարցում, ապա չեք կարող խաղալ որպես հիմք մնացած ամեն ինչի համար, և ձեր արդյունքը կլինի «երերուն»:

Խաղալ սարք. հյուրընկալող հրահանգներ, ինքնին խաղի կարգավորումներ և նախնական առաջադրանքներ, առաջադրանքներ, դերեր, post_tasks բաժիններ: Խաղի համար մնացած պարամետրերն այժմ մեզ համար կարևոր չեն։

Նրանց բաժինների կարգը առաջադրանքներով և դերերով. pre_tasks, roles, tasks, post_tasks. Քանի որ իմաստային առումով կատարման կարգը միջև է tasks и roles պարզ չէ, ապա լավագույն փորձը ասում է, որ մենք ավելացնում ենք բաժին tasks, միայն թե ոչ roles... Եթե ​​կա roles, ապա բոլոր կից առաջադրանքները տեղադրվում են բաժիններով pre_tasks/post_tasks.

Մնում է, որ ամեն ինչ իմաստային առումով պարզ է. նախ pre_tasks, ապա roles, ապա post_tasks.

Բայց մենք դեռ չենք պատասխանել հարցին. որտե՞ղ է մոդուլի կանչը: foo գրել? Արդյո՞ք մենք պետք է մի ամբողջ դեր գրենք յուրաքանչյուր մոդուլի համար: Թե՞ ավելի լավ է ամեն ինչի համար հաստ դեր ունենալ։ Իսկ եթե ոչ դեր, ապա որտե՞ղ գրեմ՝ նախա՞, թե՞ գրառման մեջ։

Եթե ​​այս հարցերին չկա հիմնավորված պատասխան, ապա սա ինտուիցիայի պակասի նշան է, այսինքն՝ այդ նույն «երերուն հիմքերը»։ Եկեք պարզենք այն: Նախ, անվտանգության հարց. Եթե խաղն ունի pre_tasks и post_tasks (և չկան առաջադրանքներ կամ դերեր), ապա կարող է ինչ-որ բան կոտրվել, եթե ես կատարեմ առաջին առաջադրանքը post_tasks Կտեղափոխեմ մինչև վերջ pre_tasks?

Իհարկե, հարցի ձեւակերպումը հուշում է, որ այն կկոտրվի։ Բայց կոնկրետ ի՞նչ։

... Կառավարիչներ. Հիմնական բաները կարդալը բացահայտում է մի կարևոր փաստ. բոլոր կարգավորիչները ավտոմատ կերպով լվացվում են յուրաքանչյուր հատվածից հետո: Նրանք. բոլոր առաջադրանքները սկսած pre_tasks, ապա բոլոր մշակողները, որոնք ծանուցվել են: Այնուհետև բոլոր դերերը և բոլոր մշակողները, որոնք ծանուցվել են դերերում, կատարվում են: հետո post_tasks և նրանց կառավարողները։

Այսպիսով, եթե քաշեք առաջադրանքը post_tasks в pre_tasks, ապա հնարավոր է, որ դուք այն կկատարեք նախքան մշակողի գործարկումը: օրինակ, եթե ներս pre_tasks վեբ սերվերը տեղադրված և կազմաձևված է, և post_tasks ինչ-որ բան ուղարկվում է դրան, այնուհետև փոխանցեք այս առաջադրանքը բաժին pre_tasks կհանգեցնի նրան, որ «ուղարկելու» պահին սերվերը դեռ չի աշխատի և ամեն ինչ կփչանա:

Հիմա եկեք նորից մտածենք, թե ինչու է մեզ անհրաժեշտ pre_tasks и post_tasks? Օրինակ, որպեսզի ավարտին հասցնեք այն ամենը, ինչ անհրաժեշտ է (այդ թվում՝ մշակողները) մինչև դերը կատարելը։ Ա post_tasks թույլ կտա մեզ աշխատել դերերի կատարման արդյունքների հետ (ներառյալ մշակողները):

Ansible-ի խորաթափանց փորձագետը մեզ կասի, թե ինչ է դա: meta: flush_handlers, բայց ինչո՞ւ են մեզ անհրաժեշտ flush_handlers, եթե մենք կարող ենք հիմնվել խաղի ընթացքում հատվածների կատարման կարգի վրա: Ավելին, մետա. when у block և այլն: Որքան լավ իմանաք հասկանալիը, այնքան ավելի շատ նրբերանգներ կարող եք անվանել «բարդ» լուծման համար: Իսկ պարզ լուծումը՝ օգտագործելով բնական բաժանում նախա/դերերի/հետո-ի միջեւ, նրբերանգներ չի առաջացնում:

Եվ վերադառնանք մեր «foo»-ին: Որտեղ պետք է այն դնեմ: Նախա, պաշտոնում, թե՞ դերերում: Ակնհայտ է, որ դա կախված է նրանից, թե արդյոք մեզ անհրաժեշտ են կառավարչի արդյունքները foo-ի համար: Եթե ​​դրանք չկան, ապա foo-ն պետք չէ տեղադրել ոչ նախընտրական, ոչ էլ փոստում, այս բաժինները հատուկ նշանակություն ունեն՝ առաջադրանքների կատարում կոդի հիմնական մասից առաջ և հետո:

Այժմ «դերը կամ առաջադրանքը» հարցի պատասխանը հանգում է նրան, թե ինչն արդեն խաղում է. եթե այնտեղ առաջադրանքներ կան, ապա պետք է դրանք ավելացնել առաջադրանքներին: Եթե ​​կան դերեր, դուք պետք է դեր ստեղծեք (թեկուզ մեկ առաջադրանքից): Հիշեցնեմ, որ առաջադրանքներն ու դերերը միաժամանակ չեն օգտագործվում։

Ansible-ի հիմունքները հասկանալը ողջամիտ պատասխաններ է տալիս ճաշակի թվացող հարցերին:

Առաջադրանքներ և դերեր (մաս երկրորդ)

Հիմա եկեք քննարկենք իրավիճակը, երբ դուք նոր եք սկսում գրել խաղագիրք: Դուք պետք է պատրաստեք ֆու, բար և բազ: Այս երեք առաջադրանքները մե՞կ դեր են, թե՞ երեք դեր: Ամփոփելու համար հարցը՝ ո՞ր պահից պետք է սկսել դերեր գրել: Ի՞նչ իմաստ ունի դերեր գրելը, երբ կարող ես առաջադրանքներ գրել... Ի՞նչ է դերը:

Ամենամեծ սխալներից մեկը (ես արդեն խոսեցի այս մասին) այն է, որ կարծենք, որ դերը նման է ծրագրի գրադարանի ֆունկցիայի: Ինչպիսի՞ն է ընդհանուր ֆունկցիայի նկարագրությունը: Այն ընդունում է մուտքային փաստարկները, փոխազդում է կողմնակի պատճառների հետ, անում է կողմնակի ազդեցությունները և վերադարձնում արժեք:

Հիմա ուշադրություն. Ի՞նչ կարելի է անել սրանից դերում: Դուք միշտ ողջունելի եք անվանել կողմնակի ազդեցություններ, սա ամբողջ Ansible-ի էությունն է՝ ստեղծել կողմնակի ազդեցություններ: Ունե՞ք կողմնակի պատճառներ: Տարրական. Բայց «փոխանցեք արժեքը և վերադարձրեք այն» - այստեղ այն չի աշխատում: Նախ, դուք չեք կարող արժեք փոխանցել դերին: Դուք կարող եք սահմանել գլոբալ փոփոխական՝ խաղալու ողջ կյանքի չափով, vars բաժնում դերի համար: Դուք կարող եք սահմանել գլոբալ փոփոխական՝ դերի ներսում ողջ կյանքի ընթացքում: Կամ նույնիսկ խաղային գրքերի կյանքի ընթացքում (set_fact/register) Բայց դուք չեք կարող ունենալ «տեղական փոփոխականներ»: Չի կարելի «արժեք վերցնել» ու «վերադարձնել»։

Սրանից բխում է հիմնականը՝ Ansible-ում չես կարող ինչ-որ բան գրել առանց կողմնակի բարդություններ առաջացնելու։ Գլոբալ փոփոխականների փոփոխությունը միշտ կողմնակի ազդեցություն է ֆունկցիայի համար: Rust-ում, օրինակ, գլոբալ փոփոխական փոխելն է unsafe. Իսկ Ansible-ում դա դերի արժեքների վրա ազդելու միակ մեթոդն է: Ուշադրություն դարձրեք օգտագործված բառերին. ոչ թե «մի արժեք փոխանցեք դերին», այլ «փոխեք այն արժեքները, որոնք օգտագործում է դերը»: Դերերի միջև մեկուսացում չկա. Չկա մեկուսացում առաջադրանքների և դերերի միջև:

Ընդամենը: դերը ֆունկցիա չէ.

Ի՞նչն է լավ դերի մեջ: Նախ, դերն ունի լռելյայն արժեքներ (/default/main.yaml), երկրորդը, դերն ունի լրացուցիչ տեղեկատու ֆայլեր պահելու համար:

Որո՞նք են լռելյայն արժեքների առավելությունները: Քանի որ Մասլոուի բուրգում, Ansible-ի փոփոխական առաջնահերթությունների բավականին խեղաթյուրված աղյուսակում, դերերի լռելյայններն ամենից ցածր առաջնահերթությունն են (հանած Ansible հրամանի տողի պարամետրերը): Սա նշանակում է, որ եթե դուք պետք է տրամադրեք լռելյայն արժեքներ և չանհանգստանաք, որ դրանք գերակայում են գույքագրման կամ խմբի փոփոխականների արժեքները, ապա դերերի լռելյայնները միակ ճիշտ տեղն են ձեզ համար: (Ես մի փոքր ստում եմ. կան ավելին |d(your_default_here), բայց եթե խոսենք անշարժ վայրերի մասին, ապա միայն դերերի լռելյայն):

Էլ ի՞նչն է հիանալի դերերի մեջ: Քանի որ նրանք ունեն իրենց սեփական կատալոգները: Սրանք դիրեկտորիաներ են փոփոխականների համար՝ և՛ հաստատուն (այսինքն՝ հաշվարկված դերի համար), և՛ դինամիկ (կա կամ օրինաչափություն կամ հակաօրինաչափություն. include_vars հետ {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Սրանք դիրեկտորիաներ են files/, templates/. Նաև այն թույլ է տալիս ունենալ ձեր սեփական մոդուլներն ու պլագինները (library/) Բայց, համեմատած խաղային գրքույկի առաջադրանքների հետ (որը կարող է նաև ունենալ այս ամենը), այստեղ միակ առավելությունն այն է, որ ֆայլերը թափվում են ոչ թե մեկ կույտի, այլ մի քանի առանձին կույտերի մեջ:

Եվս մեկ մանրամասն. կարող եք փորձել ստեղծել դերեր, որոնք հասանելի կլինեն կրկնակի օգտագործման համար (գալակտիկայի միջոցով): Հավաքածուների գալուստով, դերերի բաշխումը կարելի է համարել գրեթե մոռացված:

Այսպիսով, դերերն ունեն երկու կարևոր առանձնահատկություն. դրանք ունեն լռելյայն (եզակի հատկանիշ) և թույլ են տալիս կառուցվածքը կազմել ձեր կոդը:

Վերադառնալով սկզբնական հարցին՝ ե՞րբ կատարել առաջադրանքներ և ե՞րբ կատարել դերեր: Խաղատախտակի առաջադրանքները առավել հաճախ օգտագործվում են կամ որպես «սոսինձ» դերերից առաջ/հետո, կամ որպես անկախ շինարարական տարր (այդ դեպքում կոդում դերեր չպետք է լինեն): Դերերի հետ խառնված նորմալ առաջադրանքների կույտը միանշանակ անփութություն է: Դուք պետք է հավատարիմ մնաք կոնկրետ ոճին՝ կա՛մ առաջադրանք, կա՛մ դեր: Դերերն ապահովում են սուբյեկտների և լռելյայն տարանջատում, առաջադրանքները թույլ են տալիս ավելի արագ կարդալ կոդը: Սովորաբար ավելի «ստացիոնար» (կարևոր և բարդ) ծածկագիրը դրվում է դերերի մեջ, և օժանդակ սցենարները գրվում են առաջադրանքի ոճով:

Կարելի է import_role-ը կատարել որպես առաջադրանք, բայց եթե գրում եք սա, ապա պատրաստ եղեք բացատրել ձեր գեղեցկության զգացողությանը, թե ինչու եք ուզում դա անել:

Խորամիտ ընթերցողը կարող է ասել, որ դերերը կարող են ներմուծել դերեր, դերերը կարող են կախվածություն ունենալ galaxy.yml-ի միջոցով, և կա նաև սարսափելի և սարսափելի include_role — Հիշեցնում եմ, որ մենք կատարելագործում ենք հիմնական Ansible-ի հմտությունները, այլ ոչ թե գեղարվեստական ​​մարմնամարզության:

Գործողներ և առաջադրանքներ

Քննարկենք մեկ այլ ակնհայտ բան՝ կարգավորիչներ: Իմանալը, թե ինչպես դրանք ճիշտ օգտագործել, գրեթե արվեստ է: Ո՞րն է տարբերությունը կարգավորիչի և քաշելու միջև:

Քանի որ մենք հիշում ենք հիմունքները, ահա մի օրինակ.

- hosts: group1
  tasks:
    - foo:
      notify: handler1
  handlers:
     - name: handler1
       bar:

Դերի մշակիչները գտնվում են rolename/handlers/main.yaml-ում: Հանդիսավորները պտտվում են խաղի բոլոր մասնակիցների միջև. pre/post_tasks-ը կարող է դուրս բերել դերերի մշակողներին, իսկ դերը կարող է հանել զբաղվողներին խաղից: Այնուամենայնիվ, մշակողներին ուղղված «խաչ դերային» զանգերը շատ ավելի մեծ վտանգ են առաջացնում, քան չնչին կարգավորիչի կրկնությունը: (Լավագույն փորձի մեկ այլ տարր է փորձել չկրկնել մշակողների անունները):

Հիմնական տարբերությունն այն է, որ առաջադրանքը միշտ կատարվում է (անհզոր) (գումարած/մինուս պիտակներ և when), իսկ կառավարիչը՝ ըստ վիճակի փոփոխության (հրդեհների մասին տեղեկացնել միայն այն դեպքում, եթե այն փոխվել է): Ինչ է սա նշանակում? Օրինակ, այն, որ երբ դուք վերագործարկեք, եթե փոփոխություն չի եղել, ապա չի լինի կարգավորող: Ինչու՞ կարող է լինել, որ մենք պետք է գործարկենք կարգավորիչը, երբ գեներացնող առաջադրանքում փոփոխություն չկար: Օրինակ, քանի որ ինչ-որ բան կոտրվեց և փոխվեց, բայց կատարումը չհասավ կառավարողին: Օրինակ, քանի որ ցանցը ժամանակավորապես անջատված էր: Կազմաձևը փոխվել է, ծառայությունը չի վերագործարկվել: Հաջորդ անգամ, երբ այն սկսեք, կազմաձևն այլևս չի փոխվում, և ծառայությունը մնում է կազմաձևի հին տարբերակով:

Կազմաձևի հետ կապված իրավիճակը չի կարող լուծվել (ավելի ճիշտ, դուք կարող եք ձեզ համար հատուկ վերագործարկման արձանագրություն հորինել ֆայլերի դրոշներով և այլն, բայց սա այլևս «հիմնական անիմաստ» չէ որևէ ձևով): Բայց կա ևս մեկ ընդհանուր պատմություն՝ մենք տեղադրեցինք հավելվածը, ձայնագրեցինք .service-ֆայլ, և հիմա մենք դա ենք ուզում daemon_reload и state=started. Եվ դրա բնական տեղը, կարծես, տնօրինողն է: Բայց եթե դուք այն դարձնեք ոչ թե մշակող, այլ առաջադրանք առաջադրանքների ցանկի կամ դերի վերջում, ապա այն ամեն անգամ անզոր կերպով կկատարվի: Թեկուզ խաղատախտակը մեջտեղից կոտրվեր։ Սա բացարձակապես չի լուծում վերագործարկված խնդիրը (վերագործարկված հատկանիշով առաջադրանք չեք կարող կատարել, քանի որ անզորությունը կորել է), բայց հաստատ արժե անել state=started, playbooks-ի ընդհանուր կայունությունը մեծանում է, քանի որ միացումների քանակը և դինամիկ վիճակը նվազում է:

Բեռնարկիչի մեկ այլ դրական հատկություն այն է, որ այն չի խցանում ելքը: Փոփոխություններ չեղան. ավելորդ բաց թողնված կամ լավ արդյունք չկա, ավելի հեշտ է կարդալ: Դա նաև բացասական հատկություն է. եթե դուք տառասխալ եք գտնում գծային կերպով կատարված առաջադրանքում հենց առաջին իսկ գործարկման ժամանակ, ապա մշակողները կկատարվեն միայն այն դեպքում, երբ փոխվեն, այսինքն. որոշ պայմաններում - շատ հազվադեպ: Օրինակ՝ կյանքումս առաջին անգամ հինգ տարի անց։ Եվ, իհարկե, անվանման մեջ տառասխալ կլինի ու ամեն ինչ կկոտրվի։ Եվ եթե դրանք երկրորդ անգամ չգործարկեք, փոփոխություն չկա:

Առանձին-առանձին, մենք պետք է խոսենք փոփոխականների առկայության մասին: Օրինակ, եթե դուք ծանուցում եք առաջադրանքի մասին հանգույցով, ի՞նչ կլինեն փոփոխականներում: Դուք կարող եք վերլուծական կերպով գուշակել, բայց դա միշտ չէ, որ աննշան է, հատկապես, եթե փոփոխականները գալիս են տարբեր վայրերից:

... Այսպիսով, մշակողները շատ ավելի քիչ օգտակար և շատ ավելի խնդրահարույց են, քան թվում է: Եթե ​​դուք կարող եք ինչ-որ բան գեղեցիկ գրել (առանց ծալքերի) առանց կարգավորիչների, ավելի լավ է դա անել առանց նրանց: Եթե ​​դա գեղեցիկ չի ստացվում, ավելի լավ է նրանց հետ:

Քայքայիչ ընթերցողը իրավացիորեն նշում է, որ մենք չենք քննարկել listenոր մշակողը կարող է զանգահարել ծանուցում մեկ այլ մշակողի համար, որ մշակողը կարող է ներառել import_tasks (որոնք կարող են ներառել_role with_items-ի հետ), որ Ansible-ի մշակման համակարգը Turing-complete է, որ կարգավորիչները ներառում են_role-ից հետաքրքիր կերպով հատվում են խաղի մշակողների հետ, և այլն: դ. - այս ամենը ակնհայտորեն «հիմունքները» չեն):

Թեև կա մեկ հատուկ WTF, որն իրականում հատկանիշ է, որը դուք պետք է հիշեք: Եթե ​​ձեր առաջադրանքը կատարվում է delegate_to և այն ծանուցել է, այնուհետև համապատասխան մշակողը գործարկվում է առանց delegate_to, այսինքն. հաղորդավարի վրա, որտեղ խաղը նշանակված է: (Չնայած կառավարիչը, իհարկե, կարող է ունենալ delegate_to Նույնը):

Առանձին-առանձին ուզում եմ մի քանի խոսք ասել բազմակի օգտագործման դերերի մասին։ Մինչ հավաքածուների հայտնվելը, կար մի գաղափար, որ դուք կարող եք ստեղծել ունիվերսալ դերեր, որոնք կարող են լինել ansible-galaxy install ու գնաց։ Աշխատում է բոլոր տարբերակների բոլոր ՕՀ-երի վրա՝ բոլոր իրավիճակներում: Այնպես որ, իմ կարծիքն է՝ չի ստացվում։ Զանգվածի հետ ցանկացած դեր include_vars, աջակցելով 100500 գործին, դատապարտված է անկյունային գործի սխալների անդունդին: Դրանք կարող են ծածկվել զանգվածային փորձարկումներով, բայց ինչպես ցանկացած փորձարկման դեպքում, կա՛մ դուք ունեք մուտքային արժեքների դեկարտյան արտադրյալ և ընդհանուր գործառույթ, կա՛մ ունեք «անհատական ​​սցենարներ»: Իմ կարծիքն այն է, որ շատ ավելի լավ է, եթե դերը գծային է (ցիկլոմատիկ բարդություն 1):

Ավելի քիչ եթեներ (բացահայտ կամ հռչակագրային՝ ձևով when կամ ձև include_vars ըստ փոփոխականների խմբի), այնքան ավելի լավ է դերը: Երբեմն պետք է ճյուղեր պատրաստել, բայց, կրկնում եմ, ինչքան քիչ լինեն, այնքան լավ։ Այսպիսով, թվում է, թե գալակտիկայի հետ լավ դեր է (այն աշխատում է) մի փունջով when հինգ առաջադրանքներից կարող է ավելի քիչ նախընտրելի լինել, քան «սեփական» դերը: Այն պահը, երբ դերը գալակտիկայի հետ ավելի լավ է, այն է, երբ սկսում ես ինչ-որ բան գրել: Այն պահը, երբ վատանում է, այն է, երբ ինչ-որ բան կոտրվում է, և քեզ մոտ կասկած է առաջանում, որ դա «գալակտիկայի հետ ունեցած դերի» պատճառով է: Դուք բացում եք այն, և կան հինգ ներդիրներ, ութ առաջադրանքների թերթիկներ և մի կույտ when«օվ... Եվ մենք պետք է դա պարզենք: 5 առաջադրանքների փոխարեն գծային ցուցակ, որում կոտրելու բան չկա։

Հետևյալ մասերում

  • Մի փոքր գույքագրման, խմբային փոփոխականների, host_group_vars հավելվածի, hostvars-ի մասին: Ինչպես կապել գորդյան հանգույցը սպագետտիով. Շրջանակի և գերակայության փոփոխականներ, Ansible հիշողության մոդել: «Ուրեմն որտեղ ենք մենք պահում տվյալների բազայի օգտվողի անունը»:
  • jinja: {{ jinja }} — nosql notype nosense փափուկ պլաստիլին։ Այն ամենուր է, նույնիսկ այնտեղ, որտեղ չես սպասում: Մի քիչ մասին !!unsafe և համեղ յամլ:

Source: www.habr.com

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