浅草橋青空市場

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

Azure Container Instances が登場しましたね

急に登場したような気がするのですが「Azure Container Instances」のパブリックプレビューが始まっていました。 ホストVM無しでいきなりコンテナが動かせるというもの。また楽しそうなサービスが増えてしまいましたね。

azure.microsoft.com

既にいくつも日本語の記事が投稿されて、盛り上がってますね。

Azure Container Instances | ブチザッキ

Azure Container Instances は Hypervisor レベルでの分離を備えた次世代のコンテナ実行環境 - しばやん雑記

Azure Container Instances が出た! - 世界のやまさ

何番煎じか分かりませんが、自分用のメモも兼ねて記録しておきます。

対応リージョンは West US, East, US, West Europe の3つ。東南アジアもまだのようですね。

料金体系はこちら。 作成リクエスト毎に料金がかかるほか、メモリはGB/秒で、CPUはコア/秒で料金が発生します。メモリとCPUコア数はコンテナ作成時に指定できます。 1コア/1.5GBメモリで10,479円/月なので、立ち上げっぱなしだとVMよりだいぶ高いですね。

Pricing - Container Instances | Microsoft Azure

基本的なチュートリアルはこちらから。

Create your first Azure Container Instances container | Microsoft Docs

チュートリアルにある「aci-helloworld」程度だと数秒で起動してきます。リソースプロバイダーは「Microsoft.ContainerInstance」でした。IPアドレスも内包しており、単独のリソースとしては作られません。

オーケストレーターは含まれていません。 同時に公開された「Azure Container Instances Connector for Kubernetes」を使うと、既存のK8sクラスタのノードとしてACIを使うことができます。

いい感じにプリミティブで扱いやすそうなサービスが出てきましたね。今後が楽しみです。

Azure仮想マシンのコストパフォーマンス(Ev3, Dv3を含め)

こちらの記事の続きっぽいもの。 asazure.hatenablog.jp

Ev3、Dv3シリーズが出ましたので、カタログベースで簡単にコスパをまとめてみました。
まだ日本には来ていませんので、東南アジア(Southeast Asia)の金額です。 身の回りで使用頻度の高い、4コアのLinuxインスタンスで比較しています。

月額料金の安い順

f:id:yhara90:20170725230836p:plain

メモリ単価の安い順

f:id:yhara90:20170725230839p:plain

並べてみると、面白みはありませんがAzureの料金表ページに書いてある通りの結果になりました。
CPU性能が必要な場合は「コンピューティングの最適化」のFシリーズのお得感が際立ちます。Hyper Threadingが有効なDv3やEv3より割安なのは意外ですね。

メモリ容量が必要であれば「メモリの最適化」のEv3シリーズでしょうか。Nested Virtualization を活かしてDockerコンテナをたくさん載せたりするのに良いですかね。
DBサーバーに使う場合は、CPUやストレージ性能の高いLシリーズも良さそうです。

Markdownのテーブルだと横にはみ出して見づらかったので画像で貼りました。
テキスト版が必要な方はこちらからどうぞ。

Azure 4コアインスタンスの料金比較 · GitHub

他のサイズで比較したい場合は、そのうちこちらのサイト様が更新されるかと思いますので合わせてどうぞ。

http://azureprice.net/

Azure Ev3シリーズ仮想マシンのストレージベンチマーク

こちらの記事の続き。

asazure.hatenablog.jp

E4s_v2 Cドライブ

f:id:yhara90:20170722000247p:plain

E4s_v2 Dドライブ

f:id:yhara90:20170722000305p:plain

うーん、あんまり早くないですね…価格優先ということですかね。

▼米国東部2での比較

インスタンスサイズ 金額
DS12 v2 44,242.71/月
L4s 41,434.85/月
E4s v3 37,564.56/月

TerraformでAzure仮想マシンを作成する(Managed Disks編)

Terraformを使って、Managed Disksの付いた仮想マシンを作る簡単な手順です。 UnManaged Disksの場合はこちらの記事をどうぞ。

バーチャルマシンを ARM対応の Terraform を使ってプロビジョンしてみる - Qiita

ではさっそく。

Terraformのダウンロード

公式サイトから自分の環境用のバイナリを取得してパスの通った場所に置いて下さい。バイナリ1つで動作するのでセットアップの手間いらずでとても楽ですね。

Download Terraform - Terraform by HashiCorp

