浅草橋青空市場

Microsoft Azure のニュースや情報を中心にあれこれと

AzureのストレージサービスをExcel方眼紙職人的にまとめてみる

随所で分かりづらいという声を耳にしますし、料金表の記載がまたテクノロジーとは別の切り口なのが分かりづらさに拍車をかけている気もしますね。

料金 - Cloud Storage | Microsoft Azure

ということで、ある種の割り切りの下でExcel方眼紙職人的にまとめてみました。

f:id:yhara90:20160722020255p:plain

基本的には料金表ページそのままなんですが、まとめてみると、BLOBストレージアカウントの存在で「?」となりがちなのと、BLOB Storage にページBLOBがあるのに「Disk Storage」がまた出てくるあたりが違和感の源でしょうか。 File Storage あたりも微妙なところですが、これは用途がはっきりしているのでまだ大丈夫かなと。

料金と用途の観点からは分かり易くなってきたと思いますが、いざ使ってみようという時に、ポータルの表記だったり実装の階層構造だったりが一致しないのでまたちょっと混乱するんですよね。

AzureクラシックVMからARMへのマイグレーションにおける注意点

以前の記事では無停止で綺麗に移行できるケースを紹介しましたが、少なくとも現時点で完璧なツールというわけでもなく、いくつかの注意点があります。 ということで、今回は公式ドキュメントから注意点をいくつか拾っていきたいと思います。 経験上から「引っかかりそうだな-」というところを抜粋していますので、こちらで雰囲気を掴んだら、ドキュメントの方も読んでみて下さいね。

ベースはこちら。

azure.microsoft.com

仮想ネットワークに含まれないVMマイグレーション

  • ARMモデルのVMは必ずVNETに所属する必要があるということから、マイグレーションの際に停止・起動が発生します。
  • 具体的に書かれていない気がしますが、試した限りでは「Prepare」時にシャットダウンまで行われ(割り当て解除済み状態)、「Commit」完了後に起動されます。

仮想ネットワークに含まれるVMマイグレーション

  • ストレージアカウントに関する制限
    • ARMモデルではVMイメージとVMディスクはサポートされません。
    • ドキュメントには「will not be visible」だけど「backing VHDs will remain in the storage account」とありますが、少なくともVMイメージが残った状態でストレージアカウントのマイグレーションをかけると、「Ensure these VM Images are removed before deleting this storage account.」とエラーが出てしまいました。

「Unsupported features」からの抜粋

  • ネットワーク関連が厄介そうです
    • クラウドサービスやVMに割り当てていない予約IPアドレス マイグレーションに使うコマンドの対象がVNETかクラウドサービスなので、まあ当然というか、割り当てておかなければASMに残されるということになります。マイグレーション後に再利用予定のあるIPアドレスであれば、とりあえずでもいいので割り当ててから持っていきましょうということですね。
    • エンドポイントのACLも対象外です (Prepareの段階でエラーが出ます)。暗黙のロードバランサーはARMの明示的なリソースとしてのロードバランサーに移行され、エンドポイントは受信NAT規則に置き換えられますが、受信NAT規則にはACLが存在しないため、必然的に移行対象外となる、ということですね(NSGを作ってくれても良さそうな気はしますが)。
    • VNETのGateway(サイト対サイト、ExpressRoute、ポイント対サイト)もサポート外 とのこと。これは結構つらいですね…

「Unsupported configurations」からの抜粋

  • クラシックリソースに対するRBAC。 これもリソースのURIが変更になるためある意味仕方が無いですね。移行後に手動で再設定する必要があります。
  • 複数サブネットに接続されたVM これは困るケースも多そうです。
  • Web/Workerロールを含むクラウドサービスやVNET。そりゃそうなんですが、ちょっと惜しいですね。同様に、App Service Environment や HDInsight を含むVNETもサポート対象外とのこと。

