RDCMan でサムネイル画面のまま操作できるようにする


みんな大好き RDCMan でサムネイル画面のまま操作できないもんかと思って調べてみたら、ちゃんと出来るみたいだったのでメモ。

サムネイル画面のサイズは [Tools] – [Client Area] から [Thumbnail Unit Size] で設定。4K モニターなら FullHD で 4 画面とか、もう少し小さくて 9 画面でもいいかも。

 

肝心のサムネイル画面のまま操作する設定は、グループのプロパティとかで、[Allow thumbnail session interaction] のチェックを入れるだけ。

 

というわけで、無事できました。これは楽だ。


Test-AzureRmTraffic を公開しました


Azure の便利ツールをまた一つ公開しました。

Test-AzureRmTraffic
https://github.com/ShuheiUda/test-azurermtraffic

NSG で通信を絞ったときに、目視で個々のルールを確認して許可・拒否判断するのは非効率なので、EffectiveNSG をベースに “NSG の設定上” どう判断されるかをチェックしてくれるツールです。

例えば以下のようなシナリオの調査で使ってください

  • NSG で通信を絞った結果、許可したつもりの通信が通らない
  • 通信不可の原因が NSG なのか、VM 内の問題かを切り分けたい

使用例

PS> .\Test-AzureRmTraffic.ps1 -VMName shudaVM -SourceIPv4Address 192.168.0.4 -SourcePort 80 -DestinationIPv4Address 10.0.0.5 -DestinationPort 80 -Protocol TCP -Direction Inbound

(許可の場合)
Access : Allow
Priority : 65000
Name : defaultSecurityRules/AllowVnetInBound
Protocol : All
SourceAddressPrefix : VirtualNetwork
SourcePortRange : 0-65535
DestinationAddressPrefix : VirtualNetwork
DestinationPortRange : 0-65535
Direction : Inbound

(拒否の場合)
Access : Deny
Priority : 65500
Name : defaultSecurityRules/DenyAllInBound
Protocol : All
SourceAddressPrefix : 0.0.0.0/0
SourcePortRange : 0-65535
DestinationAddressPrefix : 0.0.0.0/0
DestinationPortRange : 0-65535
Direction : Inbound

なお、実際にパケットを投げているわけではないので、NSG 上は許可されているのに実際には通信ができないといった場合は、OS 内の Firewall なり、オンプレの Proxy, Firewall など NSG 以外の要因を疑いましょう。

 

バグやフィードバックはコメント欄にどうぞ。


Managed Disks への変換に失敗した件


Managed Disks を検証していたら、エラーで変換できない事象に遭遇したのでメモ。
変換元が SSE (Storage Service Encryption) で暗号化されたストレージだとダメみたい。

<アクティビティ ログ抜粋>
 {
    (中略)
    "properties": {
        "statusCode": "Conflict",
        "statusMessage": "{\"status\":\"Failed\",\"error\":{\"code\":\"ResourceDeploymentFailure\",\"message\":\"リソース操作が完了し、ターミナル プロビジョニング状態は 'Failed' です。\",\"details\":[{\"code\":\"InternalDiskManagementError\",\"message\":\"An internal disk management error occurred.\"}]}}",
        "serviceRequestId": "f98494e5-a880-4eee-92de-1a8122c51f25"
    },
    "relatedEvents": []
}

ドキュメントを読んだらさらに詳しく書いてあって、SSE の暗号化を無効にしても暗号化が解除されるわけではない模様。非暗号化ストレージにコピーして、そこから Managed Disks へ変換って感じですかね。(あと、Managed Disks 上での SSE での暗号化について「今後リリースされる予定です」って書いてありますね。)

Managed Disks と暗号化
SSE では、ストレージ アカウントに書き込まれたデータを暗号化します。 SSE によって暗号化されたことがある VHD ファイルがある場合、その VHD ファイルを使用して Managed Disks を使用する VM を作成することはできません。 また、暗号化された非管理対象ディスクを管理ディスクに変換することもできません。 該当のストレージ アカウントで暗号化を無効にしても、VHD ファイルが元の状態に戻り、暗号化が解除されるわけではありません。

暗号化されたディスクを使用するには、まず、暗号化されたことのないストレージ アカウントに VHD ファイルをコピーする必要があります。 これで、Managed Disks を使用する VM を作成し、作成時にその VHD ファイルを指定できるようになります。また、コピーした VHD ファイルを Managed Disks を使用する実行中の VM にアタッチすることもできます。