サービスプリンシパルの作成

Terraformを実行するためのアカウントのようなものですね。 CLI2.0で作るのが簡単なので、ポータルのAzure Cloud Shell から実行しましょう。 サブスクリプションが1つの環境であれば1行目は無くても大丈夫です。

az account set --subscription "[サブスクリプションID]"
az ad sp create-for-rbac --name "[アプリケーション名]" --role Contributor

2行目を実行したあとのレスポンスが大切です。以下の3項目はあとで使います。特に「password」はあとから参照できませんのでしっかり記録しておきましょう(パスワードリセットは可能です)。

  • appId
  • password
  • tenant

サービスプリンシパルそのものについての説明はこちらへどうぞ。

AzureのサービスプリンシパルをCLI2.0から発行する - 浅草橋青空市場

Terraformの設定ファイルを書く

ここからが本番です。「.tf」という拡張子のファイルにどんどん書いていきます。
サービスプリンシパルやOSアカウントなどの認証情報は「.tfvars」に外出しして .gitignore に入れておくのが良いでしょう。.tfvars のデフォルトは「terraform.tfvars」です。これ以外のファイル名の場合は、terraformコマンド実行時にオプションで明示的に指定する必要があります。

ではまず.tfvarsの書式から。

default_user = "OSユーザー名"
default_password = "OSパスワード"
subscription_id = "AzureのサブスクリプションID"
client_id       = "AzureのサービスプリンシパルのクライアントID(appId)"
client_secret   = "Azureのサービスプリンシパルのパスワード(password)"
tenant_id       = "AzureのサービスプリンシパルのテナントID(tenant)"

続いて.tfのコード例。
Azure側で用意されているUbuntu16.04LTSの最新版から、データディスク付きのVMを作ります。 ストレージはもちろんManaged Disks。
ほぼ公式のサンプルを踏襲していますので、IPアドレスにタグが付いていたりしますのでお好みで。

variable "default_user" {}
variable "default_password" {}
variable "subscription_id" {}
variable "client_id" {}
variable "client_secret" {}
variable "tenant_id" {}

provider "azurerm" {
  subscription_id = "${var.subscription_id}"
  client_id       = "${var.client_id}"
  client_secret   = "${var.client_secret}"
  tenant_id       = "${var.tenant_id}"
}

resource "azurerm_resource_group" "test" {
  name = "harayTerraformDemo"
  location = "Japan East"
}

resource "azurerm_virtual_network" "test" {
  name = "tfvnet1"
  address_space = ["10.0.0.0/16"]
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_subnet" "test" {
  name = "tfsubnet1"
  resource_group_name = "${azurerm_resource_group.test.name}"
  virtual_network_name = "${azurerm_virtual_network.test.name}"
  address_prefix = "10.0.2.0/24"
}

resource "azurerm_public_ip" "test" {
    name = "haraytfvm01PIP"
    location = "${azurerm_resource_group.test.location}"
    resource_group_name = "${azurerm_resource_group.test.name}"
    public_ip_address_allocation = "static"
    domain_name_label = "haraytfvm01"
    tags {
        environment = "test"
    }
}


resource "azurerm_network_interface" "test" {
  name = "haraytfvm01nic1"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"

  ip_configuration {
      name = "haraytfvm01ip"
      subnet_id = "${azurerm_subnet.test.id}"
      private_ip_address_allocation = "dynamic"
      public_ip_address_id = "${azurerm_public_ip.test.id}"
  }
}

resource "azurerm_virtual_machine" "test" {
  name                  = "haraytfvm01"
  location              = "${azurerm_resource_group.test.location}"
  resource_group_name   = "${azurerm_resource_group.test.name}"
  network_interface_ids = ["${azurerm_network_interface.test.id}"]
  vm_size               = "Standard_DS1_v2"

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }

  storage_os_disk {
    name              = "myosdisk1"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }

  storage_data_disk {
    name              = "datadisk_new"
    managed_disk_type = "Standard_LRS"
    create_option     = "Empty"
    lun               = 0
    disk_size_gb      = "32"
  }

  os_profile {
    computer_name  = "haraytfvm01"
    admin_username = "${var.default_user}"
    admin_password = "${var.default_password}"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  tags {
    environment = "test"
  }
}

Terraformコマンドを実行する

.tf と .tfvars を同じディレクトリに置いてください。 まず全体像はこんな感じです。

