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

まつもとりーのインフラ入門-第九回「高集積マルチテナントアーキテクチャの運用技術(1)」

みなさん、こんにちは。まつもとりーのインフラ入門第九回です。本連載では、主にインターネット基盤技術、または、インターネットのインフラ技術と呼ばれる領域に関して、Webホスティングサービスの歴史やWebサーバの設計と実装を中心に執筆していくと第一回で述べました。

第八回では、高集積マルチテナントアーキテクチャにおいて非常に重要となる権限分離について解説しました。

第九回では、これまでのセキュリティやリソース、性能の観点を踏まえた上で、どのように効率的に運用保守していくかについて、関連研究を踏まえて紹介してきます。

運用技術の課題

Webホスティングサービスを提供する側が、サーバを運用管理する工数は、インターネットの普及に伴い、日々増加してきています。 これまで述べた通り、高集積マルチテナントアーキテクチャにおいては、ApacheのVirtualHost機能を使うことにより効率的にホストの収容数を増やすことができます。 一方で、収容数が増えることにより運用面の課題が生じてきます。 以下の論文では、高集積マルチテナントアーキテクチャにおいて収容数が増えるに従って生じる性能や運用技術の課題についてまとめられています。

松本亮介, 川原将司, 松岡輝夫, 大規模共有型Webバーチャルホスティング基盤のセキュリティと運用技術の改善, 情報処理学会論文誌, Vol.54, No.3, pp.1077-1086, 2013年3月.

suEXEC時のCGIプログラムとインタプリタの紐付けする手法

