OpenAICloudflare2026/06/01 16:53

How we reduced core unit boot time from hours to minutes

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

コアユニットのブート時間を数時間から数分に短縮した方法

Key Points

  • UEFIの線形探索を排除
  • ブート順序を事前に宣言
  • アップグレード時間を3分に短縮

Summary

ファームウェア更新後にGen12コアサーバ群(約2,000台)がブートで数時間停止する事象を解決しました。原因はUEFIが利用可能なネットワークブートインターフェースを順次線形探索し、応答しないインターフェースで数分ずつタイムアウトしていたためです。iPXEベースの自動化を見直し、ブートインターフェースを事前に宣言することで、全体のブート/アップグレード時間をほぼ4時間から約3分へと短縮しました。

Key Points

  • 原因の特定
    • UEFIがIPv4 HTTPS→IPv4 iPXE→…と順に試行し、各試行で約5分のタイムアウトを消費。複数再起動で累積し数時間に。
  • 解決策
    • PXE前ブート段階で正しいネットワークブート順序を明示し、不要な探索を回避。
    • ベンダーと連携してEFI_IFR_REF3の遅延ロード課題を解消するトークンを有効化させ、GUI操作なしでNetwork Boot項目を発見可能に。
    • 一部UEFIにあったimmutableなForce Priority設定はBIOSアップデートとデバッグで対応。
    • NICベンダーごとの異なる表示文字列にはCfHIIConfig_Appの正規表現マッチ機能(例: .*HTTP.*IPv4.*P1)で対応し、将来的な文字列標準化を要求。
    • iPXE上での比較コストを下げるため、uefi-same-hexフラグを導入し、show→setの二段階をsetのみで済ませるように最適化。
  • 運用上の工夫
    • 設定永続性と古いUEFI対応のために、設定変更後に状態検証を行い、必要なら再適用して再起動するワークフローを追加。
  • 成果
    • ファームウェアアップグレード自動化: 約4時間 → 約3分
    • 単一起動(以降): 約20分 → 1分未満

Practical recommendations

  • ネットワークブート候補を線形探索させないため、可能なら起動前に明示的なブートインターフェース順序を設定する。
  • EFIのUI非表示/遅延ロードはベンダーと協働でトークン/BIOS修正を行う。
  • NIC名のばらつきには正規表現マッチか、UEFI側での表示フォーマット標準化を要求する。
  • 設定適用は冪等性を保ち、変更検知→再適用→検証のループを入れて自動化する。
  • iPXEやブートスクリプト側でのヘックス比較フラグ類を活用してshowコマンドを減らす。

エンジニアはまずブートシーケンスのシリアルコンソール観察と、どのインターフェースでタイムアウトが発生しているかのログ取得から始めてください。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

コアユニットの起動時間を数時間から数分に短縮した方法

コアユニットの起動時間を数時間から数分に短縮した方法

Cloudflareのコアは、コントロールプレーン、課金、分析を実行する集中型データセンター群であり、ユーザートラフィックを処理するグローバルに分散したエッジとは別物です。コアサーバはベアメタルで稼働しており、再起動時の問題は迅速に連鎖的な影響を及ぼします。起動シーケンスは UEFI によってオーケストレーションされ、ハードウェアを初期化してOSに制御を渡します。この引き渡しにおける小さな挙動の違いが大きな影響を生じさせることがあります。

ルーチンなファームウェア更新の後、一部のコアサーバは以前のように数分で戻るのではなく、復旧に4時間かかることがありました。本来1日で終わるはずのフリート全体のロールアウトが複数日にわたる作業に伸び、新しいノードは初回ブートで完全なタイムアウト地獄にさらされ、メンテナンスウィンドウは膨張し、エンジニアは無人で済むはずのアップグレードに付き添わなければなりませんでした。この問題はGen12フリートほぼ2,000台に影響しました。

これは、ファームウェアの挙動と利用可能なすべてのネットワークブートインターフェースを過剰に線形検索してしまう自動化の組み合わせが原因で、合計のブート/アップグレード時間を数時間から数分に戻した経緯の記録です。途中でUEFI内部やベンダー固有の動作、最終的に問題を解決した自動化戦略についての学びも共有します。

ネットワークブートインターフェース

ネットワークブートインターフェースは、サーバがローカルストレージではなくネットワーク経由でOSを起動することを可能にします。これは、集中管理された自動化された大規模な起動制御に不可欠で、異なる環境・用途に設置されたサーバに対して柔軟に対応できます。

