SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

VM Role で Azure Drive を使用する際の注意点

leave a comment

以前、VM Role でデータを永続化する方法として以下の 3 つの投稿をしました。

VM Role で Windows Azure Drive を使用
VM Role 起動時に Windows Azure Drive を自動でマウント
同一スクリプトで VM Role のインスタンス毎に異なる領域をマウント

これらの投稿の内容を使用して、タスクスケジューラーでインスタンスの起動時に Power Shell を実行して Azure Drive を VM Role のデータ永続化先として利用できるようにしていました。

Azure Drive をマウントした状態を続けていたらあるタイミングでアンマウントされていましたので、今回の投稿ではその原因を注意点としてまとめたいと思います。


■アンマウントされるタイミングとエラーの内容


マウントした Azure Drive ですが、ある程度の時間が経過するとイベントビューアーに以下のエラーが出力され、アンマウントされます。
image

ログの名前:         System
ソース:           WaDrivePrt
日付:            2011/02/11 13:12:27
イベント ID:       4
タスクのカテゴリ:      なし
レベル:           エラー
キーワード:         クラシック
ユーザー:          N/A
コンピューター:       WIN-AVN4II16Q56
説明:
‘/VMRole1_IN_0.vhd’ failed to renew lease the specified XDisk.
イベント XML:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="WaDrivePrt" />
    <EventID Qualifiers="49158">4</EventID>
    <Level>2</Level>
    <Task>0</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2011-02-11T04:12:27.932698400Z" />
    <EventRecordID>4951</EventRecordID>
    <Channel>System</Channel>
    <Computer>WIN-AVN4II16Q56</Computer>
    <Security />
  </System>
  <EventData>
    <Data>
    </Data>
    <Data>/VMRole1_IN_0.vhd</Data>
    <Binary>
000040000200680000000000040006C000000000100000C000000000000000000000000000
000000CC92EC0080F8FFFF00000000000000000400000000000000000000000000000000000
000000000000030C601000000000010000000000000930100000300FFFF
</Binary>
  </EventData>
</Event>

このエラーですが、マウントをしてから 30 分ほど経過すると発生していたようでした。

このタイミングを元に情報を探してみたところ以下の技術情報が見つかりました。
Drive letter for a cloud drive becomes invalid after awhile
CloudDrive.InitializeCache is failing with 1.3
Mounting Azure Drive in Azure Virtual Machine (VM) Role
Windows Azure ドライブ – NTFS – Microsoft Corporation
# Techy Freak さんは VM Role の有益を情報をかなり公開してくださっています。

この技術情報の中に以下の記述があります。

When you mount a Windows Azure Drive, a thread is created in your process to maintain the temporary signature the drive uses to authenticate with Windows Azure Storage.  If your process exits, this thread is destroyed and your drive will be unmounted in about 30 minutes because the authentication stops working.  I’m guessing this is what is happening.  The workaround is to call Mount() every time you need the drive.  If the drive is already mounted, Mount() will return very quickly with the current drive letter.

SAS (Shared Access Signature) を使用した場合は挙動が変わるようなのですが、ドライブを使用する際に SAS-URI を使用していない場合は、マウントをしたプロセスが終了すると 30 分程度でマウントが解除されてしまうようです。

今回はタスクスケジューラーで PowerShell を実行していました。
image

動作としては上図の動きとなりますため、マウントが終わったらマウントに使用していたプロセスが終了します。
そのため、マウント後 30 分で Azure Drive がアンマウントされてしまいます。

 

■アンマウントされないようにするためには


Shared Access Signature を使用するとプロセスが終了してからも 30 分以上マウントすることが可能になるようなのですが、その実装を試そうとすると時間がかかりそうですので、プロセスを終了させない方法で実装をしたいと思います。
# SharedAccessExpiryTime がどれくらいまで伸ばせるのかも検討しないといけないと思うのですが。

タスクスケジューラーで実行した場合、指定したタスクの実行が完了するとプロセスが終了されます。
コマンドプロンプトのバッチであれば、[PAUSE] を使用することで、キー入力要求を発生させ、バッチを終了させないことが可能です。
PowerShell の場合は、[$host.UI.RawUI.ReadKey()] で PAUSE 相当の動作をすることができます。
以前作成した PowerShell の最後に太字下線の行を追加します。