SSE 周りももうちょっと勉強しないとダメだなぁ。


そうだコンテナー データセンターを作ろう (Part4. 基礎工事編)


嫌な嫌な花粉症のシーズンですね。花粉のおかげで工事も進まないので、久々にコンテナ DC ブログです。

前回書いた通り土地を競売で取得したので、今回から本格的なコンテナ DC 建設工事に入ります。

Docker?いやいや、コンテナといったら物理でしょ

コンテナ DC のキモといえば海上輸送用のコンテナ。ネット上でも結構売ってる業者が見つかりますが、数年前から目をつけていたユーエンさんにお邪魔してきました。横浜の展示場 (といっても、横浜のふ頭にある広大なコンテナ置き場) で即売会を年に何度かやっていて、誰でも見学や買い付けに行けます。

このほかにも、JR 貨物が JR コンテナの中古を売りに出していたり、建築確認申請に通ったと謳っているコンテナを扱っている業者もあるようです。

ネットだと新古とか中古コンテナがどんなもんか中々わからないですが、この二枚を見比べてもらえば大体わかりますかね。新古は完全な新品ではないので数回つかった痕跡があります。(よく見ると奥の床がめくれてます。もちろん、ちゃんと交換してから納品してくれるとのこと。)

中古でも塗装や補修をすればきれいになるんでしょうが、所詮は鉄の塊なので凹みとかキズは結構気になりますね。

改造済みの電灯やらコンセントがついたコンテナも見せてもらいました。ただ、電柱からコンテナへの電気の引き込みはやってくれないようだったのと、断熱やら電気工事を含めて見積もりを取ったら結構な額になったので、改造は自前でやることにして今回は素のコンテナだけを買っています。

おっさん、キミにきめた!

コンテナの設置は水平さえ出せればどうにでもなるようで、コンクリ板で高さを調整する程度でも設置が可能だそうです。ただ、長く使うからには基礎を打っておかないと不安なので、近場の工務店にお願いしました。

が、この工務店の仕事が遅すぎてお話にならない。見積りは催促しても全然送ってくれないし、施工前の打ち合わせも一切なし、施工日の連絡も一週間前に「来週のどっかで」って言ってくる始末。結局前日になるまで日取りは決まらず、一日では全部終わらないので肝心のコンクリ流し込むところは見に行けずです…。(自前でやる案もありましたが、かなりの肉体労働になりそうで、一人じゃ到底無理そうだったので仕方ないんですが。)

とまあ、色々あって私は見に行けなかったのですが、世の中には「おっさんレンタル」なんて便利なものがあるんですね。さすがに直前すぎて無理だろうと思いつつ、前日の深夜に現場の様子見と撮影をお願いしたら明朝早々にオッケーとの返事がきて、いっぱい写真を撮ってくれました。かなり非常識かつムチャなお願いをしたのに対応してくれた某おっさんには本当に感謝です。

以下、ざっくりと工程をご紹介。詳しいことはこことか、この辺を見てください。

今回は左右に二点基礎としましたが、レーザーで水平を測って水糸を張り、根切り (穴を掘り) ます。

コンクリを流し込むための型枠を組んで、セパや添え木で動かないように固定します。

強度を出すために鉄筋をいれて。

左右で高さをそろえて、離型剤を塗ります。

あとはミキサー車からコンクリートを流し込んで完了。冬場なので 1 週間くらい乾燥させてから木枠を外します。

出来上がった二点基礎がこちら。意外に高低差があったようで、手前のほうが基礎の高さがありますね。

今回はここまで。次の更新はまた暫く期間が開くと思います。


大量の Azure VM を展開してみる


Azure がついに 7 周年らしいですね。おめでとうございます。(私は 20 歳で触り始めたので、気づけば 6 年以上使っていることに…。)

さて、昨日同僚から、「明日のトレーニングで使う VM を 40 台作りたい」と相談を受けて、片手間でデプロイしたので、落書き程度にメモを残しておきます。

1. 展開方法

詳しく話を聞くと、RDS 環境のトレーニング用に VM 5 台 (CB, SH1, SH2, Web, Client) x8 セットが明日までに欲しいとのこと。