- terraform plan : いわゆるdry-runを実行します。
- terraform apply : 実際プロビジョニングを行います。
- terraform plan -destroy : リソース削除のdry-runです。
- terraform destroy :  リソースを削除します。

plan オプションで確認してから実行、という流れですね。 .tfvars のファイル名が「terraform.tfvars」じゃない場合には、ファイル名を明示的に指定して下さい。

terraform plan -var-file myvmvars.tfvars

Managed Disks の場合、ストレージアカウントを考慮する必要がなくなりますのでより扱いやすくなりますね。

AzureのサービスプリンシパルをCLI2.0から発行する

AzureをTerraformやAnsibleから制御したかったり、Azure Container Services から Kubernetes のクラスをデプロイするときなんかに必要となるのが「サービスプリンシパル」。 言葉が分かりづらいですが、SaaSでよくある「アプリケーションパスワード」みたいなものですね。

以前はこれの発行がわりと面倒だったのですが、Azure CLI 2.0 になって劇的に楽になりました。 Azure Cloud Shell から実行する前提で、ログイン等は省略してあります。

サービスプリンシパルの発行(CLI2.0対応版)

az account set --subscription "[サブスクリプションID]"
az ad sp create-for-rbac --name "[アプリケーション名]" --role Contributor

これだけです。

(追記: 2017/06/02)

「–role」オプションでRBACベースのロールを指定します。
例では、Ansible等を想定してリソースの読み書きなどが可能な「Contributor(=共同作業者)」としてありますが、こちらを参考に適切なロールを指定して下さい。情報の取得のみであれば「Reader」あたりでも間に合いますね。

docs.microsoft.com

(追記以上)

こんな感じのレスポンスが返ってきます。パスワードはあとから照会できませんので控えておきましょう。 パスワード以外の項目は、ポータルの「Azure Active Directory → アプリの登録」から確認できます。

{
    "appId": "[アプリケーションID]",
    "displayName": "[表示名]",
    "name": "[アプリケーションID/URI]",
    "password": "[パスワード]",
    "tenant": "[テナントID]"
}

発行したサービスプリンシパルCLIからログインしてみる

az login --service-principal --username "[アプリケーションID/URI]" --password "[パスワード]" --tenant "[テナントID]"

公式のドキュメントはこちらからどうぞ。

docs.microsoft.com

(追記: 2017/06/01)

パスワードが分からなくなった場合は、ポータルからキーを新たに発行すれば良さそうです。 手順はこのあたりから。

docs.microsoft.com

複数のサブスクリプションを同じディレクトリ上で運用している場合、カレントのサブスクリプションにIAM(RBAC)権限が付与されるようです。思ったのと違うところに権限が付いた場合は、ポータル等から変更しておきましょう。

そもそもサービスプリンシパルって何?という説明はこちらの公式ドキュメントをどうぞ。

docs.microsoft.com

Azure仮想マシン用ディスクが最大4TBまで拡張されたようです

build 2017 の発表に続いてリリースが出ました。

azure.microsoft.com

さっそく検証記事が上がっていました。

qiita.com

記事がPowerShellだったので、CLIでもやってみました。 …といっても、単にCLIからManaged Diskを作っているだけですね。 Azure Cloud Shell でできるので楽ですね。

アナウンスには「West US Central Region」と書いてありますが、Japan Eastでも大きなディスクを作るだけならできました。仮想マシンにアタッチするところでエラーになるようですね。

CLIからディスクを作成する

$ az disk create --resource-group [リソースグループ名] --name [ディスク名] --sku [Standard_LRS or Premium_LRS] --location [リージョン] --size-gb [ディスクサイズ]

ディスクサイズの最大は、リリースにもあるように4,095GBです。 –sku は、Premium Disk(SSD相当)の場合は「Premium_LRS」、Standard Disk(HDD相当)の場合は「Standard_LRS」です。

既存のディスクのサイズを変更する

$ az disk update --resource-group [リソースグループ名] --name [ディスク名] --size-gb [ディスクサイズ]

Azure Lシリーズ仮想マシンのストレージベンチマーク

3月に登場したLシリーズの仮想マシンですが、低遅延なワークロード向けに最適化されたストレージが接続されているということで、実際にベンチマークしてみました。 比較対象は、L4s(4core, 32GBメモリ)とDS12v2(4 core, 28GBメモリ)、いずれも東日本です。

