Playbook završava zeleno, WireGuard jedinica je aktivna, handshake radi, a novi peer ipak ne stiže nikamo. Gledati kako playbook javlja uspjeh dok poslužitelj radi po jučerašnjoj konfiguraciji posebno je iritantno jer u izlazu ništa nije pogrešno. Ansible je učinio točno ono što je traženo: pobrinuo se da jedinica bude pokrenuta, a ona je već bila pokrenuta. Primjena prepisane konfiguracijske datoteke drugi je zadatak i događa se samo ako nešto kaže servisu da je ponovno pročita.

Pogledajte što drugo pokretanje doista javlja

Pokrenite playbook dvaput s promijenjenom konfiguracijom na mjestu i usporedite sažetak. Drugo pokretanje treba prikazati zadatak jedinice kao ok, a ne changed, jer se servis koji već radi po dizajnu ostavlja na miru. To je ispravan rad idempotentnosti i ujedno razlog zašto nova datoteka nikada ne stigne do kernela.

Dodajte probno pokretanje s diff izlazom da vidite koji bi zadaci uopće nešto dotakli.

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

Tri vremenske oznake ispričaju priču prije nego pročitate i jedan red zapisa. Ako je konfiguracijska datoteka novija od trenutka kada je jedinica postala aktivna, živo sučelje izgrađeno je iz starije datoteke i svaki daljnji simptom proizlazi iz toga.

To nije greška u Ansibleu. Isto se ponašanje javlja kod svakog alata za upravljanje konfiguracijom koji razdvaja „provjeri da radi“ od „provjeri da radi ovo“. Razlika izgleda pedantno dok vas ne košta jednog poslijepodneva.

Pokrenuto je stanje, a ne ponovno učitavanje

state: started tvrdi uvjet o jedinici. Ne obećava da će servis ponovno pročitati svoje ulaze i ne može znati da se datoteka koju nikad nije otvorio promijenila. Kod wg-quick postavljanja ulazi uključuju konfiguraciju sučelja, adrese, rute, DNS zapise i sve post-up kuke.

Zato ažurirana datoteka može sadržavati novi peer, drugu adresu ili promijenjenu rutnu direktivu, dok živo sučelje nastavlja posluživati stari skup. Handshake i dalje uspijeva jer su učitani ključevi i krajnje točke još valjani. Upravo to čini kvar teško vidljivim i objašnjava zašto ljudi sat vremena jure DNS prije nego provjere vremensku oznaku.

Dvije druge opcije modula često se smatraju rješenjem. daemon_reload tjera systemd da ponovno pročita datoteke jedinica, što je nebitno za WireGuard konfiguraciju. state: reloaded traži da jedinica izvrši svoju radnju ponovnog učitavanja, a radi li ona što vam treba zavisi isključivo od jedinice. Nijedna nije zamjena za znanje koje je ulaze pokrenuti proces stvarno pročitao.

Instalirajte datoteku, pa obavijestite handler

Obrazac koji čuva idempotentnost i ipak primjenjuje promjene uobičajen je: zadatak koji piše datoteku obavještava handler, a handler se izvršava samo kad se datoteka stvarno promijenila. Drugo pokretanje bez izmjena ne radi ništa i to je ono što želite.

- 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

Handleri se izvršavaju na kraju predstave, nakon zadataka koji su ih obavijestili, pa zadatak kasnije u istoj predstavi može još vidjeti staro sučelje. Ako je redoslijed važan, ispraznite handlere izričito pomoću meta: flush_handlers prije zadatka koji zavisi od nove konfiguracije.

Koristite restart, a ne reload, osim ako niste provjerili radnju ponovnog učitavanja jedinice. Nadređena wg-quick jedinica podržava je i sinkronizira WireGuard konfiguraciju, ali ne ponavlja postavljanje adresa, ruta, DNS-a ni kuka. Zato reload nakon dodavanja rutne direktive izgleda uspješno i ništa ne mijenja.

Usporedite živi uređaj s datotekom

Provjera koja zatvara ovu vrstu greške je usporedba onoga što drži kernel s onim što piše u datoteci. Dvije naredbe daju usporediv izlaz, a razlika je odstupanje.

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

wg showconf ispisuje živi uređaj, uključujući privatni ključ, pa taj izlaz tretirajte kao tajnu i ne lijepite ga u ticket. wg-quick strip ispisuje datoteku bez ključeva svojstvenih wg-quicku, i zato su ta dva izlaza uopće usporediva.

Razlika na popisu peerova znači da datoteka nikada nije primijenjena. Razlika samo u ključevima ili krajnjim točkama koje ste očekivali da se promijene znači da ju je nešto primijenilo djelomično. Nikakva razlika znači da je konfiguracija aktualna, a kvar je negdje drugdje, što je samo po sebi koristan rezultat.

Platite cijenu restarta svjesno

Restart sučelja ruši tunel, a ako taj tunel nosi vašu administrativnu sesiju, restart prekida sesiju koja ga je zatražila. Stavite handler iza prozora za promjene ili pokrenite playbook s putanje upravljanja koja ne zavisi od restarta sučelja.

Cijena je razlog zašto ljudi posežu za reloadom. To je razuman nagon i postaje ispravan kad znate koje promjene reload stvarno primjenjuje. Za promjene peera i ključeva na nadređenoj wg-quick jedinici dovoljan je; za adresiranje, rutiranje i kuke nije. Jednom to raščistiti jeftinije je nego otkriti tijekom prozora za promjene.

Dokumentacija modula systemd_service objašnjava razliku između started, restarted i reloaded i vrijedi je jednom pročitati umjesto nagađanja iz zelenog sažetka. Sve u ovom vodiču proizlazi iz te jedne razlike.

Povezani članci