はじめに: ファームウェアアップデートが招いた4時間の悪夢

Cloudflareのコアサーバーは、世界中に分散するエッジ(Edge)とは異なり、中央データセンターでコントロールプレーン(Control Plane)、課金(Billing)、分析(Analytics)といった中核的な役割を担っています。これらはほとんどがベアメタル(Bare Metal)サーバーであり、起動プロセスはUEFI(Unified Extensible Firmware Interface)がハードウェアを初期化し、OSに制御を移す標準的な方法に従います。

問題は、日常的なファームウェアアップデートの後に発生しました。アップデートを完了した一部のコアサーバーで、ブート時間が従来の「数分」から「4時間」にまで延びてしまったのです。当然、予定していた1日で終わるはずのアップデート作業は数日間に引き伸ばされ、エンジニアは自動化されるべきアップグレードプロセスを延々と監視しなければなりませんでした。単純なファームウェアの回帰(Regression)バグを疑いましたが、実際の原因はもっと根本的なものでした。

この記事では、ブート時間を遅延させた「UEFIネットワークブートインターフェースの順次探索」問題を追跡し、それを解決するために適用した戦略を段階的に共有します。特に、単にiPXEの設定を数行変更したレベルではなく、ベンダーとの協業から内部ツールの開発までを含む総合的なアプローチであった点を強調したいと思います。

参考資料: この記事の内容は、Cloudflare公式ブログのケーススタディに基づいて作成しました。


本論1: 問題の核心、ブートインターフェースの「順次探索」

PXEとUEFI HTTPSブート、なぜ複数必要か

サーバーがネットワーク経由でOSを起動する方法は主に2つあります。1つ目は従来のPXE(Preboot Execution Environment)方式、2つ目はセキュリティが強化されたUEFI HTTPSブート方式です。CloudflareはオープンソースのネットワークブートファームウェアであるiPXEを使用してこの2つの方式をサポートし、ハードウェア構成に応じて適切なインターフェースを選択します。

問題はこの「選択」プロセスにありました。起動時にサーバーが利用可能なすべてのネットワークブートインターフェースを1つずつ試行し、各試行が失敗するまで約5分間待機した後、次のインターフェースに移行するという方式だったのです。

# ブート試行順序 (問題発生時)
[1] IPv4 HTTPSブート試行 → 5分待機後失敗
[2] IPv4 iPXEブート試行 → 5分待機後失敗
[3] IPv6 HTTPSブート試行 → 5分待機後失敗
[4] IPv6 iPXEブート試行 → 5分待機後失敗
[5] 正しいインターフェースに到達 (例: 特定NICのHTTPSブート)

# 総所要時間: 約20分 (単純ブート時)

単純なブート1回に20分かかるのは致命的です。さらに大きな問題は、ファームウェアアップグレードの自動化です。ブート順序を改善する前は、ファームウェアアップグレードに複数回の再起動が必要であり、そのたびに上記のような20分の時間がかかっていました。その結果、総アップグレード時間は約4時間にも達していたのです。


本論2: 解決策、「宣言的ブート順序」と自動化ツール

1. ブート自動化ワークフローの再構成

Cloudflareのブート自動化は、ファームウェア初期化 → 事前ブート(PXE) → カーネル起動の3段階に分かれています。問題が発生したのは、事前ブート段階でネットワークインターフェースを探索する部分でした。これを解決するために、ハードウェアとユースケースに合わせた正確なブートインターフェース順序を事前に宣言するようにワークフローを変更しました。

これには2つの制約を克服する必要がありました。

  • レガシーサポート問題: 古いUEFIバージョンはブート順序設定をサポートしていません。
  • 設定揮発性問題: UEFIファームウェアアップグレード時に設定値がリセットされる可能性があります。

これを解決するために**状態検証ステップ(State Validation)**を導入しました。ファームウェア自動化は設定変更後にこれを検証し、設定がリセットされた場合は再適用して再起動をトリガーします。最初のブートは少し遅くなる可能性がありますが、以降のすべてのブートは20分から1分未満に短縮されます。

2. ベンダーロック解除: 隠された設定の発見

問題をさらに深く掘り下げると、ベンダーが提供するUEFI設定のうち**'Force Priority Httpv4 Httpv6 Pxev4 Pxev6'という不変(Immutable)な値がブート順序の変更を妨げていました。この設定はEFI_IFR_REF3データ構造で保存されますが、この構造は遅延ローディング(Lazy Loading)**方式のため、プログラム的にアクセスするまでBIOS設定画面に表示されませんでした。

