Извршувањето на playbook завршува зелено, единицата WireGuard е активна, ракувањето работи, а новиот peer сепак не стигнува никаде. Гледањето playbook како известува за успех додека серверот работи со вчерашната конфигурација е особено фрустрирачко, бидејќи во излезот нема ништо погрешно. Ansible го направи точно она што беше побарано: се погрижи единицата да биде стартувана, а таа веќе беше стартувана. Примената на препишана конфигурациска датотека е друга задача и се случува само ако нешто му каже на сервисот да ја прочита повторно.

Погледнете што всушност известува второто извршување

Извршете го playbook двапати со изменетата конфигурација и споредете го резимето. Второто извршување треба да ја прикаже задачата за единицата како ok, а не changed, бидејќи веќе работоспособниот сервис по дизајн се остава на мира. Тоа е исправно работечка idempotentност и воедно причината зошто новата датотека никогаш не стигнува до kernel.

Додајте проверно извршување со diff излез за да видите кои задачи воопшто би допреле нешто.

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

Трите временски ознаки ја кажуваат приказната пред да прочитате и еден ред лог. Ако конфигурациската датотека е понова од моментот кога единицата стана активна, живиот интерфејс е изграден од постара датотека и секој следен симптом произлегува од тоа.

Ова не е дефект на Ansible. Истото однесување се појавува кај секоја алатка за управување со конфигурација што го одделува «провери дека работи» од «провери дека работи токму ова». Разликата изгледа педантно додека не ве чини едно попладне.

Стартувано е состојба, а не повторно вчитување

state: started тврди услов за единицата. Не ветува дека сервисот ќе ги препрочита своите влезови и не може да знае дека датотека што никогаш не ја отворил е изменета. При распоредување со wg-quick влезовите вклучуваат конфигурација на интерфејсот, адреси, рути, DNS записи и сите post-up куки.

Затоа ажурирана датотека може да содржи нов peer, друга адреса или изменета рутирачка директива, додека живиот интерфејс продолжува да го служи стариот сет. Ракувањето сè уште успева затоа што вчитаните клучеви и крајни точки сè уште важат. Токму тоа го прави дефектот тешко видлив и објаснува зошто луѓето еден час бркаат DNS пред да проверат временска ознака.

Две други опции на модулот често се сметаат за решение. daemon_reload го тера systemd повторно да ги чита датотеките на единиците, што е неважно за WireGuard конфигурација. state: reloaded бара од единицата да ја изврши својата акција за повторно вчитување, а дали таа го прави она што ви треба зависи исклучиво од единицата. Ниту една не го заменува знаењето кои влезови процесот што работи навистина ги прочитал.

Инсталирајте ја датотеката, потоа известете handler

Моделот што ја чува idempotentноста и сепак ги применува промените е вообичаениот: задачата што ја пишува датотеката известува handler, а handler се извршува само кога датотеката навистина се променила. Второ извршување без измени не прави ништо и тоа е она што го сакате.

- 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-ите се извршуваат на крајот на play-от, по задачите што ги известиле, па задача подоцна во истиот play може сè уште да го гледа стариот интерфејс. Ако редоследот е важен, испразнете ги handler-ите експлицитно со meta: flush_handlers пред задачата што зависи од новата конфигурација.

Користете restart наместо reload, освен ако не сте ја провериле акцијата за повторно вчитување на единицата. Горната wg-quick единица поддржува една и ја синхронизира WireGuard конфигурацијата, но не го повторува поставувањето на адреси, рути, DNS или куки. Затоа reload по додавање рутирачка директива изгледа успешно и не менува ништо.

Споредете го живиот уред со датотеката

Проверката што го затвора овој клас грешки е споредба меѓу она што го држи kernel и она што го вели датотеката. Две команди даваат споредлив излез, а разликата е отстапувањето.

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

wg showconf го печати живиот уред, вклучително приватниот клуч, па третирајте го тој излез како тајна и не лепете го во тикет. wg-quick strip ја печати датотеката без клучевите својствени за wg-quick, и затоа двете воопшто се споредливи.

Разлика во списокот peer значи дека датотеката никогаш не била применета. Разлика само во клучеви или крајни точки што очекувавте да се променат значи дека нешто ја применило делумно. Никаква разлика значи дека конфигурацијата е актуелна и дефектот е на друго место, што само по себе е корисен резултат.

Платете ја цената на рестартот свесно

Рестартот на интерфејсот го руши тунелот, а ако тој тунел ја носи вашата административна сесија, рестартот ја завршува сесијата што го побарала. Ставете го handler-от зад прозорец за промени или извршете го playbook од управувачка патека што не зависи од рестартот на интерфејсот.

Цената е причината зошто луѓето посегнуваат по reload. Тоа е разумен инстинкт и станува исправен штом знаете кои промени reload навистина ги применува. За промени на peer и клучеви на горната wg-quick единица е доволно; за адресирање, рутирање и куки не е. Да се разјасни еднаш е поевтино отколку да се открие за време на прозорец за промени.

Документацијата на модулот systemd_service ја објаснува разликата меѓу started, restarted и reloaded и вреди еднаш да се прочита наместо да се претпоставува од зелено резиме. Сè во овој водич произлегува од таа една разлика.

Поврзани статии