次の方法で共有



April 2017

Volume 32 Number 4

コンテナー - Windows Server コンテナーで Windows 開発者が Docker を使えるように

Taylor Brown | April 2017

ここ数年、世界中の開発者サークルや企業の間で最も話題になっているトピックの 1 つが Docker とコンテナーです。昨年秋に Windows Server 2016 がリリースされ、Windows 開発者にコンテナーへの道が開かれたため、こうした会話がさらに盛り上げっています。Windows の世界と Docker はどのようにして融合することになったのでしょう。 2014 年夏、風光明媚なピュージェット湾で、Windows 基盤 チームが新しいプロジェクトを開始したのが始まりです。このプロジェクトが後の Windows Server コンテナーになります。今回取り上げるのは、このコードの背後にある物語です。そう、Windows Server 2016 最大の新機能の 1 つがビルドされていくようすお話します。

コンテナーの歴史と Docker のルーツ

2013 年にコンテナーは、PaaS (サービスとしてのプラットフォーム) の新興企業 DotCloud の創設者で当時 CTO だった Solomon Hykes 氏の手によって急速に関心を集め始めました。Hykes 氏は、どちらかというとわかりにくく、使いにくかった Linux カーネルの一連の機能をオープン ソース ツールにまとめ、これを Docker と名付けました。コンテナー界の覇者になろうと考えたのではなく、DotCloud を苦しめていた問題の解決策を探していました。 「開発者自身の作業環境と同じようにサーバーでも機能するコードを提供するにはどうすればよいだろう」と考えていたのです。 

DotCloud のようなサービスにとって実際に問題になるのは、顧客が導入するソフトウェア アプリケーションが多岐にわたることです。これらのソフトウェアは、異なる開発プロセスでビルドされます。コーディングの言語も異なれば、開発者が話し合う言葉も違います。修正プログラムのサイクルもその要件も異なり、依存関係も違います。ハードウェアの仮想化、つまり仮想マシン (VM) は、利用できる中では最高のツールでした。しかし、開発者の PC から運用環境にソフトウェアをリリースするにあたり、課題が生じます。開発者の環境と同じ完全に構成済みの VM を使用するか、運用環境の VM で配置ツールやスクリプトが動作するようにして開発者のアプリケーションをインストールする必要が生じます。前者は、スケーラビリティに問題が生じ管理が難しくなります。後者は、非常に柔軟性に欠け、不安定になります。

Hykes 氏は、こうした問題の答えになるのが Docker だと考えました。今になってみると確かに、Hykes 氏の考えは的を射ていました。ただし、コンテナーに注目していたクラウド サービスは Docker が最初ではありません。実は、別のクラウド サービスもその必要性を感じ、まったく新しいアイデアを打ち出したのです。それが Google です。2006 年に、Google のエンジニア Rohit Seth 氏が Linux カーネルのパッチを提示しました。このパッチは、プロセスのグループ化を追加サポートします。このグループ化は、ある機能に含まれる一連の共通リソース制御によって実現されます。この機能は cgroups と名付けられます。Seth 氏はこのパッチの説明の冒頭で次のように述べています。 「コモディティ ハードウェアの性能はますます向上しています。そのため、異なるワークロードを同じプラットフォームで実行し、ハードウェア リソースの利用効率を向上するチャンスが生まれます」(bit.ly/2mhatrp、英語)。cgroups によってリソースの分離の問題が解決されます。しかし、ディストリビューション間の不統一は解決しませんでした。そこで、Docker は cgroups だけでなく、もう 1 つの Linux テクノロジ namespaces を採用することになります。

namespaces は 2002 年に Linux カーネルに導入された機能で、プロセスから認識できるリソースと、それらのリソースの呼称を制御する手段を提供します。namespaces はアクセス制御とはまったく異なります。それは、プロセスが、リソースの存在も、使用するリソースのバージョンも認識しないためです。この簡単な例がプロセス リストです。サーバーで 20 個のプロセスが実行されていても、ある namespace 内で実行されているプロセスがこれらのうち 5 個のみであれば、プロセス リストにはその 5 個のみが表示され、残りは表示されません。他にも、namespace を使って、実際には別の場所から仮想化されているにもかかわらず、プロセスからはルート ディレクトリから読み取っているように感じられるようにする例もあります。cgroups と namespaces と コピー オン ライト (CoW) ファイル システム テクノロジを組み合わせて作られた使いやすいオープン ソース製品が、Docker の基盤となっています。

