Playbook vykdymas baigiasi žaliai, WireGuard unit yra aktyvus, handshake veikia, o naujas peer vis tiek nieko nepasiekia. Stebėti, kaip playbook praneša apie sėkmę, kai serveris veikia su vakarykšte konfigūracija, ypač erzina, nes išvestyje nieko nėra negerai. Ansible padarė būtent tai, ko buvo paprašyta: užtikrino, kad unit būtų paleistas, o jis jau buvo paleistas. Perrašyto konfigūracijos failo taikymas yra kita užduotis, ir ji įvyksta tik tada, kai kažkas pasako tarnybai jį perskaityti iš naujo.

Pažiūrėkite, ką antra eiga iš tikrųjų praneša

Paleiskite playbook du kartus su pakeista konfigūracija ir palyginkite suvestinę. Antra eiga turėtų rodyti unit užduotį kaip ok, o ne changed, nes jau veikianti tarnyba pagal projektą paliekama ramybėje. Tai teisingai veikiantis idempotentiškumas ir kartu priežastis, kodėl naujas failas niekada nepasiekia kernel.

Pridėkite patikros eigą su diff išvestimi, kad pamatytumėte, kurios užduotys apskritai ką nors palies.

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

Trys laiko žymos papasakoja istoriją prieš perskaitant vieną log eilutę. Jei konfigūracijos failas yra naujesnis už momentą, kai unit tapo aktyvus, veikiantis sąsaja buvo sukurta iš senesnio failo, ir visi tolesni simptomai kyla iš to.

Tai ne Ansible defektas. Toks pat elgesys pasireiškia bet kurioje konfigūracijos valdymo priemonėje, kuri atskiria „įsitikink, kad veikia“ nuo „įsitikink, kad veikia būtent tai“. Skirtumas atrodo pedantiškas, kol nekainuoja popietės.

Paleista yra būsena, o ne perkrovimas

state: started teigia unit sąlygą. Jis nežada, kad tarnyba perskaitys savo įvestis, ir negali žinoti, kad failas, kurio niekada neatidarė, pasikeitė. wg-quick diegime įvestys apima sąsajos konfigūraciją, adresus, maršrutus, DNS įrašus ir bet kokius post-up hook.

Todėl atnaujintame faile gali būti naujas peer, kitas adresas ar pakeista maršrutizavimo direktyva, o veikianti sąsaja toliau aptarnauja seną rinkinį. Handshake vis tiek pavyksta, nes įkelti raktai ir galiniai taškai dar galioja. Būtent tai daro gedimą sunkiai pastebimą, ir todėl žmonės valandą vejasi DNS prieš patikrindami laiko žymą.

Dvi kitos modulio parinktys dažnai laikomos sprendimu. daemon_reload priverčia systemd iš naujo skaityti unit failus, kas WireGuard konfigūracijos failui nesvarbu. state: reloaded prašo unit atlikti perkrovimo veiksmą, o ar jis daro tai, ko jums reikia, visiškai priklauso nuo unit. Nė viena nepakeičia žinojimo, kokias įvestis veikiantis procesas iš tikrųjų perskaitė.

Įdiekite failą, tada praneškite handler

Šablonas, kuris išlaiko idempotentiškumą ir vis tiek taiko pakeitimus, yra įprastas: failą rašanti užduotis praneša handler, o handler vykdomas tik tada, kai failas tikrai pasikeitė. Antra eiga be pakeitimų nieko nedaro, ir to jums reikia.

- 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: restarted

Handler vykdomi play pabaigoje, po juos pranešusių užduočių, todėl vėlesnė to paties play užduotis dar gali matyti seną sąsają. Jei tvarka svarbi, aiškiai ištuštinkite handler su meta: flush_handlers prieš užduotį, kuri priklauso nuo naujos konfigūracijos.

Naudokite restart, o ne reload, nebent patikrinote unit perkrovimo veiksmą. Upstream wg-quick unit jį palaiko ir sinchronizuoja WireGuard konfigūraciją, bet iš naujo nevykdo adresų, maršrutų, DNS ar hook nustatymo. Todėl reload po maršruto direktyvos pridėjimo atrodo sėkmingas ir nieko nekeičia.

Palyginkite veikiantį įrenginį su failu

Patikra, kuri uždaro šią klaidų klasę, yra palyginimas tarp to, ką turi kernel, ir to, ką sako failas. Dvi komandos pateikia palyginamą išvestį, o skirtumas yra nuokrypis.

sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)

wg showconf išspausdina veikiantį įrenginį, įskaitant privatų raktą, todėl traktuokite šią išvestį kaip paslaptį ir neįklijuokite jos į bilietą. wg-quick strip išspausdina failą be wg-quick būdingų raktų, ir todėl abu yra palyginami.

Skirtumas peer sąraše reiškia, kad failas niekada nebuvo pritaikytas. Skirtumas tik raktuose ar galiniuose taškuose, kuriuos tikėjotės pasikeisiančius, reiškia, kad kažkas jį pritaikė iš dalies. Visiškai jokio skirtumo reiškia, kad konfigūracija yra aktuali, o gedimas yra kitur, ir tai savaime yra naudingas rezultatas.

Sumokėkite perkrovimo kainą sąmoningai

Sąsajos perkrovimas nutraukia tunelį, o jei tas tunelis perduoda jūsų administravimo sesiją, perkrovimas užbaigia sesiją, kuri jo paprašė. Padėkite handler už pakeitimų lango arba paleiskite playbook iš valdymo kelio, kuris nepriklauso nuo sąsajos perkrovimo.

Kaina yra priežastis, kodėl žmonės griebiasi reload. Tai pagrįstas instinktas, ir jis tampa teisingas, kai žinote, kokius pakeitimus reload iš tikrųjų taiko. Upstream wg-quick unit peer ir raktų pakeitimams to pakanka; adresavimui, maršrutizavimui ir hook – ne. Kartą tai išsiaiškinti pigiau nei atrasti pakeitimų lango metu.

systemd_service modulio dokumentacija paaiškina skirtumą tarp started, restarted ir reloaded, ir verta ją kartą perskaityti, o ne spėlioti iš žalios suvestinės. Viskas šiame vadove kyla iš to vieno skirtumo.

Susiję straipsniai