Windows Azure コンピュートサービスについて
最近、Windows Azureを使う機会が多いので、気が付いたことを色々と記載していきます。基本的なこととして、1)コンピュートサービス、2)ストレージサービス、3)SQL Azure、4)ACSやサービスバスなどのAppFabricというサービスに分かれているのはご存知だと思います。その中でコンピュートサービスを中心にすると、仮想マシンの役割によって1)Webロール、2)Workerロール、3)VMロール(現時点ではCTP)の3種類になります。が、それぞれの仮想マシンの特徴を一言で表現すれば、ステートレス サーバーということができます。つまり、仮想マシンの再起動や再イメージ化によってローカルストレージのデータが失われるということです。メリットは、問題があったインスタンスを破棄して、新しいインスタンスを容易に作成できるということになります。実際の仮想マシンのローカルリソースがどうなっているかを確認したのが、以下の図になります。
この図は、Webロールにリモートデスクトップで接続してキャプチャしたものです。この図から解ることは、以下のようなドライブ構成になっていることです。
- Cドライブ:ローカルリソース用(ログなど)。
- Dドライブ:OS用。
- Eドライブ:ロールのアプリケーション用で、%RoleRoot%が示すドライブです。
%RoleRoot%環境変数は、ドライブレターを保持する変数ですから、この例では「E:」となります。実際のロールのアプリケーションは、approotフォルダーに格納されますが、このフォルダーの構造が、WebロールとWorkerロールで少しだけ異なっています。具体的には以下のようになります。
- Webロール:Binサブフォルダーにロール用のアセンブリが格納されて、approot直下にWebアプリのファイルやコンテンツが格納されます。
- Workerロール:approot直下にロール用のアセンブリが格納されます。
この違いは、StartTaskを指定する場合に重要になります。StartTaskのデフォルトパスは、WebロールではBinサブフォルダを示し、Workerロールではapproot直下を示すからです。この理由から、Visual Stduioのプロジェクトでは、StartTaskに指定するモジュールを出力先ディレクトリーへコピーと設定することをお勧めします。
次に仮想マシンが動作している権限について、以下に示します。
ASP.NETアプリ:Network Serviceアカウント。
ロールインスタンス:標準は権限の少ない特殊なアカウントで、executionContextでElevatedを指定した場合はSystemアカウントとなります。
仮想マシンのサイズによって利用できるローカルストレージは、Cドライブに確保されますが、指定した容量による制限が課せられます。このローカルストレージに指定したフォルダーに対するACLは、ロール用の特殊なアカウントとNetwork Serviceアカウントがフル アクセスに近い権限が設定されます。しかし、サブフォルダなどに対する権限の継承が設定されていませんので、普通のファイルシステムとして使用する場合は、適切なACLの設定を自分で行う必要があります。
DirectoryInfo dirInfo = new DirectoryInfo(folder);
DirectorySecurity dirSec = dirInfo.GetAccessControl();
dirSec.AddAccessRule(
new FileSystemAccessRule("NETWORK SERVICE",
FileSystemRights.FullControl,
InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow));
dirInfo.SetAccessControl(dirSec);
と行うか、icacls.exeを使って、(OI)(CI)(F)の権限を設定します。
権限設定を行う場合ですが、データが存在するフォルダーに対して行うと時間がかかるので注意が必要だということと、アクセスする必要があるアカウントに対して設定する必要があります。前述の例では、Network Serviceで設定していますが、Elavatedの場合であればSystemに対しても設定する必要があります。
それとWebロールを使う上で仕様になっているのが、テンポラリーのサイズ制限が100MBになっていることです。この制限を変更するには、ローカルリソースを使ってロールのスタートイベントやStartTaskなどで適切に変更する必要があります。後は、ローカルリソースを使った場合に問題になるのは、パスの長さかも知れません。パスの長さが問題になる場合は、mklinkコマンドを使ってシンボリックリンクを短いパスとして設定する方法が考えられます。