移行のワークフローにおける注意点

  • まず基本として、移行は「Prepare」→「Check」→「Commit / Abort」の流れで行います。
  • Prepareはコマンド、Checkは人手による確認、Commit / Abort はコマンドで行います。
  • サポート対象外の構成が存在した場合は「Prepare」の工程でエラーが出ます。試した限りでは自動的に削除されるものは無さそうなので、それなりに配慮されているようです。
  • Prepareが成功してからCommitもしくはAbortが完了するまでは、管理系の操作がブロックされます。試しにPrepareしたあとのVMに対して、キャプチャやエンドポイントの構成などをポータルから行ったところ、「HostedService xxxx 内の展開 xxxx は、移行処理中であるため変更できません。」というエラーが出ました。台数によっては数時間かかる場合もあるようなので、その辺の考慮も必要になりそうです。
  • クオータにも注意。ARMはARMのクオータがあるので、必要に応じてあらかじめ増やしておきましょう。移行中にクオータ制限にかかった場合はrollbackしましょうと書いてありますね。

AzureのクラシックVMからARMへのマイグレーション機能がGAしてました

記事が出たり引っ込んだりしてたみたいですが、ちゃんと上半期中にGAしたみたいですね。 首を長く長く伸ばしながら待っていてどうにかなりそうなところでした。

▼General availability of IaaS migration from classic to resource manager | ブログ | Microsoft Azure

azure.microsoft.com

手組のスクリプトで引っ越すことと比べて、ダウンタイム無しで移行できるのが最大のメリットですかね。

リンク先のドキュメントも、「Updated:」の日付は古いですが、内容は最新化されています(英語版のみ)。 PowerShell, Azure CLI の両方ともちゃんと更新されていましたので安心ですね。

マイグレーションできるもの、出来ないものがありますので、こちらのページから事前によく確認して移行計画を検討しましょう。

https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-migration-classic-resource-manager/

[(追記) 補足記事を書きました: 2016/7/5]

asazure.hatenablog.jp

<主なポイント>

  • IPアドレスDNS名(クラウドサービスのURL)はそのまま引き継がれます。
  • GAのタイミングでストレージアカウントのマイグレーションに対応しました。
  • VMとVNETだけARMに移してVHDはクラシックのストレージアカウントに残していくこともできます(v2VMからクラシックのストレージアカウントに繋がるようにしたみたいですね)。
  • 移行後は「<cloud-service-name>-migrated」というリソースグループが新たに作られます。
  • 「mycloudservice」であれば「mycloudservice-migrated」ですね。
  • ただし、DNS名はそのまま移行されますので、「mycloudservice.cloudapp.net」となります。
  • クラウドサービスに付いていた暗黙のロードバランサーはARMのロードバランサーが明示的に作成され、エンドポイントは受信NAT規則に置き換えられます。ただし、エンドポイントACLは引き継がれないということなので、NSGは手作業を作ることになりそうです。
  • クラシックVMのイメージとディスクはARMのストレージアカウントにマイグレーションできないのであらかじめ削除して下さい。
  • VNETもマイグレーションされるので、旧ポータルで作って暗黙のリソースグループが割り当てられているVNETは、やっぱり別リソースグループのままマイグレーションされます(ので、もともと長い暗黙のリソースグループ名に-migrated」が付けられて更に長く)。

さて、ここから移行作業です。 といってもコマンド自体はいたってシンプルで、このあたりに書いてあるとおりです。 この記事ではPowerShellで書いていきますが、CLIでも同じような手順です。

Migrate IaaS resources from classic to Azure Resource Manager by using Azure PowerShell | Microsoft Azure

Migrate IaaS resources from classic to Azure Resource Manager by using Azure CLI | Microsoft Azure

事前準備

アカウントにログインし、マイグレーションリソースプロバイダーを登録します。

# ARMのアカウントにログイン
Login-AzureRmAccount
# ARMのサブスクリプションを選択
Select-AzureRmSubscription -SubscriptionId [サブスクリプションID]
# マイグレーションリソースプロバイダーを登録する
Register-AzureRmResourceProvider -ProviderNamespace Microsoft.ClassicInfrastructureMigrate
# ASMのアカウントにログイン
Add-AzureAccount
# ASMのサブスクリプションを選択
Select-AzureSubscription -SubscriptionId [サブスクリプションID]

移行作業(VNETに接続している仮想マシンの場合)

この場合、VNETをまるっと移行させるイメージになります。実質2行のスクリプト。エラーが出たらロールバック出来ます。

# VNETを指定して移行準備
Move-AzureVirtualNetwork -Prepare -VirtualNetworkName [VNET名]
# エラーが出なければコミット
Move-AzureVirtualNetwork -Commit -VirtualNetworkName [VNET名]

