Ansible-ը հայտնում է՝ գործարկված է, բայց WireGuard-ը դեռ աշխատում է հին կոնֆիգուրացիայով
state: started-ը ձեռք չի տալիս արդեն աշխատող unit-ին, ուստի վերագրված wg0.conf-ը երբեք չի կիրառվում։ Ավելացրեք փոփոխության handler, ապա համեմատեք կենդանի սարքը ֆայլի հետ։
Playbook-ի աշխատանքը ավարտվում է կանաչ, WireGuard unit-ը ակտիվ է, handshake-ը աշխատում է, բայց նոր peer-ը դեռ ոչ մի տեղ չի հասնում։ Playbook-ի հաջողության մասին հաղորդում տեսնելը, մինչ սերվերը աշխատում է երեկվա կոնֆիգուրացիայով, առանձնահատուկ հուսահատեցնող է, որովհետև ելքի մեջ ոչինչ սխալ չէ։ Ansible-ը արեց ճիշտ այն, ինչ խնդրվել էր՝ համոզվեց, որ unit-ը գործարկված է, և այն արդեն գործարկված էր։ Վերագրված կոնֆիգուրացիոն ֆայլը կիրառելը այլ խնդիր է և տեղի է ունենում միայն այն դեպքում, երբ ինչ-որ բան ասում է ծառայությանը կրկին կարդալ այն։
Տեսեք, թե երկրորդ աշխատանքը իրականում ինչ է հաղորդում
Գործարկեք playbook-ը երկու անգամ փոփոխված կոնֆիգուրացիայով և համեմատեք ամփոփումը։ Երկրորդ աշխատանքը պետք է unit-ի խնդիրը ցույց տա որպես ok, ոչ թե changed, որովհետև արդեն աշխատող ծառայությունը նախագծով մնում է անձեռնմխելի։ Դա ճիշտ աշխատող idempotence է, և դա է նաև պատճառը, որ նոր ֆայլը երբեք չի հասնում kernel-ին։
Ավելացրեք diff ելքով ստուգիչ աշխատանք՝ տեսնելու, թե որ խնդիրներն ընդհանրապես ինչ-որ բանի կդիպչեն։
ansible-playbook -i inventory site.yml --check --diff
systemctl show wg-quick@wg0 -p ActiveEnterTimestamp -p NRestarts
stat -c '%y %n' /etc/wireguard/wg0.confԵրեք ժամանակադրոշմները պատմում են պատմությունը մինչև մեկ տող log կարդալը։ Եթե կոնֆիգուրացիոն ֆայլը ավելի նոր է, քան unit-ի ակտիվ դառնալու պահը, ապա աշխատող ինտերֆեյսը կառուցվել է ավելի հին ֆայլից, և բոլոր հետագա ախտանիշները բխում են դրանից։
Սա Ansible-ի թերություն չէ։ Նույն վարքը երևում է ցանկացած կոնֆիգուրացիայի կառավարման գործիքում, որը տարանջատում է «համոզվիր, որ աշխատում է»-ը «համոզվիր, որ սա է աշխատում»-ից։ Տարբերությունը մանրախնդիր է թվում, մինչև այն ձեզ մի կես օր արժենա։
Գործարկվածը վիճակ է, ոչ թե վերաբեռնում
state: started պնդում է unit-ի վերաբերյալ պայման։ Այն չի խոստանում, որ ծառայությունը կրկին կկարդա իր մուտքերը, և չի կարող իմանալ, որ ֆայլը, որը երբեք չի բացել, փոխվել է։ wg-quick տեղակայման դեպքում մուտքերը ներառում են ինտերֆեյսի կոնֆիգուրացիան, հասցեները, երթուղիները, DNS գրառումները և ցանկացած post-up hook։
Այդ պատճառով թարմացված ֆայլը կարող է պարունակել նոր peer, այլ հասցե կամ փոփոխված երթուղային հրահանգ, մինչ աշխատող ինտերֆեյսը շարունակում է սպասարկել հին հավաքածուն։ Handshake-ը դեռ հաջողվում է, քանի որ բեռնված բանալիներն ու վերջնակետերը դեռ վավեր են։ Հենց դա է խափանումը դժվար տեսանելի դարձնում, և դրա համար մարդիկ մեկ ժամ DNS-ի հետևից են ընկնում մինչև ժամանակադրոշմը ստուգելը։
Մոդուլի ևս երկու տարբերակ հաճախ լուծում են համարվում։ daemon_reload-ը ստիպում է systemd-ին կրկին կարդալ unit ֆայլերը, ինչը կապ չունի WireGuard կոնֆիգուրացիոն ֆայլի հետ։ state: reloaded-ը խնդրում է unit-ին կատարել իր վերաբեռնման գործողությունը, և արդյոք այն անում է ձեզ անհրաժեշտը, ամբողջովին կախված է unit-ից։ Ոչ մեկը չի փոխարինում իմանալուն, թե աշխատող պրոցեսն իրականում որ մուտքերն է կարդացել։
Տեղադրեք ֆայլը, ապա տեղեկացրեք handler-ին
Կաղապարը, որը պահպանում է idempotence-ը և միևնույն ժամանակ կիրառում փոփոխությունները, սովորականն է. ֆայլը գրող խնդիրը տեղեկացնում է handler-ին, և handler-ը աշխատում է միայն այն ժամանակ, երբ ֆայլն իսկապես փոխվել է։ Առանց խմբագրման երկրորդ աշխատանքը ոչինչ չի անում, և դա է ձեզ պետք։
- name: write the interface configuration
ansible.builtin.template:
src: wg0.conf.j2
dest: /etc/wireguard/wg0.conf
owner: root
mode: "0600"
notify: apply wg0
- name: ensure the interface unit is enabled
ansible.builtin.systemd_service:
name: wg-quick@wg0
enabled: true
state: started
- name: apply wg0
listen: apply wg0
ansible.builtin.systemd_service:
name: wg-quick@wg0
state: restartedHandler-ները աշխատում են play-ի վերջում՝ իրենց տեղեկացրած խնդիրներից հետո, ուստի նույն play-ի ավելի ուշ խնդիրը կարող է դեռ տեսնել հին ինտերֆեյսը։ Եթե հերթականությունը կարևոր է, բացահայտ դատարկեք handler-ները meta: flush_handlers-ով նախքան նոր կոնֆիգուրացիայից կախված խնդիրը։
Օգտագործեք restart, ոչ թե reload, եթե չեք ստուգել unit-ի վերաբեռնման գործողությունը։ Upstream wg-quick unit-ը աջակցում է մեկին և համաժամեցնում WireGuard կոնֆիգուրացիան, բայց չի կրկնում հասցեների, երթուղիների, DNS-ի կամ hook-երի կարգավորումը։ Այդ պատճառով երթուղային հրահանգ ավելացնելուց հետո reload-ը հաջող է թվում և ոչինչ չի փոխում։
Համեմատեք աշխատող սարքը ֆայլի հետ
Այս դասի սխալները փակող ստուգումը kernel-ի պահածի և ֆայլի ասածի համեմատությունն է։ Երկու հրաման տալիս են համեմատելի ելք, և տարբերությունը հենց շեղումն է։
sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)wg showconf-ը տպում է աշխատող սարքը՝ ներառյալ մասնավոր բանալին, ուստի այդ ելքը գաղտնիք համարեք և չկպցնեք տոմսի մեջ։ wg-quick strip-ը տպում է ֆայլը՝ առանց wg-quick-ին հատուկ բանալիների, և հենց դրա համար երկուսը համեմատելի են։
Peer ցանկում տարբերությունը նշանակում է, որ ֆայլը երբեք չի կիրառվել։ Տարբերություն միայն այն բանալիներում կամ վերջնակետերում, որոնք սպասում էիք փոխել, նշանակում է, որ ինչ-որ բան այն կիրառել է մասամբ։ Տարբերության բացակայությունը նշանակում է, որ կոնֆիգուրացիան ընթացիկ է, և խափանումը այլ տեղ է, ինչն ինքնին օգտակար արդյունք է։
Վճարեք վերագործարկման գինը գիտակցաբար
Ինտերֆեյսի վերագործարկումը գցում է թունելը, և եթե այդ թունելը կրում է ձեր ադմինիստրատիվ սեսիան, վերագործարկումը վերջ է տալիս այն սեսիային, որը պահանջել է այն։ Handler-ը դրեք փոփոխության պատուհանի հետևում կամ playbook-ը գործարկեք կառավարման այն ուղուց, որը կախված չէ ինտերֆեյսի վերագործարկումից։
Գինն է պատճառը, որ մարդիկ դիմում են reload-ին։ Դա խելամիտ բնազդ է և ճիշտ է դառնում, երբ գիտես, թե reload-ը իրականում ինչ փոփոխություններ է կիրառում։ Upstream wg-quick unit-ում peer-ի և բանալիների փոփոխությունների համար դա բավարար է. հասցեների, երթուղավորման և hook-երի համար՝ ոչ։ Մեկ անգամ պարզաբանելը ավելի էժան է, քան փոփոխության պատուհանի ընթացքում հայտնաբերելը։
systemd_service մոդուլի փաստաթղթերը բացատրում են տարբերությունը started, restarted և reloaded-ի միջև, և արժե մեկ անգամ կարդալ այն՝ կանաչ ամփոփումից ենթադրելու փոխարեն։ Այս ուղեցույցի ամեն ինչ բխում է այդ մեկ տարբերությունից։