2013 年半ばには Hykes 氏率いるチームがビルドした Docker ツールセットが注目を集め始め、GitHub で最も人気のあるプロジェクトの 1 つとなり、正式に Docker ブランドの立ち上げに至ります。Hykes 氏の重点は DotCloud から Docker に移り、最終的には、Docker Inc の CTO に留まりながらも、DotCloud ビジネスからはスピンオフすることになります。

Windows Server コンテナー

Docker が Linux サークルで話題になっているころ、Windows 基盤 チームも、顧客やサード パーティのコードを実行する Microsoft Azure サービスをそれぞれ分離し、効率を上げる方法を模索していました。コードネーム「Drawbridge」という Microsoft Research のプロトタイプを候補として調査が始まりました。このプロジェクトでは、ライブラリ OS を利用してプロセス分離コンテナーをビルドしました (bit.ly/2aCOQxP、英語)。残念ながら、Drawbridge は保守が難しく、パフォーマンスやアプリケーションの互換性に制限があり、汎用ソリューションには不向きでした。そこで調べる価値がありそうだと考えたのが、かなり前のプロトタイプ テクノロジであるサーバー サイロです。サイロは、既存の Windows ジョブ オブジェクト アプローチを拡張したものです。このアプローチは、プロセスのグループ化とリソース制御を提供します (Linux の cgroups と同様) (bit.ly/2lK1AbI、英語)。サーバー サイロ プロトタイプによって追加されるのは分離実行環境です。この実行環境には、ファイル システム、レジストリ、オブジェクト名前空間を含みます (Linux の namespaces と同様)。サーバー サイロ プロトタイプは、VM が優先されたため数年間お蔵入りしたままでしたが、Windows Server コンテナーの基盤として再考されることになります。

サーバー サイロ プロトタイプのコードは、長年見向きもされていませんでした。機能するどころか、コンパイルすらされず、Windows で実現可能な手法を証明するために作成されたプロトタイプにすぎず、運用とはほど遠い状態でした。チームの選択肢は 2 つ、最初からやり直すか、プロトタイプを復活させてそれをたたき台にするかです。チームが選んだのは後者です。プロトタイプを初めて開発したチームは、サーバー サイロが実現可能であることを証明するために編成された小さな開発者チームにすぎませんでしたが、Windows エンジニアリング チーム全体でこのプロジェクトを支えるまでになっています。Windows チーム全体からアーキテクトとエンジニアが駆り出されています。ストレージ チームが、ファイル システムの仮想化を構築しています。ネットワーク チームが、ネットワークの分離を構築しています。カーネル チームが、メモリ管理とスケジュールの抽象化を構築しています。

アーキテクチャに関して大きな問題がいくつか残っています。特に大きな問題は、システム プロセスの扱い方です。 Linux でよく行われるのは、コンテナーがプロセスを 1 つだけ実行し、そのプロセスと、ホストや他のコンテナーが、カーネルのシステム サービスを共有する方法です。ただし、Windows では何年も前にサービスの可用性とセキュリティを向上するために、カーネルのコードをユーザー モード プロセスに移しています。チームにとってはこれが問題になります。 チームが考えたのは、すべてのシステム サービスを共有する方法と、ユーザー モード システム サービスのコピーを各コンテナーで新しく作成する方法でした。前者の場合、システム サービスをコンテナー対応にするため、すべてのサービスを変更する必要があります。これは難しい判断です。各コンテナーですべてのユーザー モード サービスの新しいインスタンスを開始すると、密度とスタートアップ時間への影響が懸念されます。一方、Windows のシステム サービスをすべて更新するとなると、チームだけでなく、Windows チーム以外の開発者も作業が複雑になり、作業コストが発生します。最終的には、この 2 つのアプローチを融合させることになります。つまり、選別した一部のサービスをコンテナー対応にしますが、大半のサービスは各コンテナーでコピーを実行します。

密度への影響は最小限に抑えられます。コンテナーは他のコンテナーやホストと読み取り専用のメモリを共有するため、コンテナーごとに必要になるのはプライベート メモリだけです。しかし、スタートアップ時間の問題はかなりハードルが高く、何度もこの判断については問題にされました。Windows Server コンテナーのデモを Build 2015 の基調講演で初めて披露したとき、主にシステム サービスのスタートアップ時間が原因で起動に数秒かかりました。ただし、これには Windows Server パフォーマンス チームが対応しました。同チームは、プロファイリングと分析を行い、Windows の各チームと連携して、サービスのスピードアップと、並列処理能力を上げるために依存関係を減らしました。こうした努力の結果、コンテナーのスタートアップ時間が短縮されただけでなく、Windows のスタートアップ時間も改善されました (昨年、Xbox や Surface のスタートアップが速くなったのは、コンテナーのおかげです)。 1 年足らずの間に、およそ 7、8 秒かかっていたコンテナーのスタートアップ時間が 1 秒未満になっています。現在もスタートアップ時間を短縮する取り組みは続いています。