# prepareでエラーが出た場合はロールバック
Move-AzureVirtualNetwork -Abort -VirtualNetworkName [VNET名]

移行作業(VNETに接続していない仮想マシンの場合)

この場合は、クラウドサービスを指定して移行させるイメージになります。 また、ARMのVMはVNET必須なので、VNETを新規に自動作成して移行するか、ARMに既存のVNETに移行するということになります。

▼新規にVNETを作って移行する場合

$serviceName = "[クラウドサービス名]"
$deploymentName = (Get-AzureDeployment -ServiceName $serviceName).DeploymentName
# 移行準備
Move-AzureService -Prepare -ServiceName $serviceName -DeploymentName $deploymentName -CreateNewVirtualNetwork
# エラーが出なければコミット
Move-AzureService -Commit -ServiceName $serviceName -DeploymentName $deploymentName

# prepareでエラーが出た場合はロールバック
Move-AzureService -Abort -ServiceName $serviceName -DeploymentName $deploymentName

▼ARM環境に既存のVNETに移行する場合

$serviceName = "[クラウドサービス名]"
$deploymentName = (Get-AzureDeployment -ServiceName $serviceName).DeploymentName
# 移行準備
Move-AzureService -Prepare -ServiceName $serviceName -DeploymentName $deploymentName -UseExistingVirtualNetwork -VirtualNetworkResourceGroupName "[既存VNETのリソースグループ名]" -VirtualNetworkName "[VNET名]" -SubnetName "[サブネット名]"
# エラーが出なければコミット
Move-AzureService -Commit -ServiceName $serviceName -DeploymentName $deploymentName

# prepareでエラーが出た場合はロールバック
Move-AzureService -Abort -ServiceName $serviceName -DeploymentName $deploymentName

マイグレーション状況の確認

(Get-AzureVM -ServiceName "[クラウドサービス名]" -Name "[VM名]").VM.MigrationState

ストレージアカウントのマイグレーション

ストレージアカウントだけクラシックのままで構わない、とか事情があって移行できない、という場合にはこの手順は不要です。今回、ARMのVMからクラシックのストレージアカウントにあるVHDに接続できるようになったみたいですね。 マイグレーションにあたって、VMのイメージやディスクはARMに移行できませんので、あらかじめ削除しておかないとエラーが出ます。 あと、同じストレージアカウントに、ASMのVMが載っていてもエラーになりますので、先にVMを全て移行しておきましょう。

$storageAccountName = "[ストレージアカウント名]"
# 事前準備
Move-AzureStorageAccount -Prepare -StorageAccountName $storageAccountName
# エラーが出なければコミット
Move-AzureStorageAccount -Commit -StorageAccountName $storageAccountName

# prepareでエラーが出た場合はロールバック
Move-AzureStorageAccount -Abort -StorageAccountName $storageAccountName

手順はここまでです。 基本的に prepare → commit と繰り返すだけなので作業そのものは簡単ですね。 制約事項を事前によく確認して移行計画をきちんと考えておけば、さほど困るところは無いかと思います。 検証中に「Internal Error」が1回出ましたが、再実行で解決できました。逆ににっちもさっちもという状態になった場合はサポートに頼るしか無いかもしれません。

ネットワークセキュリティグループ(NSG)をPowerShellからまとめて設定する

Azure 仮想マシンのアクセス制限にネットワークセキュリティグループを設定することが多いと思います。 ポータルからも設定出来るのですが、ルールの更新中(プログレスバーが動いている間)に次のルールを登録することが出来ないため、結構面倒で時間もかかってしまいます。

とういことで、数が多いときはPowerShellでまとめて登録してしまいましょう。

# ログイン及びサブスクリプションの選択
Login-AzureRmAccount
$subscriptionId = (Get-AzureRmSubscription | Out-GridView -PassThru).SubscriptionId 
Select-AzureRmSubscription -SubscriptionId $subscriptionId

# ネットワークセキュリティグループを新規に作成する
New-AzureRmNetworkSecurityGroup -Location [ロケーション] -Name [NSG名] -ResourceGroupName [リソースグループ名]

# 変更するネットワークセキュリティグループを取得
$nsg = Get-AzureRmNetworkSecurityGroup -Name [NSG名] -ResourceGroupName [リソースグループ名]

# ルールを指定

