2026 / 04
このラボ全体を支えるクラスターの運用
成果7 サービスに対して単一の GitOps 配信経路と内部名前解決を統一し、ノードデバッグとデプロイ検証の落とし穴を実際の障害の後に文書化しました。
概要
2 台のベアメタルノード上で、単一の共有 Gateway API ゲートウェイの背後に 7 つの ArgoCD 管理アプリケーションを稼働。すべてのアプリで同一の二段階 GitOps パイプラインを採用。
背景
同じクラスターで外部リクエストと再現可能なアプリケーション配信の両方を扱います。
システム
Synced は、必ずしもデプロイ完了ではない。Synced is not always deployed.
課題
kubectl debug Pod の内部からノードをデバッグすることは、ノード自体をデバッグすることと同じではありません。chroot /host はデバッグ Pod 自身のマウント/PID 名前空間のスナップショットであり、ホストのライブ状態ではありません——/proc は空を返し、内部で実行した mount/umount は実際のホストのマウントテーブルに反映されません。これを信じてしまうかどうかが、NAS 再構築中のクリーンな修正と実際の障害発生の分かれ目でした。
調査
最初の仮説
chroot /host はライブなホストを示し、ArgoCD の Synced は対象ビルドのデプロイ完了を示すと考えました。
ホストの本当に最新の状態に依存する操作(マウント後の書き込み、既にマウント済みかの確認など)は、デバッグ Pod のスナップショット内で直接実行するのではなく、chroot /host systemd-run --wait --pipe --collect でホスト自身の systemd に委譲する必要があります。この「便利な代理ではなく本物の状態を確かめる」という習慣はクラスター全体で現れます。二段階 GitOps パイプライン(push がビルドをトリガーし、別の後続コミットがデプロイ済みイメージタグを更新)では、自分のコミットに対する ArgoCD の Synced+Healthy 状態を確認しても、そのコミットがイメージ参照に触れていなければ何も証明しません——実際のタグ更新コミットを待つ必要があります。
証拠
chroot /host systemd-run --wait --pipe --collect …デバッグ Pod は別の namespace のスナップショットで、ビルドコミットの後には別のタグ更新コミットが存在しました。
判断
ホスト状態に依存する処理はホストの systemd へ委譲し、タグ更新コミットをデプロイの基準にしました。
結果
ラボ全体のワイルドカード DNS(dnsmasq)と Cloudflare Zero Trust のプライベートルーティングにより、LAN 内でもリモートでも内部の *.local ホスト名にアプリごとの再設定なしで同じ方法でアクセス可能——生のクラスター IP を公開する代替案として意図的に採用したものです。
次に変えること
現在の制約: ベアメタル 2 台は小さな障害領域であり、保守には引き続き順序設計が必要です。
次の一手: 復旧手順の演習と、基盤レベルのサービス目標を整備します。
関連する記録
chroot /host はライブノードではなかった →技術構成
Kubernetes · Gateway API (kgateway) · ArgoCD · GitLab CI · Cloudflare Tunnel + Zero Trust · dnsmasq