仮想的なサーバー

一台のサーバー?それとも複数のサーバー?

もちろん、複数のサーバーで構築した方が、余計な細工をしなくていいので 柔軟性の面では圧倒的に優れている。
問題なのは、

  1. 設置場所
  2. 消費電力
  3. 複数のサーバーを管理する手間

という部分。規模が大きければラックマウントに収納するような薄型(1Uとか2Uの) の機械を積み重ねたり、ブレードサーバー(一つの筐体に、サーバー機能をもつカードを 何枚も挿すもの)で構成するのだろうが、それは、あったとしても、かなり先の話だろう。

最近は、外付けハードディスク並の大きさで、サーバーにもなる機械が 3万円程度で売られているので、中規模程度までなら、これを使って構成するのが よいのではないかと思っている。

1IPで構築する場合には、一台はporxy専用として、外からの要求をそれぞれの サーバーに振り分けることだけに使用するのがわかりやすい。

構成概念図

1台のサーバーで構成する場合

1台のサーバーで構成する場合には、残りの複数のサーバーの担っている 役割を仮想的にこの1台の機械に集約させる必要が発生する。

コンピュータそのものを仮想化してしまうもの
Virtual PCや、VMwareと呼ばれる製品がこのタイプのものです。
仮想化しようとするコンピュータの必要とするメモリーの総和分のメモリを 必要とするので、数台のコンピュータを仮想化しようとするとすぐに1GBクラス のメモリが必要となります。2GBを超えるメモリを扱える機械は現時点では かなり特殊用途向けであることを考えると、これはちょっと採用しにくい。
OS呼び出しレベルで仮想化するもの
仮想化されたコンピュータ内からのOS呼び出しを、ホストOSのOS呼び出しに 変換することによって、実現するもの。
UML(user mode linux)などがこれにあたる。
アクセス可能な資源の範囲を制限するもの
OS(カーネル)そのものは共通のものを使いながら、 アクセスできる範囲を制限・仮想化することによって、 仮想化されたサーバーの独立性を実現するもの
FreeBSDのjail環境や、LinuxのVServerなどがこれにあたる。
アプリケーションレベルで仮想化するもの
apache(WEBサーバー)の仮想ホスト機能などがこれに該当する
他に、proxyを利用するものや、アプリケーションの性質上自動的に proxyの機能が備わっているものもある

実行効率、リソースの消費量などは、下にいくほど効率がよいが、 そのぶん仮想化されたドメイン同士の独立性が下がってくる。
一人のスーパーユーザーが何でもこなすのであれば、下が有利。逆に、 それぞれのドメインの管理者に自由な権限を与えたいなら上が有利。

ほとんどの共用WEBサーバーはアプリケーションレベルの仮想化で提供されている

いいかえると、システムにかかわる変更をしたければ、スーパーユーザーに お願いしなくてはいけない。 仮想化されたドメイン同士は、実機上では同じ空間上で動作しているので セキュリティを保つためにはファイル転送以外の権限がほとんど与えられない ことが多い。

ある程度、性善説をとらないと採用しにくいモデルだ

ちなみに、保土ヶ谷教会が利用しているINETS.JPの共用WEBサーバーでは、 ファイル転送やログインこそ制限されているものの、CGIが自由に使えるので、 他の契約者のWEBデータを比較的簡単に読み出すことができる。

名前空間の衝突

メールの受信(POPやIMAP)を仮想化しようとすれば

POPやIMAPを仮想化しようと思ったら、ユーザーアカウントには ユーザー名だけでなく、ドメイン名まで含めて定義しなくてはいけない。

Cyrus imapサーバーには、Realmという機能を使って、ドメイン名まで 含めた形で POPやIMAPサービスを実現することができる。

各仮想マシンが実現されているのであれば、delegateというproxyソフトウェアを 使えば、ドメイン名付のユーザーアカウントの認証を、それぞれの仮想マシンの 対応する認証に振り分けることができる。

メールの送信は標準的なものでよい

もちろん、仮想化されたそれぞれの空間で独立に sendmailを動かしても よいのだが、sendmailは最初から複数のドメイン間のメールを転送する ことができる

IPアドレスは1個、それとも8個?

扱うドメインの数が、十数個までなら IPアドレスは1つでよい。

もちろん原理的にはドメインの数が10個だろうが100個だろうが IPアドレス1個でもやりくりはできるけれども、10Gの空間を各 仮想サーバーに割り当てれば、100個では1Tバイトのハードディスクが 必要になるし、仮想サーバー1台あたりのデータ転送量が10MB/日でも 100台分なら1GB/日になる。その規模ならそれなりのバックボーンに 費用をかけてもいいだろうというだけのことだ。

いくら仮想化して、それぞれの仮想サーバーに別々のIPアドレスを 割り当てるとはいえ、所詮は仮想なわけで外部から見えるIPアドレス の数が増えるわけではない。
IPアドレスが多ければ、実際のIPアドレスを、それぞれの仮想サーバーに 割り当てればよいので話は単純だが、コストもかかるので、 以下では1IPの場合だけを検討することにする。

IPアドレスが一つで、それぞれの仮想サーバーが共通のポート番号で サービスを提供するわけだから、特定のポートにやってきたリクエストを それぞれの仮想サーバーに振り分ける仕組みがどうしても必要になる。
メールを例にとれば、実サーバーであれば、アカウント名部分に、ユーザー名 だけを入力していればよかった部分で、ユーザー名+ドメイン名を 入力しなくてはいけなくなる。

この振り分けに proxy ソフトウェアを使う方法と、アプリケーションレベルでの 仮想ホスト機能を使うのと二通りの選択肢がまだ残る。

バランスを考えれば、jail(FreeBSD)か UML(linux)が妥当か?

jailもUMLも、仮想化されたそれぞれの空間が完全に独立している わけではないが、通常の使い方の範囲では十分独立している。
悪意をもって操作すれば別だが、通常の使用法の範囲で 間違って別の仮想空間にアクセスしてしまうということはない。

最近のハードディスクの大容量化を考えれば、仮想空間ごとに重複して ファイルを持つことのオーバーヘッドは無視してよい。

jailでsendmailのlisten portを指定するには、DAEMON_OPTIONS で指定する DaemonPortOptionsを参照せよ。