azure.microsoft.com

Linux上でのベンチマーク

OracleのORIONを使います。Oracle DatabaseのようなI/Oを再現させるということで、現実的なベンチマークが取れます。バイナリ1つというのも楽でいいですね。

ダウンロードはこちらから。ライセンス規約への同意が必要なのでブラウザでアクセスして下さい。

http://www.oracle.com/technetwork/jp/topics/index-096484-ja.html

準備

$ gunzip orion_linux_x86-64.gz
$ chmod 755 orion_linux_x86-64

計測用ディレクトリとファイルの作成

$ sudo mkdir /datadrive/iotest
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-010.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-020.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-030.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-040.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-050.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-060.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-070.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-080.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-090.dbf bs=1M count=1024
$ sudo dd if=/dev/zero of=/datadrive/iotest/testfile-100.dbf bs=1M count=1024

設定ファイルの作成

ORIONを配置したディレクトリで。

$ vi orion-test.lun
$ cat orion-test.lun
/datadrive/iotest/testfile-010.dbf
/datadrive/iotest/testfile-020.dbf
/datadrive/iotest/testfile-030.dbf
/datadrive/iotest/testfile-040.dbf
/datadrive/iotest/testfile-050.dbf
/datadrive/iotest/testfile-060.dbf
/datadrive/iotest/testfile-070.dbf
/datadrive/iotest/testfile-080.dbf
/datadrive/iotest/testfile-090.dbf
/datadrive/iotest/testfile-100.dbf

ベンチマークの実行(simpleモード: readのみ)

$ sudo ./orion_linux_x86-64 -run simple -testname orion-test -num_disks 1

ベンチマークの実行(advancedモード: read/write)

Writeの比率を20%に設定。

$ sudo ./orion_linux_x86-64 -run advanced -testname orion-test -write 20 -num_disks 1

結果のまとめ(IOPS)

#1 #2 #3 #4 #5 average
Resource Disk simple DS12v2 265,240 295,247 307,868 312,623 314,806 299,157
L4s 260,160 294,480 300,374 315,354 317,482 297,570
advanced DS12v2 4,902 105,021 150,353 151,570 151,631 112,695
L4s 15,867 231,738 250,393 251,296 256,432 201,145
Persistent Disk simple DS12v2 275,935 303,187 316,342 326,228 327,368 309,812
L4s 277,109 306,821 319,787 324,359 329,075 311,430
advanced DS12v2 73,683 84,010 89,240 86,708 84,707 83,670
L4s 177,048 199,667 251,055 252,527 250,629 226,185

「Resource Disk」がいわゆる揮発する方(/mnt/resources)、「Persistent Disk」が永続的なディスク(/)です。
「simple」と「advanced」が実行モードの違いで、simpleが読み取りのみ、advancedが読み書き混在で、今回はwrite20%で計測しました。
writeが入るとだいぶ性能差が出るようですね。

結果のまとめ(Latency)

#1 (ms) #2 (ms) #3 (ms) #4 (ms) #5 (ms) average
Resource Disk simple DS12v2 0.000 0.010 0.010 0.010 0.020 0.010
L4s 0.000 0.010 0.010 0.010 0.020 0.010
advanced DS12v2 0.200 0.020 0.020 0.030 0.030 0.060
L4s 0.060 0.010 0.010 0.020 0.020 0.024
Persistent Disk simple DS12v2 0.000 0.010 0.010 0.010 0.010 0.008
L4s 0.000 0.010 0.010 0.010 0.010 0.008
advanced DS12v2 0.010 0.020 0.030 0.050 0.060 0.034
L4s 0.010 0.010 0.010 0.020 0.020 0.014

こちらはレイテンシの測定結果です(ミリ秒)。
こちらも同様の傾向が見られますね。

Windows上でのベンチマーク

ついでにWindowsでも計測しました。CrystalDiskMarkでさらっと。
Windowsの場合はCドライブが永続的なディスク、Dドライブが揮発する方ですね。 Linuxと同じ傾向なので、やはりLシリーズのストレージは早いということになりそうです。

Cドライブでの比較

▼DS12v2
f:id:yhara90:20170428213126p:plain

▼L4s
f:id:yhara90:20170428213135p:plain

Dドライブでの比較

▼DS12v2
f:id:yhara90:20170428213144p:plain

▼L4s
f:id:yhara90:20170428213151p:plain