Playbook skončí zeleně, jednotka WireGuard je aktivní, handshake funguje a nový peer přesto nikam nedosáhne. Sledovat, jak playbook hlásí úspěch, zatímco server běží s včerejší konfigurací, je zvlášť otravné, protože ve výstupu není nic špatně. Ansible udělal přesně to, co se po něm chtělo: zajistil, že jednotka je spuštěná, a ona už spuštěná byla. Použití přepsaného konfiguračního souboru je jiný úkol a nastane jen tehdy, když něco službě řekne, aby ho znovu načetla.

Podívejte se, co druhý běh skutečně hlásí

Spusťte playbook dvakrát se změněnou konfigurací na místě a porovnejte souhrn. Druhý běh má úlohu jednotky ukázat jako ok, ne changed, protože běžící služba se záměrně nechává být. To je idempotence fungující správně a zároveň důvod, proč se nový soubor nikdy nedostane do jádra.

Přidejte kontrolní běh s výstupem diff, abyste viděli, které úlohy by se vůbec něčeho dotkly.

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

Tři časové značky řeknou celý příběh dřív, než přečtete jediný řádek logu. Pokud je konfigurační soubor novější než okamžik, kdy jednotka začala být aktivní, běžící rozhraní bylo sestaveno ze staršího souboru a všechny následné příznaky z toho plynou.

Není to vada Ansiblu. Stejné chování se objevuje u každého nástroje pro správu konfigurace, který odděluje „ujisti se, že to běží“ od „ujisti se, že to běží tohle“. Rozdíl vypadá pedantsky, dokud vás to nestojí odpoledne.

Spuštěno je stav, ne znovunačtení

state: started tvrdí podmínku o jednotce. Neslibuje, že služba znovu načte své vstupy, a nemůže vědět, že soubor, který nikdy neotevřela, se změnil. U nasazení wg-quick vstupy zahrnují konfiguraci rozhraní, adresy, trasy, záznamy DNS a všechny post-up hooky.

Proto může aktualizovaný soubor obsahovat nový peer, jinou adresu nebo změněnou směrovací direktivu, zatímco živé rozhraní dál obsluhuje starou sadu. Handshake stále projde, protože načtené klíče a koncové body jsou pořád platné. Právě proto je selhání těžko vidět a lidé hodinu honí DNS, než zkontrolují časovou značku.

Dvě další volby modulu se často považují za řešení. daemon_reload přiměje systemd znovu načíst soubory jednotek, což je pro konfiguraci WireGuardu irelevantní. state: reloaded žádá jednotku o provedení akce reload a zda dělá, co potřebujete, závisí čistě na jednotce. Ani jedna nenahrazuje vědomost, které vstupy běžící proces skutečně přečetl.

Nainstalujte soubor a pak vyrozumějte handler

Vzor, který zachová idempotenci a přesto změny aplikuje, je obvyklý: úloha, která soubor zapisuje, vyrozumí handler a handler se spustí jen tehdy, když se soubor skutečně změnil. Druhý běh bez úprav neudělá nic, a to je přesně to, co chcete.

- 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

Handlery běží na konci hry, po úlohách, které je vyrozuměly, takže úloha později ve stejné hře může ještě vidět staré rozhraní. Pokud záleží na pořadí, vyprázdněte handlery explicitně pomocí meta: flush_handlers před úlohou, která na nové konfiguraci závisí.

Používejte restart, ne reload, dokud neověříte akci reloadu jednotky. Upstream jednotka wg-quick ji podporuje a synchronizuje konfiguraci WireGuardu, ale znovu nespouští nastavení adres, tras, DNS ani hooků. Reload po přidání směrovací direktivy tedy vypadá úspěšně a nic nezmění.

Porovnejte živé zařízení se souborem

Kontrola, která tuto třídu chyb uzavírá, je porovnání toho, co drží jádro, s tím, co říká soubor. Dva příkazy dávají srovnatelný výstup a rozdíl je odchylka.

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

wg showconf vypisuje živé zařízení včetně privátního klíče, takže s tím výstupem zacházejte jako s tajemstvím a nevkládejte ho do ticketu. wg-quick strip vypisuje soubor bez klíčů specifických pro wg-quick, a proto jsou oba výstupy vůbec srovnatelné.

Rozdíl v seznamu peerů znamená, že soubor nebyl nikdy použit. Rozdíl jen v klíčích nebo koncových bodech, které jste čekali změnit, znamená, že ho něco použilo částečně. Žádný rozdíl znamená, že konfigurace je aktuální a závada je jinde, což je samo o sobě užitečný výsledek.

Zaplaťte cenu restartu vědomě

Restart rozhraní shodí tunel, a pokud ten tunel nese vaši administrativní relaci, restart ukončí relaci, která ho vyžádala. Dejte handler za okno změn, nebo spouštějte playbook z řídicí cesty, která nezávisí na restartu rozhraní.

Cena je důvod, proč lidé sahají po reloadu. Je to rozumný instinkt a správný je ve chvíli, kdy víte, které změny reload skutečně aplikuje. U změn peerů a klíčů na upstream jednotce wg-quick stačí; u adresování, směrování a hooků ne. Vyřešit to jednou je levnější než to objevit během okna změn.

Dokumentace modulu systemd_service vysvětluje rozdíl mezi started, restarted a reloaded a stojí za jedno přečtení místo hádání ze zeleného souhrnu. Všechno v tomto průchodu plyne z toho jednoho rozdílu.

Související články