suEXECを採用するためには、CGI版を利用しなければならず、シェバン行(UNIXで実行されるスクリプトの1行目に、スクリプトを渡すインタプリタを指定するために書く行。#!/bin/shなどと記述される。英語表記はshebang。)の記述や適切な実行権限設定をホスティング利用者に強制する必要があります。 しかし、例えばWebサイトの動的コンテンツの開発に多く採用されるPHPスクリプトのコードにおいては、一般にシェバン行は記述されません。 そのため、シェバン行の記述や実行権限設定はホスティングサービス仕様上の問題となります。

mod_suphpを利用すると、シェバン行の記述や実行権限設定をホスティング利用者に強制する必要なく、suEXECと同様にCGIプログラムをユーザ権限で実行できます。

Sebastian M, suPHP Homepage,
http://www.suphp.org/Home.html.

しかし、suEXECと同様にVirtualHost単位でuid、gidを設定ファイル内で指定する必要があり、mod_vhost_aliasでも動的に扱えません。 また、他ホスト領域への覗き見を防ぐことができますが、セキュリティのエントリで述べた、 システム領域の覗き見問題を解決できていません。

mod_actionsを利用すると、CGI実行方式であっても、スクリプトにシェバン行や実行権限を設定しなくても実行できるラッパープログラムに渡す設定ができます。

The Apache Software Foundation, Apache Module mod_actions,
http://httpd.apache.org/docs/2.0/en/mod/mod_actions.html.

しかし、ラッパープログラムをApacheや各ホストの権限からアクセス可能なディレクトリに安全に配置する必要があり、設定や構成が煩雑になりがちです。 また、ラッパープログラムはURLからアクセスできる領域に配置する必要があり、顧客のURLを一部占有することが問題となる場合もあります。 これまで述べた、システム領域の覗き見問題も解決できません。

松本らは、PHPプログラムに対するリクエスト時は、suEXECプログラム内部でexecve()システムコールを実行し、CGI実行方式用のPHPインタプリタファイルにリクエストされたプログラムパスを引数に渡して実行するように改修した手法を提案しています。

松本亮介, 川原将司, 松岡輝夫, 大規模共有型Webバーチャルホスティング基盤のセキュリティと運用技術の改善, 情報処理学会論文誌, Vol.54, No.3, pp.1077-1086, 2013年3月.

これによって、PHPプログラムのシェバン行や実行権限の有無をサービス利用者が意識することなく、CGI実行方式のPHPプログラムをsuEXECで実行できます。

改修によって、複数のモジュールやラッパー等を組み込む必要がないという点で非常にシンプルな構成になっています。 また、ホスティング利用顧客がDSO版PHPを扱うために、シェバン行を記述しなかったPHPスクリプトに対しても、suEXEC内部でCGI版PHPとして実行されるため、CGI版かDSO版かをホスティング利用顧客が気にする必要がありません。 一方で、PHPプログラムとインタプリタファイルの紐付けをsuEXECで行う必要があるため、PHPのようなシェバン行を通常書かないようなプログラミング言語を提供する場合には、別途ホスティングサービス提供者による紐付けが必要となります。

ホストの新規設定・追加に伴うコスト

リソース管理のエントリで述べたとおり、VirtualHostにおいてはWebサーバプロセスが停止すると、全てのホスト機能が一時的に停止します。 そのため、大規模化に伴う設定の増加を考慮すると、設定に追加あるいは変更があってもできる限りWebサーバプロセスのリロードやリスタートを実施しないようにするべきです。 新規ホストの追加設定やチューニングを行う場合に、Webサーバのリロードを実施しないでよいようにするためには、mod_vhost_aliasを用います。

The Apache Software Foundation, Apache Module mod_vhost_alias,
http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html.

mod_vhost_aliasはApacheモジュールで実装されており、Dynamically Configured Mass Virtual Hosting(DCMVH)という設定記述方法を提供します。 通常、Apacheでは、ホスト追加時に新規ホスト用のVirtualHost設定を追記します。 しかし、仮想ホストの設定はホスト名やドキュメントルート名等が異なるだけで、その他の設定は同じ場合が多いです。 そこで、DCMVHの設定記述法を利用すると、ドキュメントルートにホスト名を含んだパスになるようにディレクトリを作成しておけば、VirtualHostの設定においてパスのホスト名部分を変数で記述することができます。 その記述によって、VirtualHostの設定を1つ書いておけば、アクセスのあったホスト名で設定を動的に読み替え、該当のドキュメントルートにアクセスできるようになります。 また、設定の数がホストの数に依存しないため設定読み込みの負荷も少なくできます。 以下に、通常のVirtualHostの設定を示します.

<VirtualHost *:80>
 DocumentRoot /path/to/vhosts/host1.example.com/
 ServerName host1.example.com
 SuexecUserGroup host1 host1
</VirtualHost>
<VirtualHost *:80>
 DocumentRoot /path/to/vhosts/host2.example.com/
 ServerName host2.example.com
 SuexecUserGroup host2 host2
</VirtualHost>

suEXECを採用するためにはホスト単位でSuexecUserGroupという設定を記述する必要があります。 SuexecUserGroupに設定されたuidとgidが、実行対象のCGIプログラムとオーナが一致するか確認し、その上でCGIを実行する際にsetuid()およびsetgid()システムコールにより、オーナを変更することでセキュリティを高めています。 しかし、 mod_vhost_aliasではsuEXECの設定のuidとgidを動的に扱う記述がないため、VirtualHost単位にuidとgidを静的に記述しなければならなります。 そのため、新規VirtualHostを追加するたびに設定数が増加します。

設定反映にはApacheのリロードが必要であるため、ホスト数の増加と共にリロードによる設定読み込み時間も増加します。 さらに、設定数の増加によってWebサーバプロセスのメモリ使用量が増加し、その状態でCGI実行方式のような、fork()システムコールやexecve()システムコールを伴う処理を行うと、ページテーブルエントリ数が多数存在するため、Copy on Writeによる処置とはいえ、ページテーブルエントリのポインタ複製と削除の処理に起因して処理のコストが高くなり、CPU使用時間を多く消費します。 実際のリアルシステムにおける調査は以下のエントリにまとまっています。

・まつもとりー, 特定条件下のclone(2)を4倍速くする,
https://hb.matsumoto-r.jp/entry/2016/07/14/055215
・まつもとりー, CPU使用率100%のWebサーバをOSのチューニングだけでCPU使用率20%まで改善する,
https://hb.matsumoto-r.jp/entry/2016/07/23/000533

松本らは、各仮想ホストのsuEXECのユーザ名とグループ名を同一のダミーとして設定した上で、suEXECプログラム内部で実行ファイルのオーナ情報からユーザ名とグループ名を解釈できるようにsuEXECを改良し、ホスト単位で権限分離が必要な場合でも、全ての仮想ホストの設定を一つの設定に書き直すことができるようにしています。

松本亮介, 川原将司, 松岡輝夫, 大規模共有型Webバーチャルホスティング基盤のセキュリティと運用技術の改善, 情報処理学会論文誌, Vol.54, No.3, pp.1077-1086, 2013年3月.

以下に、mod_vhost_aliasによる統一的設定例を示す。

VirtualDocumentRoot "/path/to/vhosts/%0"
SuexecUserGroup dummy dummy

また、mod_vhost_aliasでは、環境変数に保存されるドキュメントルートが、本来保存されるべき変数を読み替えたユーザ毎の絶対パスにならない問題があるが、松本らは、ホスティングサービスの利用者が環境変数を使ったプログラムを配置する可能性を考慮し、正しいドキュメントルートで保存されるように、mod_vhost_aliasを改良しています。

リソース管理のエントリで紹介したApacheモジュールは、各ホスト専用の制限設定が書かれたファイルに設定を記述することができ、Apacheのリロードを実行すること無くリクエスト毎に新たな設定を反映させることができます。

まつもとりー, まつもとりーのインフラ入門-第四回「高集積マルチテナントアーキテクチャのリソース分離(1)」, https://pr.forkwell.com/2019-07-30-matsumoto/

その結果、ホスト数に依存した煩雑な設定無く、また、Apacheのリロードをせずに制限の設定や新規に追加するホストの設定を反映させることができ、運用性とサービス性が向上します。

まとめ

ということで、今回は、前回まとめた高集積マルチテナント環境のセキュリティと性能要件に関する関連研究の課題に 基づき、これまでのセキュリティやリソース、性能の観点を踏まえた上で、どのように効率的に運用保守していく かについて、関連研究を踏まえて紹介しました。

次回でも引き続き、運用技術の研究開発について紹介します。

リファレンス
本連載は下記の私が執筆した論文を参考に、新しい読者へ広めるために平易な形へと再編集しています。
・ 松本 亮介, 栗林 健太郎, 岡部 寿男, Webサーバの高集積マルチテナントアーキテクチャと運用技術, 電子情報通信 学会論文誌B, Vol.J101-B, No.1, pp.16-30, Jan 2018.
・ copyright©2018 IEICE

(記事:松本 亮介)

京都大学博士(情報学)、さくらインターネット研究所上級研究員、ペパボ研究所客員研究員、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名に選出される。