主なインターフェースは以下です。

  • PXE (Preboot Execution Environment)
  • UEFI HTTPS boot

Cloudflareでは、iPXE(HTTP/HTTPSなどのモダンプロトコルをサポートするオープンソースのネットワークブートファームウェア)を使用しています。iPXEにより、OSイメージをウェブサーバやクラウド、エンタープライズストレージから直接ブートでき、高速かつ信頼性の高い起動が可能になります。iPXEは起動プロセスをプログラム可能なワークフローに変え、ハードウェア構成に応じたプロビジョニングやセキュアなディスクレスワークステーションの管理といった複雑な展開を自動化できます。

一部ハードウェアはHTTPSベースのUEFIネットワークブートをネイティブにサポートしており、マザーボードのファームウェアが安全にOSファイルをダウンロードできます。

線形探索(The linear search)

問題の発端は、あるファームウェア更新でした。更新後、内部チャネルに「サーバが戻らない」という報告が入り、監視ダッシュボードは機器が予想より遥かに長くpre-OS状態で止まっていることを示していました。

まずはファームウェアのリグレッションを疑い、影響を受けたマシンのシリアルコンソールを開いてブートをリアルタイムで観察しました。POSTは正常、ハードウェア初期化も問題ありませんでした。しかし、素早くネットワークブート段階に進んでOSイメージを取得する代わりに、サーバはただ待ち続けていました。

コンソール出力はこう語っていました: システムはIPv4 HTTPSネットワークブートを試み、数分でタイムアウトし、次にIPv4 iPXEを試みてまたタイムアウトし、それを繰り返した後でようやく成功するIPv6 HTTPSブートインターフェースに到達していました。失敗するネットワークブート試行ごとに約5分のタイムアウト待ちが発生し、正しいインターフェースに到達するまでに4回分が積み重なると、単一のブートで約20分が無駄になっていました。

ルーチンな再起動でも痛手ですが、各コンポーネントごとに再起動が必要なファームウェアアップグレード自動化では、これらの20分ペナルティが重なって1台あたりほぼ4時間のアイドル待ちになっていました。

インターフェースを明示する — 探索をやめる

ブートシーケンスを追跡しタイムアウトパターンを特定すると、原因は明白でした: サーバが利用可能なすべてのネットワークブートインターフェースを順に盲目的に探しており、応答しないインターフェースごとに待ち時間を消費していたのです。解決策は推測を排し、正しいブートインターフェースを事前に宣言して、応答しないインターフェースに時間を浪費させないことでした。

ただし、実際にこれを運用に落とし込むにはいくつかの障害がありました:

  • ブート自動化ワークフローの順序
  • 変更がブロックされている設定
  • NICベンダー間での文字列フォーマットの違い

ブート自動化ワークフロー

我々のブート自動化は大きく3つの段階に分かれます: ファームウェア初期化、プリブート、カーネル起動。電源投入後、UEFIファームウェアがハードウェアと周辺機器の初期化を行い、PXEプリブート環境に移ります。プリブートはNICをセットアップし、bootloaderと呼ばれる小さなプログラムを実行してカーネルを起動します。このPXE段階で適切なネットワークインターフェースがプローブされます。

初回ブート時にはファームウェアアップグレードが自動化フローに含まれており、各アップグレードが再起動を必要とするため、合計でほぼ4時間になっていました。プリブート(PXE)段階の早い段階で各ハードウェア/ユースケースに対してネットワークブートの優先順序を明示するよう自動化を再構成することで、それぞれのファームウェアアップグレードで20分を費やして探索する必要がなくなり、合計で約1時間分の短縮が得られました。

ネットワークブート順序を設定しようとした際に生じた2つの制約:

  • Legacy Support: 古いUEFIバージョンではブート順序設定がサポートされていない
  • Persistence: UEFIファームウェアのアップグレード後に設定がリセットされることがある

これらのエッジケースに対処するため、状態検証のステップを実装しました。ファームウェア自動化は変更後に設定を検証し、設定が変更されていることを検出した場合は再適用して再起動をトリガします。初回ブートはわずかに長くなる可能性がありますが、この変更により以降の起動時間は大幅に短縮され、約20分が1分未満に改善されます。

ベンダーにより無効化されていたブート順設定

ネットワークブート設定の内部データ構造はEFI_IFR_REF3で、遅延ロード(lazy loaded)されていました。つまり、そのデータはGUIのコールバックで明示的にアクセスされるまでインスタンス化されません。

