2015年09月11日
Facebook ではデータセンターにおいて Kea DHCP サーバーをどのように活用しているか?
Kea を使うのはまだずっと先の話だろ?って考えていたんですが、「How Facebook is using Kea in the datacenter」によれば何と Facebook では既にバックエンド・テクノロジとして活用されているみたいです。 ISC(Internet Systems Consortium)社の Vicky Risk さんが書いたこの大変興味深い記事を勝手に日本語訳しつつ、僕の感じたことを付け足してみます。
何故フェイスブックは新しい DHCP ソリューションを必要としたか?
”私達は商用データセンター内のプロビジョニング・サーバーの一部として DHCP を利用しています。 具体的にはベアメタル・プロビジョニングとアウト・オブ・バンド管理インターフェースへの IP アドレス配布の両方に使用しています。 旧来のシステムは ISC dhcpd と、在庫管理システムが生成した静的なファイル(dhcpd.conf)をベースしていました。”
プロビジョニングって何でしょうか? この用語に対して僕が適切だと感じる日本語訳を見る機会は少ないです。 多分、IT においてプロビジョニングという言葉でカバーされる範疇が広すぎて、どれもある一部分だけを表したものになっているからだと思います。 僕にとってのプロビジョニングは「あるデバイスやサービスを有効化(アクティベーション)するための一連の作業及びその自動化」です。
アンジェロさんのいうベアメタル・プロビジョニングってのは金属(と石)の塊である無機質なサーバー PC を Facebook を支えるソフトウェア、Facebook コードが動く有機的な環境を作るまでに必要な一連の作業(OS、ミドルウェア、プログラム実行環境のインストールなど)を指しています。
アウト・オブ・バンドは Facebook ユーザーが写真や動画をアップロードする(イン・バンド)側とは別の、インフラ管理用ネットワークを意味していて、例えばこのネットワークにサーバー PC のシャーシに組み込まれ本体(ホスト)とは独立して動作するコントローラー・ボードのケーブルをつなげてインフラを管理するのです(これで、もしサーバーが異常停止したとしても僕は、夏でも風邪を引きそうなくらい寒いデータセンターにあるラックの前に行かず、デスクでビールを飲みながら電源をオン・オフしたり、異常停止しているホスト側のログを見ることができます!)。
”私達は生成した設定ファイルを複雑化した svn/rsync ベースの断続的なパイプライン を使い、最後に ISC dhcpd の再起動を行うことでサーバー・インスタンスへ反映していました。 この方式は私達が望んでいたよりも長い(処理)時間を要しました。 私達が取り扱っているような規模では、常に多くのパーツ(Network Interface Card やサーバー自体)を追加・交換するといった作業が発生します。 これまでの DHCP サーバー(ISC dhcpd)はそれ自身のサービス・トラフィックよりも設定の変更を検知するためのアプリケーション再起動に多くの時間を費やしていました。 それに加えて設定ファイルの再生成パイプラインも遅いという問題がありました。あるときには変更が(末端の DHCP サーバーまで)伝搬するまでに最大で3時間を要するほどで、データセンターの復旧を遅くする原因となっていました。 要するに、私達はデータセンターでメンテナンスや拡張を行った後でハードウェアを立ち上げるための、より早い方法を求めていました。”
Facebook ではサーバー PC を管理するシステム(在庫管理システム)があって、ここへ新しい PC の MAC アドレスやロール(役割)に基づいたプロファイルを登録すると動的に設定ファイルが生成され、幾つかの中間処理(パイプライン)を経たのちデータセンターの ISC dhcpd がそれを再ロードしていたみたいです。
ここでちょっとだけ、理解を深めるためにオープンソースのマシン・プロビジョニング・ツール Cobbler(https://cobbler.github.io/)を使ってアンジェロさんの言っていることを再現してみましょう。
Facebook ユーザーがペット、風景、ラーメンの写真を保存するイメージ保存用のマシンが入荷したとします。 僕はその MAC アドレス(ee:ee:ee:00:00:01) を cobbler に登録します。 このとき、OS の種類やインストール・スクリプト(これは RedHat 系 OS ではキックスタートといいます)が関連付けられたプロファイル名も指定します。
cobbler $ sudo cobbler system add --name=img-server1 --profile=centos-6.7-x86_64 --mac=ee:ee:ee:00:00:01
続けて sync を実行すると cobbler はプロビジョニングに必要な設定ファイルを出力し、各プロセスを再起動します。
cobbler $ sudo cobbler sync
ISC dhcpd もそのうちの1つで、dhcpd.conf にクライアントの host エントリを含む dhcpd.conf が生成されます。
# group for Cobbler DHCP tag: default
group {
host generic2 {
hardware ethernet ee:ee:ee:00:00:01;
filename "/pxelinux.0";
next-server 192.0.0.1;
}
}
このパイプラインは Facebook よりもずっと単純で数秒のうちに ISC dhcpd の再起動までが完了します。
プロビジョニングの準備ができた僕は cobbler の電源管理オプションを使い、アウト・オブ・バンド側からマジック・パケットを送って、サーバー PC に再起動(それか、パワーオン)を促します。
$ cobbler system reboot --name=img-server1
再起動したサーバー PC はローカル・ストレージ上に起動可能なイメージが見つからず、ネットワーク・ブート・プロセスに入ります。 ネットワーク・インターフェース・カードには最低限のインテリジェンスを持った PXE Client が書き込まれていて DHCP を使って IP アドレスの取得を試みますが、この時 DHCP サーバーがクライアントに通知すべきネットワーク・ブートストラップ・プログラム(NBP)のファイル(pxelinux.0)やダウンロード先 TFTP サーバー(next-server)を知っていれば DHCP/BOOTP レスポンスのフィールド値(又は DHCP オプション)でクライアントへ通知してくれます。
NBP を入手したクライアントはこれを起動して、引き続き、TFTPサーバー pxelinux.cfg ディレクトリの下にあって自身の MAC アドレスをファイル名に含むブート構成ファイルを入手します(TFTP は認証の必要が無い FTP です)。
$ cat /tftpboot/pxelinux.cfg/01-ee-ee-ee-00-00-01
default linux
prompt 0
timeout 1
label linux
kernel /images/centos-6.7-x86_64/vmlinuz
ipappend 2
append initrd=/images/centos-6.7-x86_64/initrd.img ksdevice=bootif lang= kssendmac text ks=http://192.0.0.1/cblr/svc/op/ks/system/img-server1
このファイルにはカーネルのイメージとキックスタートの入手先が定義されていて、これ以降は Linux OS に制御が移り全ての作業が自動で進みます(Cobbler の詳しい説明は「Cobbler によるシステム・インストールの自動化と管理」をどうぞ)。
一見すると単純に見えるこれらのプロセスも Facebook のような巨大な集合体ではパイプラインが複雑化し在庫管理システムへの登録から、マシンのプロビジョニングが開始するまで数時間を要したってアンジェロさんは言っているわけです。
”Facebook は全てのデータセンターにおいて非常に高い可用性に関する基準を課しています。 冗長構成のために、各クラスタ・サーバーごとに私達は2つの物理的な DHCP サーバー(アクティブ及びスタンバイ構成)を用意していました。 問題は、もし H.A(High Availability)を構成する2つのサーバーがクラッシュして失われた場合、クラスター・サーバーが DHCP サービスを完全に失うことでした。 私達は、ネットワーク上にいる全ての DHCP サーバーが DHCP クライアントからのリクエストに場所を問わず応じることが可能な、もっと柔軟なアプローチを求めていました。”
”数年後、私達は全てのハードウェア・ロードバランサを Linux IPVS 及び Proxygen(オープンソースのロードバランサ)に切り替えました。 私達は同様に DHCP サーバーに対しても改修を実施することに決めました。私達は DHCP サーバーのバーチャル・クラスタを作り、各サーバー・インスタンスをネットワーク上に配置しました。 私達はエニーキャスト及び BGP を DHCP サーバーのクラスタを表すアドレスとして利用しました。 これは、私達にシンプルなクラスタ/データ・センター間のマシン立ち上げまでのプロセス、それに、アクティブ/スタンバイ構成で問題となっていた同時サーバー障害という問題に対するより良い解決方法を与えました。”
どうもこのあたりで ISC dhcpd から Kea へ切り替わったみたいです。 エニーキャスト・アドレスを使うと複数のホスト(サーバー)に同じアドレスを設定することができます。 「それってマルチキャストじゃねーの?」って思うかもしれません。 が、エニーキャストの場合はグループに含まれる最も近い何れか1つのインターフェースにパケットが届くと他のインターフェースには配送されません(BGP ルーティングも必要)。
「めちゃくちゃ便利じゃねーか!」って僕は驚きました。 ただ、ちょっとした条件があります。 エニーキャストは IPv6 でサポートされたアドレスで、利用するには Facebook のようにネットワーク全体を IPv6 化する必要があります。
Facebook は何故 Kea dhcpd を選んだのか?
”私達は Kea が現代的なソフトウェアであり、拡張性に優れている点を好んでいます。Kea は受信したパケットの解析ロジックを追加し、ネットワーク・インターフェースから送信する前段階でレスポンス・パケットを変更することができるフック・ポイントを持っています。 私達は我々の要求を満たす為に Kea をカスタマイズする際、このフック機能を色々な場所で有効活用しています。 Kea の大きなアドバンテージの1つに ISC dhcpd に比べて動的に設定を再構成できるという点がありますが、私達はこれついてはさほど興味を引かれませんでした。”
ここまでを読んでいて、僕には「class や group シンタックスがまだサポートされていない Kea 0.x 系で Facebook はどうやって適切な DHCP/BOOTP フィールドの値やオプションを設定し、クライアントへアドレスを配布したんだ?」って疑問があったんですが、どうもその答えは Hook だったみたいです。
Hook は今僕も知った機能です。 Kea では pkt4_receive、pkt4_send など予め決められた、コールアウトと呼ばれるユーザー関数を C++ で実装することができます。 このユーザー独自のロジックは設定ファイルを使ってサーバー・インスタンスに注入することができます(Hook に関する詳しい説明は「Hooks Developer's Guide」を見て下さい)。
"Dhcp4": {
:
"hooks-libraries": [ "/usr/local/lib/example.so" ]
:
}
Kea dhcpd サーバーは、一連の DHCP シーケンスにおいて、決められたフック・ポイントに達すると該当するコールアウト(ユーザー)関数を実行してくれます。 僕らはコールアウト関数の中で共有された DHCP パケットの中身を見たり、外部にある在庫管理サーバーを参照して適切な値を新たに追加したり、書き換えたりすることができます。
”私達は可能な限り設定データを中央管理し、そしてステートレスな DHCP サービスを動かしたいのです。 私達は Kea をタッパーウェア(我々の持つ Linux コンテナ技術で、これは Google の Borg に相当するものです)にデプロイすることを計画しました。 私達は巨大な設定ファイルで構成されるアプリケーションにはしたくなかったし、ネットワーク上に点在する複数の場所でこのデータを維持管理したくはありませんでした。 私達が開発したものはシンプルで高速なデプロイ(ハードウェアやアプリケーションの配備)を実現します。 私達は Kea をインストールし、非常に基本的な設定で運用していて、残りのデータは動的に在庫管理システムから取得しています。 私達は host, subnet など DHCP クライアントに関わる設定は在庫管理システム上で管理しています。これによって DHCP サーバー側の開発、DHCP 運用設定の簡素化を実現しています。”
Facebook は DHCP サーバーに MVC でいう単純なコントローラーを求め、Kea を使ってモデル(在庫管理システム)との分離を実現したみたいです。 これはかなり珍しい実装だと思います。 現在の多くの DHCP サーバー製品はそれ自身に API が用意されており、外部システムがこれをコールします。 Facebook のアプローチは Web アプリケーションのようでモデルが中心になり、コントローラーがそれを呼び出しています(アンジェロさんは DHCP サーバーが状態や複雑な設定を持たないことをステートレスと呼んでいます)。
ステートレスなシステムを設計・実装するのはどれほど困難なことでしたか?
”さほど困難なことではありませんでした。 Kea 開発者向けドキュメントはとても明確でした。ドキュメントには簡単なライブラリ実装例を使ったフック API の説明が記述されていて理解しやすいものでした。 私達が Kea を使って開発を始めた時、ネットワーク・ブート・オプションはまだサポートされていませんでした、それで C++ で独自の拡張フック・モジュールを書くことにしました。 自分たちの運用ロジックを DHCP サーバーに組み込むことが可能になったことは私達に多くの可能性を与えました。 私達は突然、他のインフラストラクチャと DHCP サーバーを統合できるようになったのです。 統計データの監視システムへの送信、使い勝手の良いダッシュボードの利用、Scribe インフラへのログ送信、アラームの送信などです。 また、不正な DHCP クライアントを取り扱うのに Python を使ってグルー・コードを書く必要がなくなりました。 それと Kea は、昨年夏に IPv6 ネットワークだけでクラスタを構築した際に起こった TFTP によるファームウェアの更新に関する問題をバイパスするコードを書くのにも役立ちました。”
Scribe(https://github.com/facebookarchive/scribe)は Facebook 製のオープンソースのログ・コレクター、アグリーゲーション・サービスみたいです。 日本人だと Fluentd(http://www.fluentd.org/)や Logstash(https://www.elastic.co/products/logstash)が先に頭に浮かびますね。
グルー・コードってのは、そのままでは分離してしまうソフトウェアや処理フロー間を結びつける糊(グルー)のようなコードを意味しています。 グルー・コードはシステムに存在する乖離・矛盾を解決するためだけに書かれる中間コードですから、無いに越したことはありません。
グルー・コードってのは、そのままでは分離してしまうソフトウェアや処理フロー間を結びつける糊(グルー)のようなコードを意味しています。 グルー・コードはシステムに存在する乖離・矛盾を解決するためだけに書かれる中間コードですから、無いに越したことはありません。
このプロジェクトに要した期間は?
”私達は 2014年 2月に Kea に関する作業を開始しました。 1つのサーバーで構成した Kea を使いフック開発の概念検証(POC)に約1ヶ月を要しました。 最初の1週間はヴァニラ・バージョンの Kea で遊びつつ、ドキュメントを読みました。 次の2週間は C++ で私達の在庫管理システムとのアダプタになるコードを書きながらベンチマークをして過ごしました。 最終週は最初のフック・ライブラリのチューニングで過ぎました。 その後、幾つかの商用環境で評価し、我々の商用インフラとの統合、幾つかのバグや問題を解決を行い最終的な商用版を用意するのに約2ヶ月ほどを要しました。 4ヶ月も経った頃(2014 年 5月末)には私達は Kea を使って全ての DHCP クライアントにサービスを提供していました!それからはフック・ライブラリの改善、リファクタリング、新しい要求への対応に取り組んできました。”
僕、POC(Proof Of Concept)について、「具体的にどこまでを指すんだろ?」ってずっと疑問があったんですが、アンジェロさんの言葉を聞く限り、要件の実現に必要なコアだけを小さなプログラムとして実装して周辺技術・設計に矛盾が無いかを評価するってことみたいですね(プロトタイプよりも小さく、コンセプトの中心機能に限定したモジュールの実装と検証)。
あと、貴方はヴァニラ・バージョンって言葉を知っていましたか? 僕は全然知らなくて、ネットで検索してもすぐにはわかりませんでした。 これは例えばアイスクリーム(Kea やその他ソフトウェア)に何もトッピングせず(カスタマイズ・コードや特殊な設定を行わず)、ヴァニラそのものの味(標準的な機能)を楽しむ(評価する)ってときに使う言葉みたいです。
まあ、僕なんか確実に「”ヴァニラ”って顔かよ!きめー。」って影で言われるので絶対に使えない言葉です。
その結果はどうなりましたか?
”現在では、以前のように静的な DHCP 設定ファイルを生成するのではなく、在庫管理システムから動的に設定情報を取得して DHCP ロジックへ反映するのにフックを利用しています。 私達はサーバー・クラスタの起動や再ロードが高速にできています。 旧来のシステムであれば DHCP サーバーへ変更を反映に数時間を要していた!のがです。 この新しいステートレスな設計によって、私達は DHCP サーバーの再ロードを除くことができ、在庫管理システムからの伝搬時間を1,2分に短縮しました。 また、私達は大幅に簡略化したルーティングも行っています。 現在ではネットワーク上の全ての DHCP サーバーはエニーキャスト・アドレスを使ってどのクライアントからの DHCP リクエストに対してもレスポンスすることが可能です。 これは私達のセットアップ作業を簡略化しました。私達はラック上のスイッチが持つ DHCP リレー・エージェント機能を使っています。 これに単一でグローバルなエニーキャスト・アドレスを設定すれば良く、新しいクラスタやデータセンターの立ち上げが容易になりました。 ハードウェア・ロードバランサの必要性を除去したことでクロス・クラスタの冗長性(可用性)を向上することにもなりました。 それにプロビジョニング時の問題解決・分析に役立つ美しいダッシュボードも手に入れました。”
同じような悩みを抱える人たちへ助言、伝えたい事はありますか?
”データセンター向けアプリケーションにおいては、ステートレスな DHCP アプローチを強く推奨します。状態や設定データをアプリケーションから分離しましょう。 そのようなモデルとなるデータはそれ専用の外部システムに委譲すべきです。 これによってデータの管理やサーバー・デプロイメント(配備)を簡素化します。”
”Kea のようなオープンソース・ソリューションを有効活用し、「車輪の再発明」シンドロームと戦って下さい。 要求を満たす手段が本当に何もない場合だけ、スクラッチでコードを書くべきです。 これを実践するときオープンソース・プロダクトを試してみて下さい。”
Angelo Failla さんについて
Angelo Failla さんはアイルランドのダブリンでクラスタ・インフラストラクチャ・チームに所属し、クラスタ技術及びデータセンターの自動化について取り組んでいる Facebook のプロダクション・エンジニアです。
彼はシステム・エンジニアとして 10 年、プログラマとして 15 年の経験があります。 彼は Bash、Python、C++、その他のコーディング技術を使って Facebook でオートメーションや自動復旧・修復といった点から運用の改善に取り組んでいます。 アンジェロさんは PyCon 2014、SREcon 15、DevOps イタリア 2015 で講演しました。 彼の Facebook ページは食べ物の写真で埋め尽くされています。 彼とは Twitter、LinkdIN、そして勿論 Facebook で友達になることができます。
アンジェロさんは SREcon 15 カンファレンスで「DHCP Infrastructure」について語っていて、今でも SREcon 15 Europe 特設ページ(https://www.usenix.org/conference/srecon15europe/program/presentation/failla)でそのプレゼン・ビデオを見ることができます。
なんだか「今すぐ Kea でフック開発してみたい」って気持ちになってきましたね!
じゃあ、また今度。
[24時間365日] サーバ/インフラを支える技術 ‾スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)
posted with amazlet at 15.09.10
安井 真伸 横川 和哉 ひろせ まさあき 伊藤 直也 田中 慎司 勝見 祐己
技術評論社
売り上げランキング: 14,807
技術評論社
売り上げランキング: 14,807