パッと思いつく方法としては、以下の 4 通りくらいでしょうか。

  • ポータルからポチポチする (論外)
  • Azure PowerShell で単純にループさせてシリアルでデプロイする (遅い)
  • Azure PowerShell でパラレルでデプロイする (面倒)
  • JSON テンプレートを使う

どの方法でも作れますが、今日はデプロイに時間をかけられないので JSON にしました。(夕方相談を受けて、明日使うということだったので。)

なお、余談ですが PowerShell で複数リソースをパラレル展開する方法は以下にメモってあります。ただ、これも作成するリソース数が増えると、エラーを吐きやすくなってデバッグが面倒なので、今回は候補から除外。

2. JSON テンプレートの作り方

使い慣れていない人に PowerShell とか JSON テンプレートって言うとあからさまに嫌な顔されるんですが、一回作って慣れてしまえば大したことはないです。

JSON が初めての人は、横着せずに以下全部きっちり目を通しましょう。これだけ知っていれば十分なので。

で、具体的にどう作るかというと、既存のテンプレートをパクってきて切り貼りします。

 

今回は VM を大量に複製したいので、名前に loop と入った以下をベースにします。

このまま [Deploy to Azure] ボタンでサクっとデプロイできるのですが、40 と入れると 5 台までしか作れないとエラーになります。生の JSON を開いてみると、以下の通り numberOfInstances のパラメーターが maxValue 5 となっているので、40 などに書き換えてしまいましょう。

なお、運用環境の場合は 1 つのストレージ (20000 IOPS 上限) に大量の VHD (500 IOPS 上限) を配置するとパフォーマンスに影響があるので、適切にストレージを分割する必要があります。あと、Premium ストレージについては 35 TB の容量制限もあるので気を付けましょう。

    "numberOfInstances": {
      "type": "int",
      "defaultValue": 2,
      "minValue": 2,
      "maxValue": 5,
      "metadata": {
        "description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account"
      }
    },

 

次に Visualize ボタンを押して含まれるリソースを確認すると以下が入っていることがわかります。リソース名に copyindex() とついている VM と NIC は、1 つしか定義されていませんが、ループさせて必要数だけ作成されるようになっています。

生の JSON をさらに深堀してみると、例えば NIC は以下のように定義されています。name は nic0, nic1, nic2… などとなるように、copyindex() でループのカウンタ (0, 1, 2…) をセットして、concat で文字列を結合しています。また、copy セクションで count として設定されている数だけループするように定義してあります。(ここでは、あとで任意の値が設定できるよう、numberOfInstances というパラメーターが入っています。)

    {
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[concat('nic', copyindex())]",
      "apiVersion": "2016-03-30",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "nicLoop",
        "count": "[parameters('numberOfInstances')]"
      },
      "dependsOn": [
        "[variables('virtualNetworkName')]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('subnet1Ref')]"
              }
            }
          }
        ]
      }
    },

 

同じく VM についても 1 台分しか定義されていませんが、ループさせて numberOfInstances 台だけ展開されるようになっています。その他、コンピューター名やVHD のパス、NIC の ID なども copyIndex() を使って定義されていることに気を付けましょう。

    {
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[concat('myvm', copyIndex())]",
      "apiVersion": "2016-03-30",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "virtualMachineLoop",
        "count": "[parameters('numberOfInstances')]"
      },
      "dependsOn": [
        "nicLoop",
        "[variables('storageAccountName')]"
      ],
      "properties": {
        "availabilitySet": {
          "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]"
        },
        "hardwareProfile": {
          "vmSize": "Standard_D1_v2"
        },
        "osProfile": {
          "computerName": "[concat('vm', copyIndex())]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": "[variables('imageReference')]",
          "osDisk": {
            "name": "osdisk",
            "vhd": {
              "uri": "[concat(reference(variables('StorageAccountName'), '2016-01-01').primaryEndpoints.blob, 'vhds/osdisk', copyIndex(), '.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',concat('nic', copyindex()))]"
            }
          ]
        }
      }
    }

各パラメーターを一通り見てみると、実は Public IP が付与されていないことが判明します。このままでは直接 RDP できないので、他の Public IP 付きの VM を展開するテンプレートから Public IP の定義と、NIC の依存関係の部分をパクってきます。

