Playbook-køyringa endar grønt, WireGuard-eininga er aktiv, handtrykket fungerer, og den nye peer-en når framleis ingen ting. Å sjå ein playbook melde suksess medan tenaren køyrer gårsdagens konfigurasjon er særleg frustrerande, fordi ingenting i utdata er gale. Ansible gjorde nøyaktig det det vart bedt om: det sytte for at eininga var starta, og eininga var alt starta. Å ta i bruk ei omskriven konfigurasjonsfil er ei anna oppgåve, og det skjer berre om noko ber tenesta lese ho på nytt.

Sjå kva ei andre køyring faktisk rapporterer

Køyr playbooken to gonger med den endra konfigurasjonen og samanlikn samandraget. Den andre køyringa bør vise einingsoppgåva som ok, ikkje changed, fordi ei teneste som alt køyrer med vilje blir late i fred. Det er idempotens som verkar rett, og det er òg grunnen til at den nye fila aldri når kjernen.

Legg til ei kontrollkøyring med diff-utdata for å sjå kva oppgåver som i det heile ville røre noko.

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

Dei tre tidsstempla fortel historia før du les éi einaste logglinje. Om konfigurasjonsfila er nyare enn augneblinken eininga vart aktiv, er det køyrande grensesnittet bygt frå ei eldre fil, og kvart etterfølgjande symptom følgjer av det.

Dette er ikkje ein feil i Ansible. Same åtferd viser seg med alle konfigurasjonsstyringsverktøy som skil «syt for at det køyrer» frå «syt for at det køyrer dette». Skilnaden verkar pedantisk heilt til han kostar deg ein ettermiddag.

Starta er ein tilstand, ikkje ei omlasting

state: started hevdar eit vilkår om eininga. Det lovar ikkje at tenesta les inndata sine på nytt, og det kan ikkje vite at ei fil det aldri har opna, er endra. Ved ei wg-quick-utrulling omfattar inndataa grensesnittkonfigurasjonen, adressene, rutene, DNS-oppføringane og eventuelle post-up-krokar.

Difor kan ei oppdatert fil innehalde ein ny peer, ei anna adresse eller eit endra rutingsdirektiv medan det levande grensesnittet framleis tener det gamle settet. Handtrykket lukkast framleis fordi nøklane og endepunkta som vart lasta, framleis er gyldige. Nettopp det gjer feilen vanskeleg å sjå, og difor jagar folk DNS i ein time før dei sjekkar eit tidsstempel.

To andre modulval blir ofte oppfatta som ei løysing. daemon_reload får systemd til å lese einingsfiler på nytt, noko som er irrelevant for ei WireGuard-konfigurasjonsfil. state: reloaded ber eininga køyre omlastingshandlinga si, og om ho gjer det du treng, avheng heilt av eininga. Ingen av dei erstattar å vite kva inndata den køyrande prosessen faktisk las.

Installer fila, og varsle deretter ein handterar

Mønsteret som bevarer idempotensen og likevel brukar endringar, er det vanlege: oppgåva som skriv fila, varslar ein handterar, og handteraren køyrer berre når fila faktisk er endra. Ei andre køyring utan redigeringar gjer ingenting, og det er det du vil.

- 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

Handterarar køyrer på slutten av playet, etter oppgåvene som varsla dei, så ei oppgåve seinare i same play kan framleis sjå det gamle grensesnittet. Om rekkefølgja er viktig, tøm handterarane eksplisitt med meta: flush_handlers før oppgåva som avheng av den nye konfigurasjonen.

Bruk restart i staden for reload, med mindre du har stadfesta omlastingshandlinga til eininga. Upstream wg-quick-eininga støttar ei, og ho synkroniserer WireGuard-konfigurasjonen, men ho køyrer ikkje oppsett av adresser, ruter, DNS eller krokar på nytt. Ei reload etter å ha lagt til eit rutedirektiv ser difor ut til å lukkast og endrar ingenting.

Samanlikn den levande eininga med fila

Kontrollen som lukkar denne feilklassen, er ein samanlikning mellom det kjernen har, og det fila seier. To kommandoar gjev samanliknbare utdata, og skilnaden er avviket.

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

wg showconf skriv ut den levande eininga, inkludert den private nøkkelen, så handsam utdataa som ei løyndom og ikkje lim dei inn i ei sak. wg-quick strip skriv ut fila utan nøklane som er spesifikke for wg-quick, og difor er dei to samanliknbare i det heile.

Ein skilnad i peer-lista tyder at fila aldri vart brukt. Ein skilnad avgrensa til nøklar eller endepunkt du venta skulle endre seg, tyder at noko brukte ho delvis. Ingen skilnad tyder at konfigurasjonen er oppdatert og feilen ligg ein annan stad, noko som i seg sjølv er eit nyttig resultat.

Betal prisen for omstarten med vilje

Omstart av grensesnittet riv ned tunnelen, og om den tunnelen ber den administrative økta di, avsluttar omstarten økta som bad om han. Set handteraren bak eit endringsvindauge, eller køyr playbooken frå ein administrasjonsveg som ikkje avheng av at grensesnittet blir starta på nytt.

Prisen er grunnen til at folk grip etter reload. Det er ein rimeleg instinkt, og han blir rett når du veit kva endringar ein reload faktisk brukar. For peer- og nøkkelendringar på upstream wg-quick-eininga er det nok; for adressering, ruting og krokar er det ikkje. Å avklare det éin gong er billegare enn å oppdage det i eit endringsvindauge.

Dokumentasjonen for systemd_service-modulen forklarer skilnaden mellom started, restarted og reloaded, og han er verdt å lese éin gong i staden for å gjetta frå eit grønt samandrag. Alt i denne gjennomgangen følgjer av den eine skilnaden.

Relaterte artiklar