# 必要となるアセンブリの参照
Add-Type -Path "C:Program FilesWindows Azure Integration Componentsv1.3refMicrosoft.WindowsAzure.StorageClient.dll"
Add-Type -Path "C:Program FilesWindows Azure Integration Componentsv1.3refMicrosoft.WindowsAzure.CloudDrive.dll"
Add-Type -Path "C:Program FilesWindows Azure Integration Componentsv1.3refMicrosoft.WindowsAzure.ServiceRuntime.dll"

# サービスの起動が完了するまで待機
while((Get-Service -Name "Windows Azure Cloud Drive Provider").Status -ne "Running"){
    Start-Sleep -s 10
}

while((Get-Service -Name "Windows Azure Integration Components").Status -ne "Running"){
    Start-Sleep -s 10
}

while((Get-Service -Name "Windows Azure Remote Forwader Service").Status -ne "Running"){
    Start-Sleep -s 10
}

# Azure Storag に接続するための接続文字列をサービスモデルで定義した設定から取得
$connection = [Microsoft.WindowsAzure.CloudStorageAccount]::Parse([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetConfigurationSettingValue("StorageConnectionString"))
while (!$?) {
    $connection = [Microsoft.WindowsAzure.CloudStorageAccount]::Parse([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetConfigurationSettingValue("StorageConnectionString"))
}

# Azure Storage に接続
$account = New-Object Microsoft.WindowsAzure.CloudStorageAccount( $connection.Credentials, $false)

# ローカルストレージに Azure Drive 用のキャッシュディレクトリを作成
# GetLocalResource で指定しているのは、サービス定義ファイル (csdef) で指定した LocalStorage の設定値
$localstorage = [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetLocalResource("AzureLocalStorage")
[Microsoft.WindowsAzure.StorageClient.CloudDrive]::InitializeCache($localstorage.RootPath + "cache", $localstorage.MaximumSizeInMegabytes)

# Azure Drive として、VHD をマウント
$clouddrive = [Microsoft.WindowsAzure.StorageClient.CloudStorageAccountCloudDriveExtensions]::CreateCloudDrive($account, "$($account.BlobEndpoint)persistent/$([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id).vhd")
$driveletter = $clouddrive.Mount(100, [Microsoft.WindowsAzure.StorageClient.DriveMountOptions]::None)

# プロセスを維持するためキー入力要求を発生
$host.UI.RawUI.ReadKey()

タスクスケジューラーでは実行したタスクは基本的に非対話形式で処理がされますので、キー入力要求が発生するとタスクが実行され続けた状態となります。

デフォルトの設定ですと、タスクスケジューラーのタスクは [3 日間] で停止されてしまいますので、この辺の設定は無効にしておいた方が良いかと思います。
image

これで、以前作成した Azure Drive をマウントするスクリプトを使用して 30 分以上マウントをした状態にすることが可能となります。

タスク スケジューラでタスクが実行され続けた状態となり、
image

タスク マネージャーからもタスクスケジューラーで実行した [powershell.exe] が実行され続けた状態となります。
image

この方法であれば、マウントしたプロセスは終了しない状態となりますので PowerShell でマウントした Azure Drive のドライブが 30 分経過してもマウントされ続けます。

 

■VM Role Adapter について


今回は PowerShell で Pause して Azure Drive のマウント状態を保持してみましたが、VM Role には VM Role Adapter という方法があります。
Developing the VM Role Adapter
Startup Tasks in Azure Virtual Machine (VM ) Role
Mounting Azure Drive in Azure Virtual Machine (VM) Role

VM Role Adapter ですが、いろいろと調べてみたところ通常に Windows サービスと同じみたいですね…。

サービスとして、Management API や、ローカルストレージ等を使用するプログラムを組み込んで、起動させることで VM Role Adapter として使用するようです。。

サービスとして Azure Drive をマウントするプログラムを起動することで、サービスを停止するまではマウントをしたプロセスが終了されませんので、Azure Drive をマウントしたままにすることができるようになります。

PowerShell で実行していた時と同様に各サービスの起動状況や、Management API が使用できるようになるまでのリトライ等は実装する必要があるかと思いますが。

前から、VM Role を起動したままにしていると、気付いたらマウントが解除されていたのが気になったので調べてみたのですがいろいろと勉強になりました。
最初はマウントのスクリプトがうまく動いていないのかと思ったのですが、アンマウントされていたみたいですね。

Shared Access Signature についても勉強しないと…。。

Written by masayuki.ozawa

2月 11th, 2011 at 3:18 pm

Posted in Windows Azure

Tagged with ,

Leave a Reply

*