# VNET内の通信を許可する
$rule = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg -Name 'localnet' -Access Allow -Protocol * -Direction Inbound -Priority 110 -SourceAddressPrefix VirtualNetwork -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange *

# 外部からの通信は、指定したIPアドレス(レンジ)のみ接続する。
$rule = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg -Name 'ssh' -Access Allow -Protocol * -Direction Inbound -Priority 210 -SourceAddressPrefix [IPアドレス(CIDR)] -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 22
$rule = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg -Name 'http' -Access Allow -Protocol * -Direction Inbound -Priority 220 -SourceAddressPrefix [IPアドレス(CIDR)] -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 80
$rule = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg -Name 'https' -Access Allow -Protocol * -Direction Inbound -Priority 230 -SourceAddressPrefix [IPアドレス(CIDR)] -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 443

# ルールをNSGに反映する
Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $rule

「-SourceAddressPrefix」は、タグで指定することが出来るようです。 * Internet * VirtualNetwork * AzureLoadBalancer のいずれかがビルドインで指定できるようです。

登録できるルールの数は、セキュリティグループ当たり200個までとのことなので、IPアドレスを範囲で指定するなどして、ルールが増えすぎないように注意ですね。

Azure仮想マシンのパブリックIPアドレスに独自の逆引きFQDNを設定する

Azureの仮想マシンなどに固定のIPアドレスを割り当て(予約)していて、独自の逆引きFQDNを設定したくなったので調べてみました。 ASMの場合はクラウドサービスに対して設定、ARMの場合はパブリックIPアドレスリソースの属性を設定、となるようです。

固定IPアドレスじゃなかったり、正引きが登録されていなかったりするとエラーになるかと思います。

サービスマネージャー(ASM)の場合はこちら。

# 逆引きを設定する
Set-AzureService -ServiceName [(クラウドサービスの)サービス名]  -ReverseDnsFqdn '[設定したいFQDN]'

# 逆引きを削除する
Set-AzureService -ServiceName [(クラウドサービスの)サービス名] -ReverseDnsFqdn ''

リソースマネージャー(ARM)の場合はこんな感じです。

# 逆引きを設定する
$pip = Get-AzureRmPublicIpAddress -Name [パブリックIPアドレス名] -ResourceGroupName [リソースグループ名]
$pip.DnsSettings.ReverseFqdn = '[設定したいFQDN].'
Set-AzureRmPublicIpAddress -PublicIpAddress $pip

# 逆引きを削除する
$pip = Get-AzureRmPublicIpAddress -Name [パブリックIPアドレス名] -ResourceGroupName [リソースグループ名]
$pip.DnsSettings.ReverseFqdn = ''
Set-AzureRmPublicIpAddress -PublicIpAddress $pip

ARMの場合、Azure Resource Explorer から publicIpAddresses リソースを直接書き換えても構わないとは思いますが未検証です。

何か問題があると以下のようなエラーが出ますので、いろいろと見直してみて下さい。

ReverseFqdn [FQDN名] that PublicIPAddress [IPアドレス名] is trying to use does not belong to subscription [サブスクリプションID].
One of the following conditions need to be met to establish ownership:

1) ReverseFqdn matches fqdn of any public ip resource under the subscription;
2) ReverseFqdn resolves to the fqdn (through CName records chain) of any public ip resource under the subcription;
3) It resolves to the ip address (through CName and A records chain) of a static public ip resource under the subscription.

Azure仮想マシンでUnixBenchを取ってみた

わりと微妙なベンチマークが身内で話題になっていたので、せっかくなので実測してみました。 1コアのインスタンスでUnixBenchを走らせてみた結果です。 OSは Ubuntu Server 14.04 LTS です。

テスト項目 Standard_A1 Standard_DS1 Standard_DS1v2
Dhrystone 2 using register variables 1224.4 2047.9 2752.8
Double-Precision Whetstone 312.4 521.4 763.4
Execl Throughput 535.4 898.9 1448.1
File Copy 1024 bufsize 2000 maxblocks 1215.2 2071 3084.7
File Copy 256 bufsize 500 maxblocks 802.1 1335.3 1951
File Copy 4096 bufsize 8000 maxblocks 2107.6 3948.9 6319.2
Pipe Throughput 671.9 1112.8 1680.3
Pipe-based Context Switching 403.4 615 914.1
Process Creation 512.9 848.2 1399
Shell Scripts (1 concurrent) 923.3 1566.8 2420
Shell Scripts (8 concurrent) 874.4 1457.4 2239.1
System Call Overhead 1210.1 2114.3 2930.2
System Benchmarks Index Score: 787.8 1325.4 1993.9