typedef struct _EFI_IFR_REF3 {
  EFI_IFR_OP_HEADER Header;
  EFI_IFR_QUESTION_HEADER Question;
  EFI_QUESTION_ID QuestionId;
  EFI_GUID FormSetId;
} EFI_IFR_REF3;

この手法はBIOSブート時間を短くするための業界的な一般手法ですが、結果として「Network Boot Interface」がプログラムによるスキャンから見えなくなっていました。構造体がまだ“ロードされていない”ため、我々の自動化は優先順位を検出できませんでした。

これに対して我々はベンダーと連携し、固定の"Boot Order Module"内の特定のトークンを有効化してもらいました。これにより、GUI操作を不要にしてブートシーケンス中にNetwork Boot Interfaceが発見されるようになりました。

さらに、我々の機器向けUEFIには Force Priority Httpv4 Httpv6 Pxev4 Pxev6 という不変設定があり、ブート順の変更を阻害していました。これを解決するためにベンダーから新しいBIOSバージョンを提供してもらい、設定時にデバッグセッションを実施しました。

NICベンダーごとの文字列差異

NICベンダーによってUEFIに表示される文字列が異なり、iPXE経由でブート順を設定する際に不一致が発生しました。例:

  • UEFI: HTTPS IPv4 Ethernet Network Adapter XXX-XXX-Y for OCP 3.0 P1
  • UEFI: HTTPS IPv4 Network Adapter - 50:00:E6:8F:4F:32 P1

回避策として、CfHIIConfig_Appツールに部分一致で設定できる機能を実装しました。例えば:

.*HTTP.*IPv4.*P1

このパターンで許容される設定文字列にマッチさせ、正しいブート順を選択できるようにしました。現在はUEFIベンダーと協力して、ネットワークインターフェース文字列をプロトコル、転送タイプ、ポート番号、物理スロットインデックスといった関連情報のみに標準化し、MACアドレスなどのプロダクト詳細は除外する方向で調整中です。必要であれば製品詳細はNICの埋め込みVPD(vital product detail)から読み取れるようにします。これにより設定のドリフトやワイルドカードの使用を排除できます。

iPXE経由での設定確認不可への対処

iPXEはこの変数をHEXとして読み取るため、文字列出力をそのまま16進で読んでいました。ネットワークブート設定が変更されたかを確認し、ブート時間を短縮するために(設定前に変数を出力して比較する必要がないように)論理フラグ uefi-same-hex を実装しました。これにより、まず show で比較してから set するのではなく、単一の set コマンドを実行するかどうかを決めることができるようになりました。

以下は実際に使っているコマンド例です:

# construct path to read the update variable
set buffer-var-guid 91468514-75bc-4bb5-8f33-91efff9e9b1f
set var-upd-path efivar/CfHIIVarUpd-${buffer-var-guid}

#Run the config change command
imgexec <signed CF UEFI configuration App> set ${uefi-setting}=${uefi-value}

#Compare the update variable with the expected value if it has changed.
#If it has changed, set the local variable to reboot the system
iseq ${uefi-same-hex} ${${var-upd-path}} || set has-changed ${uefi-diff-hex}

結果: より動的なシステム

ネットワークブートシーケンスから推測を排除することで、我々は4時間に及ぶ苦闘を再び3分のプロセスに戻しました。これにより、変更は動的になり、手動でBIOSを操作する必要はなくなりました。単一のBIOSファームウェアイメージがすべてのSKUに対応し、設定更新は既存のリリースパイプラインで大規模にデプロイされ、ワークフロー全体がiPXE上で動作します。

MetricBefore ordering changeAfter ordering change
Firmware Upgrade AutomationNearly 4 hours3 minutes
Subsequent Single BootAbout 20 minutesLess than a minute

これらはUEFIの深掘り、OEMベンダーとの緊密な連携(プログラム的なブート順制御を解放するため)、およびiPXEのようなオープンソースツールを活用してスケーラブルな自動化を構築した結果です。CloudflareのOpenBMCチームは日々、コアフリートのブートプロセスについて学び、実験し、最適化を続けています。

ベアメタルインフラを管理していてサーバの起動が遅く悩んでいる方には、本ポストがネットワークブートシーケンスにおける不必要な遅延を特定・排除するための実践的なフレームワークを提供できれば幸いです。

iPXEやネットワークブート自動化に興味がある方は、check it out here !

タグ: server-island-start Infrastructure Engineering Networking Core