Hyper-V による分離

Hyper-V による分離ついて最初にたずねられるのは「コンテナーによって既に分離されているのに、 なぜ Hyper-V が必要なのですか」という質問です。 確かにコンテナーによって分離が提供され、ほとんどのシナリオでは、その分離でまったく問題ないと思われます。ただし、攻撃者がカーネルを侵害できたとしたら、侵害されたコンテナーから他のコンテナーやホストに影響が及ぶリスクがあります。Windows ではカーネルのエクスプロイトは時折見受けられ (年に数回)、Azure Automation や Azure Machine Learning のような、共有インフラストラクチャ上でエンド ユーザーやサードパーティのコードを使用および実行するサービスの場合、カーネルの分離だけに頼るのはリスクが高過ぎます。この種のサービスをビルドおよび運用するチームは、VM 全体の密度とスタートアップのコストに対応するか、別のセキュリティ技法や分離技法を考案する必要があります。必要なのは、侵入者に対抗しながら、マルチテナントの安全性を保つ汎用の分離メカニズムでした。 それが、Windows Server コンテナーと Hyper-V による分離の併用です。

チームは既に Windows Server コンテナーに懸命に取り組んでいました。これはすばらしい経験になり、サービスをビルドするチームにとっては優れた管理モデルが得られました。Windows Server コンテナーと、確かな実績を持つ Hyper-V の分離を組み合わせることで、必要なセキュリティが実現されます。ただし、スタートアップ時間と密度の問題を解決する必要がありました。これは、以前から VM に関係する問題です。

ほとんどの仮想化プラットフォームと同様、Hyper-V は新旧含めさまざまなゲスト OS を実行できるよう設計されています。できる限りハードウェアと同じ動作を目指して、ほとんどの仮想化プラットフォームが採用したソリューションは共通ハードウェアのエミュレーションを行うことでした。しかし、仮想化が一般的になるにつれ、OS 自体が「調整」 (ゲスト VM として運用できるように変更) され、大半のエミュレーションは不要になっています。その好例が Hyper-V の第 2 世代 VM です。この VM ではスタートアップ時間とパフォーマンスの改善を優先してエミュレーションを廃止していますが、ゲストをハードウェアで直接実行しているかのような動作を実現するという目的を達成しています (bit.ly/2lPpdAg)。

コンテナーの場合、ニーズも異なれば、目標も異なります。 古い OS を実行する必要はなく、VM 内部のワークロードはコンテナーに決まっています。そこで、コンテナーの実行を目的に設計した新しい種類の VM をビルドしました。すばやいスタートアップというニーズに対処するため、複製テクノロジを開発しました。このニーズがこれまでの VM にとって常に課題になっていたのは、OS がホスト名や ID などによって特殊化されるためです。こうした特殊な状況はリブートしなければ簡単には変更できません。しかし、コンテナーには独自のホスト名と ID があるため、この点については問題はなくなります。複製は密度の問題にも効果がありますが、それ以上に必要なことがあります。 それはメモリを共有することです。

メモリを共有する方法は 2 とおりあります。1 つは、複数の VM の間で共通するメモリを探し、重複を排除する方法です (ただし、ほとんどのカーネルに実装されているメモリのランダム化テクノロジにより、この方法は困難です)。もう 1 つは、カーネルと同様に、読み取り専用 (パブリック) メモリと読み取り/書き込み (プライベート) メモリを分離する方法です。後者の場合は、通常、ゲスト VM のメモリ マネージャーが相互作用する必要があり、分離要件に反します。しかし、VM のブート方法とファイルへのアクセス方法を変更することで、ホストがゲストを信頼する必要がなく、ゲストどうしも信頼する必要がない方法を見つけました。それは VM のブートとファイル アクセスを仮想ハード ディスクからではなく、ホストのファイル システムから直接行うようにする方法です。つまり、ホストは同じように読み取り専用 (パブリック) メモリを共有できます。これが密度を桁違いに向上する鍵となります。今後も長年にわたり、密度を向上できる道筋が見えてきます。

Hyper-V の分離によってもたらされるもう 1 つのメリットは、コンテナー化したアプリケーションを Windows 10 コンピューターで開発している開発者の場合、コンテナーで実行するカーネルを変えることで、サーバー カーネルを実行しながら、アプリケーションが運用環境でも開発者の開発用コンピューターと同じように動作することを保証できます。したがって、Windows 10 Anniversary Update において、Windows Server コンテナーと Hyper-V の分離の連携を有効にし、Docker と協力して Docker for Windows を開発して、この開発者向けの新しいテクノロジを最大限活用できるようにしています。

Docker と Windows Server コンテナー

最後に残った問題は、この新しいプラットフォーム テクノロジをユーザーがどのように操作することになるかです。 Linux の世界では Docker が賛辞を集め、瞬く間にコンテナー管理のデファクト スタンダードになりました。同じようにユーザーが Windows Server コンテナーを使用できるようにすればよいのではないでしょうか。 その年の秋、Docker と面談するためサンフランシスコに飛びました。Docker が Windows ベースのコンテナーをどのように考えるのか。そもそも、Windows 上にコンテナーをビルドすることに関心を示すかどうかもわかりませんでした。しかし、驚いたことに、 Hykes 氏は Windows コンテナーのアイデアをすばらしいと考えたのです。 しかし、同社は Windows の上位にコンテナーをビルドするのでしょうか。 そのときの話合いで、プロジェクトの様相は一変しました。Hykes 氏は「Docker はオープン ソースです。Windows 上で動作できるようにコードを追加できます。当社も手伝いましょう」と話し、そのとおりになりました。それ以来、Hyper-V チームのソフトウェア エンジニアの John Howard は、Docker プロジェクトの担当者となり、実際、歴代最高のコード貢献者に 4 度輝いています (bit.ly/2lAmaZX、英語)。図 1 に、Windows と Linux のコンテナーおよび Docker の基本アーキテクチャの違いを示します。

Windows と Linux のコンテナーおよび Docker の基本アーキテクチャの比較
図 1 Windows と Linux のコンテナーおよび Docker の基本アーキテクチャの比較

まとめ

4 か月前の Microsoft Ignite において、Windows Server 2016 をリリースし、Docker との提携拡大を発表しました。この提携拡大によって、有償サポート バージョンの Docker Engine が、Windows Server ユーザーには無償提供されることになります。この発表以降は目が回る忙しさです。Tyco などのユーザー企業は、Docker と Windows Server コンテナーを利用して、すべて同じプラットフォームを基盤に、ソフトウェア開発の方法を変革し、既存のアプリケーションを近代化しています (bit.ly/2dWqIFM、英語)。Visual Studio 2017 は、Windows と Linux のコンテナー向けの包括的統合ツールで、F5 デバッグ機能などを含みます。Visual Studio Code には Dockerfile が含まれ、作成のサポートが組み込まれます。Azure と Amazon のコンテナー サービスも Windows Server コンテナーのサポートを追加しており、100 万を超える Windows ベースのコンテナー イメージが Docker Hub から取得されています。エンドツーエンドのセキュリティとオーケストレーションを実現するため、Docker Datacenter が用意されます。これは、開発者とシステム管理者がどこからでも、分散アプリケーションをビルド、リリース、運用できるプラットフォームです。Docker により、アプリケーションをリリースするまでの期間を数か月から数分に短縮でき、ワークロードをデータセンターとクラウド間でスムーズに移行できます。また、コンピューティング リソースの利用効率も 20 倍になります。

コンテナーを担当することになったとき、非常にストレスの高いプロジェクトになることを覚悟していました。何度も長い夜を過ごし、週末も仕事をして、多大な努力を払うことになることはわかっていました。しかし、数百万人の開発者が、今よりも速いアプリをさらに多く開発する役に立つので、それだけの意義はありました。また、非常に楽しく、Windows でアプリケーションが開発および実行される方法を大きく変えるチャンスがあることもわかりました。予想以上に仕事をすることになりましたが、予想できないほど楽しいことも多くありました。この経験は何物にも変えられません。プロジェクトが始まってすぐの、ある週末を思い出します。天気のとてもよい夏の日で、オフィスの窓から外を眺めながら、「皆さんにこれを使ってもらえるようになるとよいな」と考えていました。


Taylor Brown は Microsoft の Windows およびデバイス部門を率いる首席プログラム マネージャーです。Windows 基盤エンジニアリング チームのメンバーで、Windows Server コンテナーを含め、特に、コンテナー テクノロジを中心に、Windows Server 開発者戦略を担当しています。Windows 開発のキャリアは、Windows 2003 向けの 1394/FireWire スタック関連の開発から始まり、Windows Server 2003 SP1 の ACPI/電源管理を経て、新たに設立された仮想マシン チームのメンバーになりました。それ以来、Virtual PC、Virtual Server と Hyper-V の全バージョンなど、Microsoft がリリースしたすべての VM テクノロジに貢献しており、仮想化テクノロジ界の専門家として認められています。連絡先は taylorb@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれた技術スタッフの David Holladay に心より感謝いたします。