Ansible siger startet, men WireGuard kører stadig den gamle konfiguration
state: started lader en kørende enhed være, så en omskrevet wg0.conf bliver aldrig anvendt. Tilføj en change-handler, og sammenlign derefter den levende enhed med filen.
Playbook-kørslen slutter grønt, WireGuard-enheden er aktiv, handshaket virker, og den nye peer kan stadig ikke nå noget. At se et playbook melde succes, mens serveren kører gårsdagens konfiguration, er særligt frustrerende, fordi der ikke er noget galt i outputtet. Ansible gjorde præcis, hvad det blev bedt om: det sikrede, at enheden var startet, og enheden var allerede startet. At anvende en omskrevet konfigurationsfil er en anden opgave, og den sker kun, hvis noget beder tjenesten om at læse den igen.
Se, hvad en anden kørsel faktisk rapporterer
Kør playbook to gange med den ændrede konfiguration på plads, og sammenlign opsummeringen. Den anden kørsel bør vise enhedsopgaven som ok, ikke changed, fordi en tjeneste, der allerede kører, med vilje lades i fred. Det er idempotens, der virker korrekt, og det er også grunden til, at den nye fil aldrig når kernen.
Tilføj en kontrolkørsel med diff-output for at se, hvilke opgaver der overhovedet ville røre noget.
ansible-playbook -i inventory site.yml --check --diff
systemctl show wg-quick@wg0 -p ActiveEnterTimestamp -p NRestarts
stat -c '%y %n' /etc/wireguard/wg0.confDe tre tidsstempler fortæller historien, før du læser en enkelt loglinje. Hvis konfigurationsfilen er nyere end det øjeblik, enheden blev aktiv, er det kørende interface bygget fra en ældre fil, og hvert efterfølgende symptom følger af det.
Det er ikke en fejl i Ansible. Den samme adfærd ses med ethvert konfigurationsstyringsværktøj, der skelner mellem »sørg for, at den kører« og »sørg for, at den kører dette«. Forskellen virker pedantisk, indtil den koster dig en eftermiddag.
Startet er en tilstand, ikke en genindlæsning
state: started fastslår en betingelse om enheden. Det lover ikke, at tjenesten læser sine input igen, og det kan ikke vide, at en fil, den aldrig har åbnet, er ændret. Ved en wg-quick-udrulning omfatter inputtene interface-konfigurationen, adresserne, ruterne, DNS-posterne og eventuelle post-up-hooks.
Derfor kan en opdateret fil indeholde en ny peer, en anden adresse eller en ændret routingdirektiv, mens det levende interface fortsat leverer det gamle sæt. Handshaket lykkes stadig, fordi de indlæste nøgler og endpoints stadig er gyldige. Det er netop det, der gør fejlen svær at se, og hvorfor folk jager DNS i en time, før de tjekker et tidsstempel.
To andre modulindstillinger opfattes ofte som en løsning. daemon_reload får systemd til at læse unit-filer igen, hvilket er irrelevant for en WireGuard-konfigurationsfil. state: reloaded beder enheden om at køre sin reload-handling, og om den gør det, du har brug for, afhænger helt af enheden. Ingen af dem erstatter at vide, hvilke input den kørende proces faktisk har læst.
Installer filen, og underret derefter en handler
Mønstret, der bevarer idempotensen og stadig anvender ændringer, er det sædvanlige: opgaven, der skriver filen, underretter en handler, og handleren kører kun, når filen faktisk er ændret. En anden kørsel uden rettelser gør intet, og det er det, du vil have.
- 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: restartedHandlers kører i slutningen af spillet, efter de opgaver, der underrettede dem, så en opgave senere i samme spil kan stadig se det gamle interface. Hvis rækkefølgen er vigtig, skal du tømme handlerne eksplicit med meta: flush_handlers før den opgave, der afhænger af den nye konfiguration.
Brug restart frem for reload, medmindre du har verificeret enhedens reload-handling. Den upstream wg-quick-enhed understøtter en, og den synkroniserer WireGuard-konfigurationen, men den kører ikke opsætning af adresser, ruter, DNS eller hooks igen. Et reload efter tilføjelse af et rutedirektiv ser derfor ud til at lykkes og ændrer intet.
Sammenlign den levende enhed med filen
Den kontrol, der lukker denne klasse af fejl, er en sammenligning mellem det, kernen holder, og det, filen siger. To kommandoer giver sammenligneligt output, og forskellen er afvigelsen.
sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)wg showconf udskriver den levende enhed, inklusive den private nøgle, så behandl det output som en hemmelighed og indsæt det ikke i en ticket. wg-quick strip udskriver filen uden wg-quick-specifikke nøgler, og derfor er de to overhovedet sammenlignelige.
En forskel i peer-listen betyder, at filen aldrig blev anvendt. En forskel begrænset til nøgler eller endpoints, du forventede ville ændre sig, betyder, at noget anvendte den delvist. Ingen forskel betyder, at konfigurationen er aktuel, og fejlen er et andet sted, hvilket i sig selv er et nyttigt resultat.
Betal omstartens pris med vilje
Genstart af interfacet nedlægger tunnelen, og hvis den tunnel bærer din administrative session, afslutter genstarten den session, der bad om den. Sæt handleren bag et ændringsvindue, eller kør playbook fra en administrationsvej, der ikke afhænger af, at interfacet genstartes.
Prisen er grunden til, at folk griber efter reload. Det er et rimeligt instinkt, og det bliver korrekt, når du ved, hvilke ændringer et reload faktisk anvender. For peer- og nøgleændringer på upstream wg-quick-enheden er det nok; for adressering, routing og hooks er det ikke. At få det afklaret én gang er billigere end at opdage det under et ændringsvindue.
Dokumentationen for systemd_service-modulet forklarer forskellen mellem started, restarted og reloaded, og den er værd at læse én gang i stedet for at gætte ud fra en grøn opsummering. Alt i denne gennemgang følger af den ene forskel.