// UEFIネットワークブート設定の内部データ構造
// (この構造は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;

Cloudflareはベンダーと協力して**'Boot Order Module'**内の特定トークンを有効化することで、GUIなしでネットワークブートインターフェースを自動検出し、順序を変更できるようにしました。

3. NICベンダー別の文字列差異の克服

ブート順序をiPXEで設定する際に別の問題が発生しました。ネットワークインターフェースカード(NIC)ベンダーごとに、ブートインターフェースを識別する文字列が異なっていたためです。

# NICベンダー別のブートインターフェース文字列例
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

この問題を解決するために、Cloudflareは内部ツールであるCfHIIConfig_Appに正規表現を使用した設定機能を追加しました。

# 正規表現を用いた部分文字列マッチング
.*HTTP.*IPv4.*P1

これにより、完全な文字列を知らなくても、プロトコル、転送方式、ポート番号、物理スロットインデックスのみで正しいブートインターフェースを選択できるようになりました。現在はベンダーと協力して、MACアドレスのような製品詳細情報を削除し、標準化された文字列のみを使用するよう努めています。

4. iPXE設定検証問題: HEX比較

iPXEはUEFI変数をHEX値として読み取るため、設定が正しく適用されたかどうかを確認することが困難でした。この問題を解決するために、uefi-same-hexというブーリアンフラグを実装しました。

# iPXEスクリプト: 設定変更および検証の自動化
# 設定変更後、変更の有無を確認して再起動の要否を決定

# 設定変更コマンド実行
imgexecset ${uefi-setting}=${uefi-value}

# 変更された変数と期待値を比較して変更を確認
# 変更されていればローカル変数に再起動シグナルを設定
iseq ${uefi-same-hex} ${${var-upd-path}} || set has-changed ${uefi-diff-hex}

このフラグにより、毎回showコマンドで変数を出力して比較する代わりに、単一のsetコマンドで設定と検証を同時に実行できるようになり、ブート時間をさらに短縮しました。


本論3: 結果と注意点

改善効果: 4時間 → 3分

指標変更前変更後
ファームウェアアップグレード自動化約4時間3分
後続の単一ブート約20分1分未満

この結果は、単にiPXEの設定を数行変更しただけでなく、UEFI内部構造への深い理解、ベンダーとの協業、自動化ツールの開発までを含む総合的な努力の成果です。

注意点と限界

  • ベンダー依存性: この問題を解決する過程で、特定ハードウェアベンダーのUEFIファームウェア修正が必要でした。すべての環境で同じ方法で解決できるとは限りません。
  • 初期設定時間: 状態検証ステップにより、最初のブートは以前より少し長くかかる可能性があります。
  • 正規表現マッチングのリスク: .*HTTP.*IPv4.*P1のようなワイルドカードマッチングは、設定が誤ったインターフェースとマッチングする可能性があります。継続的な標準化努力が必要です。

まとめと次のステップ

Cloudflareの事例は、ベアメタルサーバーを運用する際に「ブート時間」が単なる待ち時間ではなく、運用効率に直結する重要な最適化対象であることを示しています。特に、ファームウェアアップデートのように複数回の再起動が必要な作業では、ブート時間が全体の作業時間を左右する可能性があります。

この記事で扱った核心は「むやみに待つのではなく、ブートインターフェースを宣言的に制御しよう」ということです。この概念は、Cloudflareのインフラだけでなく、ベアメタルサーバーを扱うあらゆる環境で有用に適用できます。

次のステップとして推奨する学習方針:

  1. iPXEスクリプティングの応用: 公式ドキュメントを通じて、さまざまなブートシナリオとスクリプト作成方法を学んでみてください。
  2. UEFI内部構造の学習: EFI_IFR_REF3のようなデータ構造を理解すると、ベンダーロック問題をより簡単に解決できます。
  3. ブート自動化ツールの構築: この記事で紹介されたCfHIIConfig_Appのように、独自の設定ツールを作成してみるのも良い練習になります。

合わせて読みたい記事:

Cloudflare data center rack with bare metal core servers requiring firmware updates Programming Illustration

本コンテンツは、信頼性の高い情報源をもとにAIツールを活用して作成され、編集者によるレビューを経て公開されています。専門家によるアドバイスの代替となるものではありません。