なお、この際にリソース名等に使われている変数 (variables) が定義されていなかったりするので、concat(‘pip’, copyIndex()) などへ変更し、Public IP と NIC を紐づけるなど、ベースのテンプレートと整合性が取れるように微修正します。

    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[variables('publicIPAddressName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "publicIPAllocationMethod": "Dynamic",
        "dnsSettings": {
          "domainNameLabel": "[parameters('dnsLabelPrefix')]"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[variables('nicName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ]
      }
    },

とまあ、こんな具合でそれっぽいテンプレートが出来上がったら、ポータルの [新規] – [テンプレートのデプロイ] に張り付けて、デプロイしてみましょう。(コンピューター名を役割ごとに別で定義したかったので、以下では VM やら NIC、Public IP を 5 台分コピーして定義しています)

 

大体どっかしら間違っていて、展開前の検証フェーズで失敗すると思います。エラーに表示された内容やキーワードを頼りに、カッコがそろっているか、パラメーターが前後と整合性がとれているかなどを確認しましょう。あとは修正とデプロイを繰り返して、期待したものが出来上がるまで微調整すれば終わりです。

 

3. 余談

大量の VM を展開する際は、サブスクリプションのクォータに気を付けましょう。足りない場合は引き上げ申請をすればいいんですが、数日~1 週間程度かかるので、急ぎの場合はリージョンを変えればいいと思います。(ARM はリージョン毎にクォーター設定されているので。)

ちなみに、クォーターはプレビュー ポータル (https://preview.portal.azure.com) のサブスクリプション ブレードから細かく見れるようになっています。(そのうち一般のポータルにも来るはず?)

 

あと、JSON の編集は Visual Studio もしくは Visual Studio Code を使うとかなり便利です。

 

そんなこんなで、実質 2 時間くらいで無事デプロイが終わりました。クラウドの時代なので、このくらい片手間でサクっと出来ると便利ですね。業務効率化は正義!


Azure VM に大容量ディスクを作ってみる


気まぐれで、Azure VM に大容量ディスクをアタッチしたくなったので、どこまで出来るのか試してみました。

1.概要

まず、前提として Azure VM にアタッチできるディスク (VHD) は 1 本 1 TB が上限です。これは Azure Storage の Page BLOB の上限です。

このため、1 TB の VHD を複数アタッチして、OS の中でソフトウェア RAID 等を構成する必要があります。

また、Azure VM のサイズによってアタッチできる本数の上限が決まっています。G5 / GS5 のサイズで最大 64 本 (64 TB) になりますが、G シリーズはお高いので、一般的に使うサイズだと 32 本 (32 TB) が上限と思ったほうがよいでしょう。

2. 手順

データ ディスクの追加はポータルからもできますが、64 本もアタッチするのは面倒なので Azure PowerShell でサクっとやります。

# 既存の VM 情報を取得
$VM = Get-AzureRmVM -Name "&amp;lt;VM 名&amp;gt;" -ResourceGroupName "<リソース グループ名>"

# 新規で 1023 GB のディスクを 64 本アタッチ
for($i = 0; $i -lt 64; $i++){
    if($i -gt 32){
        Add-AzureRmVMDataDisk -VM $VM -Name "datadisk$($i)" -VhdUri "https://<ストレージ アカウント名 1>.blob.core.windows.net/vhds/datadisk$($i).vhd" -DiskSizeInGB 1023 -Lun $i -CreateOption Empty
    }else{
        Add-AzureRmVMDataDisk -VM $VM -Name "datadisk$($i)" -VhdUri "https://<ストレージ アカウント名 2>.blob.core.windows.net/vhds/datadisk$($i).vhd" -DiskSizeInGB 1023 -Lun $i -CreateOption Empty
    }
}

# 設定を反映
Update-AzureRmVM -VM $VM -ResourceGroupName $VM.ResourceGroupName

これで、VM に 64 本のデータ ディスク (および OS ディスクと一時ディスク) がアタッチされた状態になります。

注意事項:

  • Standard ストレージの場合、1 つのストレージに 20000 IOPS 制限があります。1 BLOB (VHD) あたり 500 IOPS が上限なので、パフォーマンスの観点からは 40 本以上のディスクはストレージを分散させます。
  • Premium ストレージの場合、1 つのストレージに 35 TB 上限があります。課金も恐ろしい額になるので注意しましょう。

 

あとは Windows Server の記憶域スペース・記憶域プールを使って、64 TB の大きなプールを作ってから、ディスクを切り出しましょう。

以下、スクショでお楽しみください。