一応書いておくと、各インスタンスのスペックはこんな感じです。売り文句より実測値の方がちょっと速めですね。

  • A1・・・1コア、1.75GBメモリ
  • DS1・・・1コア、3GBメモリ(Aシリーズより60%早いのが売り)
  • DS1v2・・・1コア、3GBメモリ(Dシリーズより35%早いのが売り)

DSのv2シリーズ、早く日本に来ませんかねー。Dシリーズより早い上に安いんですよね。

Azure PowerShellで仮想マシンV2を作成する (SysprepしたVHDから)

qiita.com

という記事を読みましたので、Sysprepした方のVHDからv2仮想マシンを生成するPowerShellスクリプトも置いておきます。

VM本体を構成するだけのスクリプトなので、各種コンポーネントはあらかじめ作っておいて下さい。 以下のものがあらかじめ用意されている前提のスクリプトになっています。 * リソースグループ * ストレージアカウント * 仮想ネットワークとサブネット * NIC * 可用性セット * (必要に応じて)ロードバランサーとパブリックIPアドレス * Sysprep されたVHDファイル

特殊化VHD(Sysprepしていない)との大きく違うところは、置いてあるVHDをそのまま仮想マシンに接続するのではないというところでしょうか。 「-VhdUri」で指定したところに新たなVHDファイルが作られます。

# Azureアカウントへログイン
Login-AzureRmAccount

# サブスクリプションの指定
$SubscriptionId = '[Subscription ID]'
Get-AzureRmSubscription -SubscriptionId $SubscriptionId | Select-AzureRmSubscription

# リソースグループの指定
$ResourceGroupName = '[Resource Group Name]'

# OSディスク情報の指定(Syspreped / Generalized VHDから生成する場合)
$StorageAccountName = '[Storage Account Name]'
$Caching = '[Disk Cache Mode]'
$CreateOption = 'fromimage'
$osDiskSourceImageUri = '[Source VHD Uri]'
$vhdUri = "[OS Disk VHD Uri]"

# 仮想マシンの構成情報
$vmName = '[VM Name]'
$vmSize = '[VM Size]'
$cred = Get-Credential
$Location = (Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $ResourceGroupName).Location

# 可用性セットの構成情報
$AvailabilitySetName = '[Availability Set Name]'
$vmAs = Get-AzureRmAvailabilitySet -ResourceGroupName $ResourceGroupName -Name $AvailabilitySetName

# NICの指定
$NicName = '[NIC Name]'
$nic = Get-AzureRmNetworkInterface -Name $NicName -ResourceGroupName $ResourceGroupName

# VM構成情報の組立
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $vmAs.Id
$vm = Set-AzureRmVMOperatingSystem -ComputerName $vmName -Credential $cred -VM $vm -Windows
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.id
$vm = Set-AzureRmVMOSDisk -VM $vm -SourceImageUri $osDiskSourceImageUri -VhdUri $vhdUri -Name $vmName -CreateOption $CreateOption -Caching $Caching -Windows

# VMのデプロイ
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $vm

ちなみに、Sysprepしてない手順でSysprepしたVHDから仮想マシンを作ると、「国または地域」などを指定する画面で止まってしまって悲しいことになります。

おまけで、仮想マシンのキャプチャを行うPowerShellスクリプトはこちらです。Sysprepだったり、Linuxの場合は sudo waagent -deprovision+user だったりは事前に各自で行って下さい。

$ResourceGroupName = '[Resource Group name]'
$vmName = '[VM Name]'
$DestinationContainerName = '[Destination Blob Container Name]'
$VHDNamePrefix = '[Vhd Prefix]'

# 仮想マシンの汎用化
Set-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $vmName -Generalized

# キャプチャの実行
Save-AzureRmVMImage -DestinationContainerName $DestinationContainerName -Name $vmName -ResourceGroupName $ResourceGroupName -VHDNamePrefix $VHDNamePrefix

JSONテンプレートを触った方が楽なケースが多いとは思いますが、用途によってはということで。