ブログ・ア・ラ・クレーム

技術的なメモとかライフログとか。

Maygh: Building a CDN from client web browsers (EuroSys'13) を読んだ

はじめに

本稿は システム系論文紹介 Advent Calendar 2014 14 日目の記事です。

Maygh: Building a CDN from client web browsers (EuroSys'13) という論文を読みました。ざっくりと内容紹介や所感を記述します。

概要

Maygh は Web ページで要求される静的リソースを、既にそのリソースを持っている他のクライアントから P2P 通信で受け取ることによりサーバ側の帯域使用量を低減するシステムです。 Maygh は JavaScript で記述されたクライアントスクリプトという形でユーザに提供され、 WebRTC などを使ってクライアント間通信を実現します。その他専用のブラウザのプラグインなどを導入する必要はありません。 ただしコンテンツ配信者は coordinator と呼ばれるキャッシュ保持情報と保持するクライアントの IP アドレスを教えるためのサーバを提供する必要があります。 各クライアントはリソースを取得する際にまず coordinator に問い合わせ、それのキャッシュを持つ他クライアントがいれば coordinator からもらった情報を元に WebRTC 接続を確立して要求されるリソースのやり取りを行うことになります。

Maygh の評価として、ショッピングサイト Estyアクセスログを用いたシミュレーション結果が提示されています。 このシミュレーション結果によると、 Esty のワークロードにおいて約 75 %ほど帯域使用量を削減することができるとのことです。

従来のコンテンツ配信

大規模な Web サービスを運営する上で、コンテンツ配信に伴うネットワーク負荷を捌く方法は悩ましい問題です。 今日ではネットワーク設備を強化する、配信サーバの台数を増やす、静的コンテンツの配信に Akamai や Limelight などの CDN(Contents Delivery Network) を利用するなどの方法が存在します。 しかしながらこれらの方策は大きなコストが発生しがちです。

近年の別のアプローチとして、サーバ側設備を増強するのではなく、クライアント側で静的コンテンツの配信を共有し合ってもらい、サーバ側帯域使用量を提言する手法が現れてきています。 具体的な実装例として Akamai NetSession Interface などが存在します。 しかしながらこれらの既存手法は専用アプリケーションやブラウザのプラグインの導入を強いるものになっており、エンドユーザにとって導入障壁が高いものとなっています。

Maygh のデザイン

Maygh は幾つかのモダンなブラウザの提供する機能の支援を受けて、エンドユーザに専用プラグインなどの導入を強いることなくユーザ参加型のコンテンツ配信を行うシステムです。 Maygh を利用するにあたって、ユーザのブラウザには都合下記のような要件が発生します。

  • JavaScript が有効になっている

  • Indexed Database API, WebStorage をサポートしている必要がある

    • Maygh はこれら Storage API を用いて各クライアントの LocalStorage にキャッシュを保持する
  • WebRTC をサポートしている

    • Maygh クライアント間の P2P 通信に用いられる
    • WebRTC が使えない場合、 RTMFP を使用することも可能

Maygh は、各クライアントに配布される Maygh クライアントスクリプト と、コンテンツ配信者により提供される coordinator サーバ から構成されます。 Maygh クライアントは小サイズの JavaScript で実装されたスクリプトです。 RTMFP を用いるための小さな Flash オブジェクトも伴います。 coordinator は Maygh クライアントと各クライアントが持つコンテンツの対応関係を管理する client map と、 各コンテンツを持つオンライン状態のクライアントの情報を管理する content location map の二つのデータを持つサーバです。 Maygh の coordinator は性能がスケールできるよう複数台で動作できるよう設計されています。複数の coordinator を動作させる際は、それぞれの coordinator が content location map を持ち、自分にぶら下がっているクライアントの情報を管理するようになります。

Maygh による通信

Maygh によるクライアント間、そしてクライアントと coordinator 間の通信は下図の通りになっています。

f:id:syu_cream:20141214234254p:plain

図には含まれていませんが、クライアントは Web ページ初回アクセス時に coordinator にコネクションを張り、 Maygh の update メッセージで自身の持つコンテンツ情報を送ります。 各コンテンツの取得時に最初に lookup メッセージを送信し、それに対するレスポンス lookup-response をもって要求する他のクライアント(以降、ピア)の ID を取得します。 その後 coordinator に connect メッセージを送信し、コンテンツを所有するピアとの RTMFP/WebRTC セッションを確立します。 この際、多くの場合ピアの間には NAT デバイスが挟まっていることが想定されるので coordinator に STUN をしゃべってもらい、相手方ピアの IP アドレスとポート番号を教えてもらいます。 その後は RTMFP/WebRTC セッションを確立し、コンテンツの取得を行い、最後にコンテンツを取得完了した旨を update メッセージで coordinator に伝えます。

評価

実装

この論文では Maygh の評価を行う上で下記の実装を行ったとのことです。

また、 Maygh の実装は GitHub に公開されている ようです。

coordinator がスケールするかの検証

複数の coordinator プロセスを1台の検証用マシンで動作させた際と、複数のマシンで動作させた際の transaction/sec が検証されています。 検証の結果、複数マシンで動作させることにより coordinator 数に比例して捌けるトランザクション数が上昇しており、十分スケールするとのことです。

Maygh による帯域使用量削減効果の検証

Esty の 7 日間のアクセスログを用いた、 Maygh の効果のシミュレーション結果が提示されています。 この結果によると、 Maygh 導入により約 75% の帯域使用量削減効果が見られたようです。 また既存の専用プラグインを導入してクライアントサイドでコンテンツ交換を行う手法との比較として、「10% のユーザがそのプラグインを導入する」という想定での帯域使用量の削減効果も検証されていますが、こちらは約 7.8% と Maygh と比較して低い効果しか見られないとのことです。

余談: 最近の関連トレンド

この論文を読んでいて思い出したのですが、昨年に米 Yahoo! が PeerCDN という配信システムを持つ会社を買収した話 があったかと思います。 記事によると WebRTC で P2P 通信することでコンテンツ配信をするらしい話が記載されていることもあり、本論文に近い手法であるものかと推測されます。 PeerCDN のその後の話も気になりますね。 また最近ですと、あまり詳細な情報は出ていないようですが、 BitTorrent 社が BitTorrent を用いてコンテンツ共有を行う Web ブラウザ Maelstrom のアルファテストを開始したとのニュース があったかと思います。

P2P でクライアント間でコンテンツ配信負荷を負担し合ってサーバ側帯域使用量を減らす手法の今後の動向が気になるところです。

ISUCON4 オンライン予選に参加した所感など

ISUCON4 のオンライン予選に参加したので簡単に所感をまとめてみます。

チームは @AknEp くん, @suma90h くんと一緒に組みました。 チーム全体でやったことは @AknEpくんのブログ でまとめられているので、本記事では僕のやったことと反省点・感想などにフォーカスします。

自分がやったこと:

反省点:

  • BitBucket の使用に躓く
    • 最初の頃 git push できなくてちょっと時間食った
    • 過去に気付かないうちにBitBucketのアカウント二つ作っていて、別アカウントでpushしようとしていたらしい()
  • ちゃんとボトルネック解析しましょう
    • top などで見る程度はやっていた
    • プロファイリング能力が足りない?
  • 事前準備をもっとすべきだった
  • 最後の方にスコア稼げたのは @AknEp くんの活躍の依るものが多かったので、もう少し頑張って貢献すべきであった

色々と勉強になることが多く、刺激的でした。 同チームの @AknEp くん、 @suma90h くん、参加者の皆さんお疲れさまでした。 俺たちのISUCON4はこれからだ! -完-

Wireshark 1.12.0 でHTTP/2サポートが入ったらしい

前々から Wireshark で HTTP/2 対応されるという話がありましたが、 1.12.0 で正式にサポートされたようです。

2.5. New Protocol Support
...
Speed LAN Instrument Protocol (HiSLIP), HTTP2, IDRP, IEEE 1722a, ILP, iWARP Direct Data Placement and Remote 
...

Wireshark 1.12.0 Release Notes - 2.5. New Protocol Support

というわけで手元の Mac 機で早速試してみました。 まずはここから最新版を取得します。(本記事執筆時は 1.12.1) うまくインストールできたら Edit -> Preferences -> Protocols -> HTTP2 から、 Enable HTTP2 heuristic にチェックを付けましょう。

f:id:syu_cream:20140927034012p:plain

後は適当に平文のHTTP/2リクエスト流してみて、HTTP/2フレームが覗き見れることを確認してみます。 下記のスクリーンショットは nghttp2から http://nghttp2.org/ にリクエスト投げてみた際のフレームの内容を覗き見たもの。 HEADERS フレームのペイロードもちゃんとデコードして内容確認できていることがわかります。

f:id:syu_cream:20140927034417p:plain

ちなみに、どうやら Wireshark 1.12.1 現在では、draft-14 に対応していない模様。。。

RFC 7230 における HTTP/1.1 の同時接続数について

今日よく使われるWebブラウザは、ドメイン毎に複数コネクションを張ってWebページの表示までにかかる時間を短縮しています。 この同時接続数については、 High Performance Browser Networking では 6 個だと書かれています。(この値はブラウザの実装依存なところがあり、IE11では 13 個同時にコネクションを張りうるらしいです。また、この値は Firefox であれば about:config から変更が可能なようです。)

そもそも仕様ではどうなっているのかというと、 RFC 2616 では 8.1.4 Practical Considerations にて下記のような記述があります。

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.

ユーザの同時接続数は2つまでにすべきとの記述があります。 ・・・とは言ってもこの制約は Persistent Connections が多用される前提の話でしょうし、 SHOULD と書かれているし、実際は多くのブラウザ実装はこれを無視してより適した値を用いている、という感じでしょうか。

ところで、2014年6月に RFC 2616 が更新&分解されたのは記憶に新しいかと思います。 その更新後の Message Syntax and Routing に関する仕様を記述している RFC 7230 の Appendix の Changes from RFC 2616 には下記のような記述が含まれます。

The limit of two connections per server has been removed. An idempotent sequence of requests is no longer required to be retried. The requirement to retry requests under certain circumstances when the server prematurely closes the connection has been removed. Also, some extraneous requirements about when servers are allowed to close connections prematurely have been removed. (Section 6.3)

どうやら更新後の HTTP/1.1 の仕様では、同時接続数の制限は除去されているようです。 めでたしめでたし?

F2FS(Flash-Friendly File System) を試してみる。

このエントリは、 カーネル/VM Advent Calendar 2013 の 19日目の記事として書いています。

こんにちは、 @syu_cream です。 本記事では SSD に特化したファイルシステムであるところのF2FS(Flash-Friendly File System) の軽い説明を入れつつ、試しに使ってみて軽くベンチマークを取ってみた結果を掲載します。

大分ざっくりと書いてるので、誤った点など多々あるかと思います。適当にご指摘頂けると幸いです。

F2FS とは

F2FS(Flash-Friendly File System) は Linux カーネル 3.8 でマージされた、Samsung が中心となって開発した、主にSSDに特化したファイルシステムです。 生のフラッシュメモリ 特化のファイルシステムは、既存のものが幾つか存在するのですが、F2FS はそれらとはまた違った構造のストレージを想定して設計されています。

で、ざっくりと結論を出してしまうと、F2FS は SSDにとって苦手なランダムライト性能を、ログ構造ファイルシステム的なデータの書き出し方をすることで向上する ファイルシステムと言えます。 実際にベンチマークしてみたところ、確かに F2FS の導入によりランダムライト性能が向上する傾向が見られました。

SSD に有効なファイルシステムとは

先述の通り、 F2FS は NANDフラッシュベースのストレージ 、例えばSSDに特化したファイルシステムだと主張されています。 生のフラッシュメモリ特化 のファイルシステムはこれまで幾つか、例えば jffs2 や logfs などが存在するのですが、これらはNANDフラッシュメモリを直接アクセスするような環境で使用されることを想定されています。

さて、NANDフラッシュベースのストレージであるSSDはしかし、ソフトウェアのレイヤから見た時に生のフラッシュメモリではなくハードディスクで使われるようなSATAなどをしゃべるディスクのように振る舞います。 しかしながら、NANDフラッシュメモリはモノからして磁気ディスクとは違うものです。 そのため、配線や材料の特性上、ハードディスクには無い以下のような特徴を持ちます。

  • 読み書きと削除の 粒度が異なる

    • ページ : 読み書きの単位。一般的なSSD なら、4kB~ であることが多い。
    • ブロック : 削除の単位。一般的なSSD なら、1MB~ くらい?
  • メモリセルへの 上書き処理が直接出来ない

    • そのため、まず削除を行う必要がある。巻き込まれるデータは退避させる
    • この処理のコストが大きいため、上書きするような小サイズのランダムライトの性能は出にくい
  • メモリセルに 書込み回数の上限(寿命) が存在する

このように、NANDフラッシュメモリは根本的にハードディスクと違うストレージである(そもそも内部的にはセクタ区切りにされていない!)ため、SSDはファームウェアで実装されている FTL(Flash Translation Layer) によって、これらの特性の隠蔽や改善を行っています。 このFTLは名前通りの変換処理以外にも、以下に挙げるような様々な役割を持っています。

  • セクタ単位のアドレスから、NANDフラッシュメモリに対応する物理アドレスへの変換
  • メモリセル延命のための ウェアレベリング
  • 削除処理の発生を抑制するための使用済みページの ガベージコレクション
  • オーバープロビジョニング(OSには隠された予備領域) を使った性能向上

この辺は Software Design 2013年11月号のFusion-io解説記事 とか、僕が昔書いた資料を読むと良いと思われます(宣伝)

さて、F2FS の話に戻します。 F2FSが謳っている NANDフラッシュベースのストレージ特化 というのは、「FTLがなんか色々勝手に処理しているのを想定した上で的確に振る舞う」ファイルシステムとなります。

F2FS の仕組み

F2FS は以下のような特徴、機能を持つファイルシステムです。 基本的に、ログ構造的な書込み方式を採用しつつ、副次的な問題を抑制することにより書き込み性能を向上するところが大きなメリットであると思われます。

  • LFS(Log-structured File System) 的なデータ書込み方式による、書込み性能の向上
  • LFSのネックを抑制する設計

  • フラッシュメモリの処理単位に合わせたログ書き出し

LFS(Log-structured File System) について


Log-structured File System はパーティション全体を連続した記憶領域として扱います。 LFSへの書込みはその連続した領域に"ログ"として書き残されます。

LFS はディスクへの書込みをシーケンシャルライトで行うため、SSDに導入することでランダムライトの発生を抑制し、性能向上をねらうことができます。 しかしながら、ある程度使い込まれた際に不要になったログを回収(ガベージコレクション)して、新たにログを書き出せる連続した空き領域を作る必要があり、この処理のコストが高い問題があります。

LFSのモダンな実装として、NILFS2 などが挙げられます。

F2FS の工夫


F2FSでは、上記のLFSのようなログ構造的なデータの書き出しを行い、SSDに対して発行されるランダムライトの頻度を低下させる(シーケンシャルライトとして書き出させる)ことにより性能を向上させつつ、LFSのデメリットを解消する工夫がなされています。 ちょっと調べたところ、以下のような特徴があるようです。詳しくはF2FSの紹介スライドなどを参照してみてください。

1. バックグラウンドガベージコレクション

後述のブロック割当のポリシーにもよるのですが、ログのガベージコレクションを基本的にバックグラウンドで行います。

2. ブロック割当のポリシー

ログのガベージコレクション処理は非常にコストのかかる重い処理ですが、これを行わなければ連続した空き領域を確保できずランダムライトが発生してしまいます。 F2FSでは、これを考慮し、ガベージコレクションを行う/行わないポリシーを提供し、デフォルトではこれを状況に応じて使い分けるような挙動をします。 具体的には、通常は以下に挙げる Copy-and-compaction を採用し、空き領域が十分に無い場合には Threaded logging に動的に切り替わります。

3. Hot/Cold データの分離

F2FSでは、データの書き込み頻度の偏りにより、書き出すログをそれぞれ別の場所に分離し、性能向上のためそれぞれフラッシュメモリの処理単位にまとまるように書き出します。 書込み頻度の高いデータの局所性を高めることにより、ガベージコレクションのオーバーヘッドを低減している模様?

F2FS の性能

ここまでの流れから、確かに F2FS でランダムライトの性能を向上できる気がしてきます。 しかしながら、他のファイルシステムと比較して性能がどれくらい伸びるのか、ランダムライト以外の性能はどうなのかという点も気になってきます。

F2FSの性能に関しては、既に幾つかのファイルシステムとの性能比較データがあります。 が、SSDはベンダーや型番により中身が大きくことなるのに合わせ、最近のカーネルだと性能がどうなのかという辺りが気になったので、fio でベンチマークを行い性能比較を行ってみました。

実験環境

ベンチマークを行った環境は以下の通りです。

各項目 詳細
CPU Intel Core i5 760 @ 2.80GHz
Mem 8GB
SSD Intel 320 80GB (ファームウェア最新)
OS Ubuntu 13.10
Kernel 3.12.5 (バニラカーネル)

実験方法

ここでは、fio を用いてベンチマークを行ってみます。 *.fio ファイルは以下の通り記述しました。 各項目については、man を読むなどして確かめてみてください。

ここでは以下の4つのアクセスパターンに絞ってベンチマークを行ってみました。 アクセスパターンは、上の *.fio ファイルの値を適宜修正することで変更しました。

  • シーケンシャルリード
  • シーケンシャルライト
  • 4k ランダムリード
  • 4k ランダムライト

また、ファイルシステムの差異による性能の違いを見たいため、以下のようなファイルシステムを対象にそれぞれベンチマークを回しました。

  • F2FS
  • ext4
  • XFS
  • btrfs
  • btrfs(ssd_spread オプション有効)
  • NILFS2

btrfs については、SSD の最適化をより強化するためのマウントオプション ssd_spread があるようなので、これが有効/無効である場合でそれぞれ測定を行いました。

実験結果

fio による性能測定結果は、以下のグラフの通りになりました。 グラフの縦軸の単位ですが、シーケンシャルリード/ライトは Mbps 単位で、ランダムリード/ライトは IOPS 単位で出しています。

この実験結果から、だいたい次のことが言えるかなと思います。

  • F2FS、本当に性能が出た。特にランダムライトが顕著
  • XFS、btrfs もかなり検討している。

    • ただし、btrfs の ssd_spread オプションによる性能向上は今回は見られなかった
  • NILFS2 の性能があまり出ない・・・何かミスっているだろうか

シーケンシャルリードの性能


ファイルシステム毎の差はほとんど見られない値になりました。

f:id:syu_cream:20131219214953p:plain

シーケンシャルライトの性能


ext4、次いで NILFS2 が性能が落ち、他はほぼ同じくらいの性能となりました。

f:id:syu_cream:20131219215002p:plain

ランダムリードの性能


ext4、btrfs、NILFS2の性能があまり伸びす。 F2FS とXFSの性能が目立ちます。

f:id:syu_cream:20131219215009p:plain

ランダムライトの性能


F2FSが抜きん出て性能が良いです。 次いで btrfs、XFSの性能が目立ちます。

f:id:syu_cream:20131219215017p:plain

さいごに

性能だけ見ると、F2FSは悪くないように思えます。 おそらく、安価でファームウェアがあまり賢く無いSSDに使うには良いかと。導入もそれほど難しくなくお手軽なので。 ただし、実際の運用が楽なのかどうかという点も気になりますね。

最近、SSD自体やSSDをハードディスクのキャッシュとして用いる性能向上手法がやたら出てきて群雄割拠の状態かと思います。 更に、Fusion-io みたいな余計なレイヤ挟まないことにより性能を出すみたいな道も一般化してきていて。。。 F2FSがこの先生きのこるにはどうするか、どうなっていくのか気になってくるところですね。

ATSのドキュメント翻訳活動とその周辺

このエントリーは、 Doc-ja Advent Calendar 2013 の 17日目の記事として書いています。 前日の担当者は、@okano_t さんです。

どうもこんにちは、 @syu_cream です。

主に、最近やっている Apache Traffic Server のドキュメント翻訳についてつらつらと書いてゆきます。 翻訳作業に着手して3ヶ月程度しか経過しておらず、まだまだ初心者の域を脱せていないと思うのですが、何か参考になることがあれば幸いです。

Apache Traffic Server is 何

Apache Traffic Server (以下、ATS)は、オープンソースの高性能 HTTP キャッシュプロキシサーバです。 元々は Yahoo!(米社) が自社で使用していたキャッシュサーバがOSS化されたもので、現在は Apache の Top level projects の一つとして開発が進められています。 使用している企業として、Yahoo! や Taobao 、LinkedIn、国内では Yahoo! JAPAN や pixiv が挙げられます。
また、類似する機能を持つソフトウェアに、 nginx, Squid, Vernish などが存在します。 (これらキャッシュサーバの比較については、IIJの記事が纏まっていて良さげです。)

ATSは日本国内ではユーザは少なめなのか、日本語の資料が不足しています。 そこで本家のドキュメントを翻訳し、最低限利用可能な情報を手に入れ易くしたい、という辺りが本活動のモチベーションです。

ATSの翻訳活動について

規模

現在、アクティブな翻訳参加者は 4 人と、小規模な活動となっております。

翻訳のフロー

現在 ATS ドキュメントの日本語化の作業は、Sphinx のドキュメント国際化のフローに則り、GetText の PO(Portable Object) ファイルを編集することで行っております。 PO ファイルの管理やレビューは、 GitHub ベースで行われています。

現在の基本的な翻訳作業のフローは下図の通りになります。 まず前提として、日本語翻訳専用の Organization アカウント(trafficserver-doc-ja)が存在し、このアカウントが本家ATSのリポジトリを fork したリポジトリを持ち、その中に翻訳済みドキュメントを集約するブランチ(doc-ja) を持ちます。 各翻訳者は、このリポジトリを個々で更に fork します。

各翻訳者はまずドキュメント翻訳作業ブランチを切り、手元で PO ファイルを編集することで作業を進めます。 その後、 trafficserver-doc-ja の doc-ja ブランチに Pull-Request を送ります。 これを他の翻訳者がレビューし、不適当な訳文は指摘して修正し、適当になったタイミングでマージを行います。 ある程度ドキュメントの翻訳が進んだら、trafficserver-doc-ja のオーナーとなる翻訳者が本家ATSリポジトリに Pull-Request を送ります。(本家リポジトリへの貢献は現在は計画段階であり、実行するまでには至っておりません)

f:id:syu_cream:20131217002308p:plain

翻訳のツール

エディタ


各翻訳者が思い思いのエディタを使います。 ちなみに僕は Vim を使って翻訳作業をしています。

コミュニケーション


基本的なコミュニケーションは IRC 上で行っております。 また、翻訳作業に関する issue などは、GitHub でやり取りします。

レビュー


レビューは GitHub 上で Pull-Request に対してコメントを付けることで行っています。 指定の行にサクッとコメントを付けて良いです。 しかし一方で、長文になると読みにくい、指摘された箇所の原文・訳文対応がパッと見た時に分かりにくいという難点もあります。

翻訳の進捗どうですか?

進捗ダメです! ・・・というほどでは無いとは思います。着々とは進んでいるはず。

しかし未だ、必要最低限の日本語のドキュメントが揃っているとは言いがたい状態です。。。

翻訳作業を通して思い付いた開発ネタ

翻訳作業をしていくうちに、翻訳作業自体の効率化についても興味が湧いてきます。

直近では、Vim 上でPOファイルのシンタックスチェックができるよう、シンタックスチェックプラグインの Syntastic に Pull-Request を投げたりしました。

最近は、poedit 風の編集画面を Vim 上でも使えるようになりたいなーなどと考えております。 えっ Vim を捨てて poedit を素直に使えば良い?そういう手段もあるのか!思い付かなかったぜ!

翻訳活動に関する悩み

  • 英語力が無さ過ぎ て翻訳が難しい・・・
  • ギッハブの Pull-Request ベースのレビューが読みにくくてつらい・・・
  • 編集環境がまだ最適化の余地がある気がする・・・
  • モチベーションの維持が大変・・・

この辺り、アドバイス等お待ちしております!

さいごに

ATSのドキュメント翻訳に興味のある方がいらっしゃいましたら、ぜひ活動に参加してみてください。 翻訳したドキュメントのPR投げるなり、既に翻訳されているドキュメントの間違いを指摘して頂けるだけでも大助かりです! また、ATS自体に興味を持って触れて頂けたりしても、嬉しく思います。:)

Doc-ja Advent Calendar 2013 18日目の記事は @naru0ga さん担当です。宜しくお願いしますー。

ChefのcookbookでLXCのコンテナのパッケージや設定を管理する

みんな大好きコンテナ仮想化。LXC非常に便利です。

しかし込み入った環境を作る際、コンテナを作り直したりリストアしたい場合、パッケージ導入を繰り返すのはなかなかしんどいと思われます。

そこで、Chefのcookbookでコンテナに入れるパッケージや設定を管理しましょう。

環境

以下、さくらVPSの2GプランでUbuntu 12.04をインストールした環境で試しています。

また、基本的にVPSのインスタンス上で作業をすることを想定しています。

コンテナへのcookbookの流し込みは、knife-soloで行います。

手順

1. LXCとChef 、knife-solo のインストール

apt でLXCを、gem でknife-solo をそれぞれインストールしておいてください。

2. LXC コンテナ用の、ローカルDNS設定を用意

コンテナを作成するたびに、コンテナのIPを調べるのは面倒なので、コンテナ名でアクセスができるようdsnmasqの設定を変更しておきます。

参考: http://orangain.hatenablog.com/entry/multi-node-serves-using-lxc-on-sakura-vps

3. knife-solo が利用可能な、ベースとなるコンテナを作成

knife-solo では基本的にsshでcookbookを流し込むので、事前に鍵設定を入れておくと便利です。

ここでは、鍵設定や、knife-soloのセットアップに必要なwgetを入れたコンテナを事前に作り、以降それをcloneして使おうと思います。

(コンテナ外で)
$ sudo lxc-create -n ubuntu-chef-base -t ubuntu
$ sudo lxc-start -n ubuntu-chef-base -d
$ ssh-keygen  -t rsa -b 4096 -f ~/.ssh/chef_key
$ ssh ubuntu@ubuntu-chef-base.local.example.com

(コンテナ内で)
$ mkdir .ssh
$ cat > .ssh/authorized_keys
chef_key.pub を貼付けてCtrl-D
$ chmod 600 .ssh/authorized_keys
$ sudo apt-get install wget
$ exit

(コンテナ外で)
$ sudo lxc-shutdown -n ubuntu-chef-base

4. ベースコンテナからclone してknife-solo を準備する

cookbookを流し込むコンテナをcloneし起動、chef-soloを実行出来るようprepareします。

$ sudo lxc-clone -o ubuntu-chef-base -n test
$ sudo lxc-start -n test -d
$ knife solo prepare ubuntu@test.local.example.com

5. Chef リポジトリを作成

手元にChefリポジトリを作ります。基本的にこのリポジトリ以下にcookbookを配置することになります。

$ knife solo init <リポジトリ名>

knife.rb (knifeの設定ファイル)に、cookbook_path などの記述が無ければ追記します。

$ vim ~/.chef/knife.rb
以下の記述がなかったら追記する。
role_path '/path/to/chef-repo/roles'
cookbook_path  '/path/to/chef-repo/cookbooks'
data_bag_path '/path/to/chef-repo/data_bags'

6. cookbook を用意

コンテナに流し込むcookbookを用意しましょう。

サードパーティ製 cookbook を持ってくる場合

例えば、opscode の提供するnginxのcookbookを持ってくる場合は以下のようにします

$ knife cookbook site vendor nginx

自分で cookbook を用意する場合

以下のようにして、新規にcookbook を作成します

$ knife cookbook create <cookbook名>

あるいは、既に作成した cookbook を chef-repo/cookbooks/ 以下に配置しましょう。

7. cookbook をコンテナに送り、実行させる

実行するrecipeを、nodes/ 以下のrun_listか、knife solo cook のoオプションで指定します。 以下はnginxのrecipeを実行する場合。

$ knife solo cook -i ~/.ssh/chef_key -o "recipe[nginx]" ubuntu@test.local.example.com

雑感

LXC、Chef周辺は補助的なツールが多くて、どういった構成が良いのかなかなか悩みます。

dockerとか、Berkshelf とか使うともっと楽になるのかしら。

本記事は以下の記事を参考に、手順をまとめました。: http://inokara.hateblo.jp/entry/2013/04/01/005519