Fedora CoreOSの自動アップデート管理:クラスターの一斉再起動を防ぐ方法

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

自動化機能が「裏目」に出る時

開発機としてFedoraを使うのは、パッケージが常に最新なので非常に快適です。しかし、Fedora CoreOS (FCOS) を本番環境に導入すると、その「完全自動化」の哲学が、笑えないトラブルを引き起こすことがあります。FCOSはデフォルトで、新しいカーネルを適用するためにパッチのダウンロード、インストール、 preschool 再起動を自動的に行います。

3台のノードで構成されるWebサーバークラスターを運用していると想像してください。午前3時ちょうど、3台すべてのノードがアップデートを検知します。それらは一斉にダウンロードし、そして一斉に…再起動します。結果として、システムが「勤勉」すぎたために、全サービスが3〜5分間完全にダウンしてしまいます。Etcdのような繊細なシステムでは、2/3のノードを同時に失うとクォーラム(定足数)が失われ、クラスター全体が麻痺してしまいます。

なぜデフォルトのZincatiだけでは不十分なのか?

FCOSのエコシステムにおいて、Zincatiは新しいリリースのチェックとrpm-ostreeの調整を担当するエージェントです。問題は、Zincatiが非常に独立して動作することです。隣接するノードが生きているか死んでいるかなどお構いなしです。

「アトミックアップデート」の仕組み上、新しいデプロイを有効にするにはサーバーを再起動する必要があります。デフォルト設定のままだと、主に3つの大きなリスクに直面します:

  • クラスター全体が同時に再起動し、サービスの中断(ダウンタイム)が発生する。
  • 予備ノードの優先順位が設定できない。
  • 分散アプリケーション(Kubernetesやデータベースクラスターなど)の状態を破損させやすい。

解決策:FleetLockによる再起動の調整

状況をコントロールするためには、再起動前に「許可を求める」仕組みが必要です。FleetLockは門番のような役割を果たします。再起動する前に、Zincatiは「ロック(鍵)」を取得するためのリクエストを送信しなければなりません。FleetLockサーバーが承認して初めて、そのノードは先に進むことができます。そうでなければ、順番が来るまで待機する必要があります。

ステップ1:FleetLockサーバーの構築

ロックの状態を管理するための小さなサービスが必要です。最も簡単な方法は、fleetlock-serverをコンテナとして実行することです。専用の管理サーバーに配置するか、高可用性構成であればクラスター内で直接実行することも可能です。

# Podmanを使用してFleetLockサーバーを実行
podman run -d --name fleetlock-server \
  -p 8080:8080 \
  -v ./fleetlock.toml:/config/fleetlock.toml:Z \
  quay.io/coreos/fleetlock-server:latest

fleetlock.tomlファイルで、同時に再起動を許可するノード数を制限します。通常、安全を確保するために1台(slots = 1)のみを許可します:

[groups.production]
slots = 1

ステップ2:FCOSノードでのZincati設定

各ノードのZincatiが勝手に再起動しないように設定する必要があります。代わりに、FleetLockサーバーにお伺いを立てるようにします。この設定は、ノードを初期化する前にButaneファイルを通じて行うのが一般的です。

以下は、FleetLockを参照するために私がよく使用する設定例です:

variant: fcos
version: 1.4.0
storage:
  files:
    - path: /etc/zincati/config.d/50-fleetlock.toml
      contents:
        inline: |
          [updates]
          strategy = "fleetlock"
          [updates.fleetlock]
          base_url = "http://192.168.1.100:8080/"
          group = "production"

重要な注意点:

  • strategy = "fleetlock": Zincatiに自由な再起動ではなくFleetLockプロトコルを使用するよう指定します。
  • base_url: 先ほど構築したFleetLockサーバーのIPアドレス。
  • group: ロックを個別に管理するためのサーバーグループ名(例:staging, production)。

ステップ3:動作確認

設定を適用した後、以下のコマンドでエージェントの状態を確認できます:

systemctl status zincati

アップデートがある場合、Zincatiのログに「Waiting for lock(ロック待ち)」というステータスが表示されます。最初にロックを取得したノードが再起動します。そのノードがオンラインに戻るとロックが解放され、次のノードがプロセスを開始します。これにより、3台のクラスターであれば常に少なくとも2台のノードが稼働している状態を維持できます。

現場からの実践的なアドバイス

実際の運用を通じて、システムをより安定させるための3つの注意点を見つけました:

  1. メンテナンスウィンドウの設定: FleetLockを導入していても、updates.periodic.window設定を使用して、オフピーク時(例:午前2時〜4時)にアップデートを制限することをお勧めします。
  2. Prometheusによる監視: zincati_pushed_updates_totalメトリクスを監視して、どのノードが詰まっているか、またはアップデートを長時間待ちすぎているかを把握しましょう。
  3. FleetLockの可用性: もしFleetLockサーバーがダウンした場合、Zincatiは安全策として「何もしない」ことを選択します。これにより一斉再起動は防げますが、サーバーのセキュリティパッチの適用が遅れる原因になります。

ZincatiとFleetLockを組み合わせることで、Fedora CoreOSを規律あるインフラへと変えることができます。新しいパッチが出るたびにハラハラする代わりに、サービスダウンで真夜中に叩き起こされる心配をすることなく、システムに自動修復を任せることができるようになります。

Share: