エンジニアの生き様をウォッチするメディア

まつもとりーのインフラ入門-第二回 「WebサーバとWebホスティングシステム」

みなさん、こんにちは。まつもとりーのインフラ入門第二回です。 本連載では、主にインターネット基盤技術、または、インターネットのインフラ技術と呼ばれる領域に関して執筆していくと前回述べました。 そこで、第二回では古くからあるWebホスティングサービス、または、レンタルサーバと呼ばれるサービスについて、Webサーバの観点からどのような技術的取り組みがなされてきたかを紹介します。

本記事を通じて、Webホスティングサービスのように古くから提供され、長い間改善が積み重ねられてきたサービスの構成や設計から、WebサーバやOSに関する基礎的でありながら実践的な知識を習得頂ければ幸いです。

Webサーバのマルチテナントアーキテクチャとは

Webサービスの普及とスマートフォンのように手軽にWebサービスを利用できる個人端末の爆発的普及によって、安定したWebサービスを構築するための基盤技術とシステム運用技術が注目されてきました。 その中で、Webサーバ上に複数のホストを高集積に同居させることを目的とした高集積マルチテナントアーキテクチャは、大幅にハードウェアコストを低減するだけでなく、負荷分散や可用性を担保できる構成をとることで運用コストも低減できるとされ、数多くの取り組みがなされてきました。

特に、マルチテナントアーキテクチャを採用した代表的なWebサービスであるWebホスティングサービスは、20年前から高集積化とそれによる低価格化も目的としていたため、Webサーバのマルチテナントアーキテクチャを採用することが多くなっています。 高集積マルチテナントアーキテクチャを採用することで、後述しますが、収容ホスト数の増加に伴って、Webサーバソフトウェアの設定を変更し、プロセスの再起動や再読込することなく高集積に収容することができます。 そのため、同一設定のまま新しいサーバを増やすといったようなスケールアウト型の負荷分散も可能となりハードウェアのコストを効率良く利用できます。

しかし、そのようなシステムの信頼性を高め、安定的にサービスを提供するためには、セキュリティ、リソース分離、および、運用技術の改善が重要になってくることがわかってきました。 同時に、Webホスティングサービスは、各ユーザ領域に利用者が任意のWebコンテンツを置くことを許すため、管理者はWebコンテンツに依存しないOSやミドルウェアといった基盤技術のみで、マルチテナント環境におけるセキュリティや安定性を担保しなければなりません。

例えば、Webサーバにおける高集積マルチテナントアーキテクチャの目的の一つは、例えば、メモリ数十GBのメモリを積んだ1台のサーバに数万以上のホストの収容を目指しながらも、収容するホスト数に依存して、リソース使用量や設定変更に伴う再起動が極端に増加しないようにすることです。 さらに、Webホスティングサービスの場合、サービス利用者が各ホストに自由にWebコンテンツを配置できます。 そのため、Webホスティングサービス事業者は、ホストに対するコンテンツの配置やアクセスは事前に予測できず、特定のホストにアクセス集中し、サーバが高負荷状態になることもあるわけです。

このような課題を解決するためには、HTTPリクエストのあったホスト名に従って、ホスト毎にサーバープロセス群を待機させるのではなく、単一のサーバプロセス群を事前に待機させて、複数のホストに対するリクエストを共有して処理する必要があります。 ただし、実際にサーバプロセスは収容ホスト数には依存しないものの処理を分散させるために、一般的にCPUコア数から常に数十、数百のワーカープロセスが待機しています。 このような構成をとれば、収容ホスト数が増加してもホスト数に依存して待機しておくプロセス群を増やす必要がなく、リソース効率が良くなります。 さらに、複数のホストを単一のサーバプロセス群で処理するため、同一の設定のままWebサーバを複数台に増やすことも可能となり、スケールアウト型の負荷分散も可能になります。

また、異なるホストへのHTTPリクエストを単一のプロセスが代わる代わる処理処理するため、ホストのセキュリティをプロセスの機能を利用してHTTPリクエスト単位で担保しながら、性能を最大化する必要もあります。 同様に、複数のホストのリソースが単一のプロセスグループ間で共有されるため、いかにホスト間で生じるリソース競合を低減させるかも課題です。 このことから、セキュリティやリソース管理について、いかに人の手を介さずにWebサーバの機能として実現しWebさーばの運用コストを減らせるかが、高集積マルチテナントアーキテクチャを採用したシステムの運用・保守にかかるコストを低減させるために重要となります。

本連載では、大規模Webホスティング基盤を実現するにあたり、ApacheのVirtualHostのような高集積マルチテナントアーキテクチャを採用することで生じる、セキュリティや性能上、運用上の課題およびリソース分離といった実践的な観点から、Webサーバのアーキテクチャに基づいてLinuxやWebサーバの基礎技術を体系的に紹介します。

まず、本エントリではWebサーバのアーキテクチャやWebホスティングシステムの構成について整理します。

WebサーバとWebホスティングシステム

Webホスティングサービスとは、複数のホストでサーバのリソースを共有し、それぞれの管理者のドメインに対してHTTPサーバ機能を提供するサービスです。 Webホスティングサービスにおいて、ドメイン名(FQDN)によって識別され、対応するコンテンツを配信する機能をホストと呼ぶことにします。

サービス提供側がWebホスティングシステムを構築する手法は、主に以下の4種類に分類することができます。

  1. XenやVMware等の仮想マシンでホストを分ける手法
  2. FreeBSD jailやLXC、OpenVZ等のコンテナ型仮想化のようにファイルシステムや名前空間を操作するシステムコールによってOS上に複数の仮想的な隔離環境を用意しホストを分ける手法
  3. IPアドレスやポート単位でWebコンテンツが配置された複数のホストを分離し各ホストに個別のプロセスを用意して起動させる手法
  4. 単一のサーバプロセス群で複数のホストを仮想ホスト方式により扱う手法

サーバの運用面やセキュリティを重視した場合は、手法(1)(2)(3)等の、管理者それぞれに対して、個別のサーバプロセスや仮想マシンを割り当てる構成がとられてきました。 例えば、OSのシステム領域に近い環境を、特定のディレクトリ配下に作り、IPアドレスを1台のサーバに複数設定した上で、リクエストを受けたIPアドレスに応じてそのディレクトリ内へchroot()システムコールによりルートディレクトリを移動する方法です。 さらに、unshare()システムコールによって、プロセスIDやネットワーク名前空間を隔離し、そのようなコンテナ型の仮想環境を複数用意し、それぞれで個別のIPアドレスで通信できるWebサーバプロセスを起動します。

以下の図は、運用面とセキュリティを重視した場合に、(2)の手法でchroot()システムコール等を活用したホスト分離をApacheで構築した場合の概要図です。

chroot環境内部において、Webサーバプロセスはchroot()システムコールの実行権限を持たない一般ユーザとして起動し、OSのシステム領域に到達することはできなくなります。 また、chroot環境はOSのシステム領域とほぼ同等のライブラリ群を任意に配置できるという利便性もあります。 そのため、サーバプロセスの設定を全てホスト専用に設定することができ、運用面でも可用性が高くなります。 さらに、不必要なコマンドやライブラリを配置しないことで、簡易的に機能を制限することができます。

JaveServletのように個別のJVMを複数用意して、各JVMのプロセス単位で複数のホストを収容する方式は(3)に該当します。 同様に、Ruby on Railsも(3)の方式であり、Webサーバ機能と一体となってアプリケーションサーバとして動作するため、複数ホストを収容するためにはその数だけアプリケーションサーバプロセスを用意する必要があります。

例えば、(3)の手法を利用して複数のサーバプロセスをそれぞれ異なるユーザ権限で起動する方法もあります。 しかし、各chroot環境などにおいて、ホスティング利用者単位でサーバプロセスを起動させると、リソース使用量の面で高集積にサーバにホストを収容することができなくなります。 これに対し、(4)の手法による単一のサーバプロセス群で複数のホストを仮想的に処理する構成の場合、仮想ホスト方式と呼ばれるマルチテナントアーキテクチャを用いることで、高集積にホストを収容できないという課題を解決することができます。

以下の図は、ApacheのVirtualHostを利用して単一プロセスで複数ホストを扱う構成を示しています。

本記事では、仮想ホスト方式によるマルチテナントアーキテクチャにおいて数万以上のホストを収容できるものを高集積マルチテナントアーキテクチャと呼ぶことにします。

仮想ホスト方式では、アクセスのあったホスト名に対応したドキュメントルートにアクセスするようにWebサーバ内部で制御するので、複数のホストに対して単一のサーバプロセス群が起動していればよいです。 さらに、複数の仮想ホストが設定されたサーバを複数台用意しておくことにより、いずれかのサーバのWebサーバプロセスにアクセスがあれば、共有ストレージを介して、適切なレスポンスを返すことができます。 各サーバのサーバプロセス数は収容するホストの数に依存しないため、複数台の物理サーバ上で同一の設定のサーバプロセスを起動しておくことで、共有ストレージを用いた効率の良い負荷分散構成も構築できます。 新しいWebサーバの追加も、追加した後に必要なタイミングでProxyなどを使ってリクエストを新たに振り分ければよいため、容易に実現できます。

まとめ

ということで、今回は高集積マルチテナントアーキテクチャを採用した代表的なサービスであるWebホスティングサービスにおいて、ホストを収容する方法とその分類について述べました。 次回は、もう少しWebホスティングサービスとWebサーバに必要な基礎知識を述べた後に、こういった高集積マルチテナントアーキテクチャにおいて、どのようにホスト同士のリソース管理を行うかについて紹介します。

(記事:松本 亮介)

京都大学博士(情報学)、さくらインターネット研究所上級研究員、ペパボ研究所客員研究員、Forkwell技術顧問、セキュリティ・キャンプ講師、情報処理学会各種委員、松本亮介事務所所長。

2008年に現場の技術を知るため修士に行かずにホスティング系企業に就職したのち、2012年に異例の修士飛ばしで京都大学大学院の博士課程に入学。インターネット基盤技術の研究に取り組み、mod_mrubyやngx_mrubyなどのOSSを始めとした多数のOSSへの貢献や学術的成果を修める。

2015年4月より2018年10月までGMOペパボ株式会社にてチーフエンジニアとしてプロダクトのアーキテクトやエンジニア組織のマネージメントに従事すると同時に、ペパボ研究所では主席研究員としてOS・Middleware・HTTPに関する研究、及び、事業で実践できるレベルまで作りこむことを目標に研究に従事。

2018年11月より現職のさくらインターネット研究所で上級研究員を務める。

第9回日本OSS奨励賞や2014年度情報処理学会山下記念研究賞など、その他受賞多数。2016年に情報処理学会IPSJ-ONEにおいて時流に乗る日本の若手トップ研究者19名に選出される。