NATS サーバーのアップデート

管理対象ホスト上のブローカーをアップデートするのは一番面白いケースです。なぜなら agent は ブローカー越しにブローカーと話す から — NATS を止めると ジョブの途中で agent との接続が切れます。これに対しては 2 つの仕組みが組み合わさって対処しています:

  1. 再接続。 agent の NATS クライアントはブローカー再起動時に自動再接続します。人の介入は不要。
  2. outbox。 ブローカーが落ちている間に発生したジョブ結果は %ProgramData%\Kanade\outbox\ に貯められ、接続が戻り次第再送されます。新しい NATS サーバーが立ち上がるとすぐに result row が backend に届きます。

したがってフローは backend のアップデート と同じ — スクリプトはサービスを止めてバイナリを差し替え再起動し、agent はブローカーの空白期間を透過的にやり過ごします。

NATS アップデート固有の注意点

懸念実際
result row はロストする?いいえ — outbox がブローカー停止中を跨いで保持し、再接続時に drain します。
SPA からアップデートできる?はい、他のジョブと同じです — kanade exec install-kanade-nats --pcs <broker-host>
NATS が再起動してこなかったら?result は outbox にずっと残ります。operator はブローカーホストの outbox/ を復帰失敗の早期サインとして監視するべき。
新しい NATS バージョンに互換性がなかったら (JetStream のアップグレードなど)?まず canary 1 台に rollout (--pcs <one-broker>)、outbox と backend の健全性を見てから fleet 全体に展開。SPA クエリには 5 分の cache TTL があるので canary の状態は数分以内に反映されます。

手動インストール (ブートストラップ)

初回インストール (ブローカーホストにまだ agent がない状態) では直接ワークフローを使います:

.\scripts\build-release.ps1 -Roles nats       # fetches nats-server.exe
                                              # from github.com/nats-io/nats-server/releases
.\scripts\deploy\nats.ps1 -NatsToken '<token>'

これで nats-server.exe%ProgramFiles%\Kanade\ に、nats-server.conf%ProgramData%\Kanade\config\ にインストール (bearer token を平文で保存するので ACL を SYSTEM + Administrators のみに絞ります)、KanadeNats Windows サービスを登録、TCP 4222 (broker) と 8222 (monitoring HTTP) を開放、サービスを起動します。

agent 経由のアップデート (定常運用)

ステータス: template のみ。scripts/deploy/nats.ps1 はまだ $AgentSource* ノブを持っていません — agent モードは backlog 行きです。下記はノブが入った後の想定形です。

1. nats-server.exe をビルド or 取得

どちらか:

.\scripts\build-release.ps1 -Roles nats   # fetches the binary

…もしくは github.com/nats-io/nats-server/releases から直接ダウンロード。

2. バイナリを publish

kanade app publish nats-server 2.10.20 .\nats-server.exe

3. deploy-nats.ps1 を編集

agent モードノブが入ったあとは、パターンは deploy/backend.ps1 と同じ:

$AgentSourceUrl       = 'http://kanade-backend.example.com:8080'
$AgentSourceVersion   = '2.10.20'
$AgentSourceSha256    = '<nats-server.exe の lowercase hex>'
$AgentSourceAuthToken = '<backend HTTP API 用 bearer>'

4. publish + 登録 + exec

kanade script publish deploy-nats 2.10.20 .\deploy-nats.edited.ps1
kanade job create jobs\install-kanade-nats.yaml
kanade exec install-kanade-nats --pcs <broker-host>

ジョブマニフェストはこんな形になります:

id: install-kanade-nats
version: 2.10.20
execute:
  shell: powershell
  script_object: deploy-nats/2.10.20
  timeout: 300s
  run_as: system
require_approval: true

5. 確認

ブローカーが復帰すると outbox が drain され、/api/results に result row が出てきます。新しい NATS バージョンはブローカーの monitoring エンドポイントで確認:

curl http://<broker>:8222/varz | python -m json.tool | rg version

なぜ独立した「broker update」機構が要らないのか

初期の設計では「ブローカー越しにブローカーを更新する鶏卵問題」を避けるために専用のブートストラップチャネル (agent が broker update 専用に使う並列 NATS 接続) を検討していました。outbox + 再接続のペアによってこれは不要に: 結果は「失われる」のではなく「遅延するだけ」。トランスポートはひとつ、メンタルモデルもひとつで済みます。