LinuxユーザーがイジるはじめてのAzure

LinuxユーザーがAzureを使いこなせるように応援するブログです

ARM templateのパラメータファイル渡しとJson Parser

ARM templateについてご質問をいただくことも多くなってきたので

このへんで少し活用するためのワザを紹介しておきましょう。

 

紹介するワザは2つ。

 

1)テンプレートをパラメータファイルと分けて管理する

2)出力されたJson形式から必要な要素をパース処理する

 

どちらもARM templateをシンプルに利用するだけなら必要ないですが

個社・個別にカスタマイズ・管理していくと必ずぶち当たる壁でもあります。

 

まず1)についてからいきましょう。参考とするサイトは以下です。

Azure CLI とテンプレートを使用してリソースをデプロイする | Microsoft Docs

 ⇒「パラメーターファイル」と記載されたサイト中央に記載されています。

 

ご利用されるケースとしては、ARM templateで自社の自動化パターンを

いくつか用意したが、VM名やvNETアドレス、OS起動時の自動実行スクリプト

など、依頼・利用したい側のユーザー部門の要望に合わせて柔軟に対応したい。

でもユーザー部門に記入いただく範囲はJSON本体ファイル全てではなく

パラメーター部分の範囲だけに絞りたい、そんなご要望にお応えできる機能です。

 

つまり企業内で言えば情報システム部門JSONの本体ファイルの管理と

デプロイを担い、ユーザー部門やグループ企業へ記入をお願いする範囲は

パラメーターファイルのみにしたい、といったケースですね。

 

では実行時のサンプルからいきましょう。(1行です)

az group deployment create

  --resource-group ${your_resource_group_name}

  --template-file original.json

  --parameters @parameterssample.json

 

ここではoriginal.jsonというファイルが本体ファイルで、parameterssample.json

というファイルが個別に用意したパラメーターファイルです。

 

ポイントをいくつか記載しておきます。

まず、本体ファイルであるoriginal.jsonですが、特に手を加える必要は

ありません。そのままテンプレートデプロイできる本体ファイルの

ままで修正する個所はありません。これは楽ちんです。

 

次にパラメーターファイルであるparametersample.json

記載方法が本体ファイルのparameters{}とは若干異なります。

 

以下の部分は本体ファイルと同じです。(共通部分)

{

 "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",

 "contentVersion": "1.0.0.0",

 "parameters": {

     }

}

 

注意が必要なのはparameters{}内に入れた変数名と値の指定方法です。

以下がパラメーターファイルのサンプルです。

 

"parameters": {

     "loginUser": {

          "Value": "azure02"

     },

      "virtualMachines_name": {

          "Value": "centclient201"

     },

      "vmSize": {

          "Value": "Standard_A2"

      }

}

 

パラメータファイルの注意点:

・TypeやMetadataなどの項目は指定しない。

・defaultValueはValueとして指定する。

 ※Valueの値「""内」だけユーザー部門に入力してもらう

・パラメーターファイルに記載する変数名(例:loginUser)

 は本体ファイルに定義した変数名と合わせる必要がある

・本体ファイルに記載されていない変数はパラメーターファイルに

 追記できない。(デプロイ前にエラーになる)

・本体ファイルに記載されている変数名と値はパラメーターファイルで

 必ず記載する必要はない。省略可能ということ。

 (本体ファイルに指定されている値がデプロイ時に有効)

・本体ファイルに記載されている変数名と値が、パラメーターファイル

 で指定されているものと全く同じ変数名と値でも、デプロイに問題

 はない。(ユーザー部門が修正された個所だけ変更される)

 

上記の注意点を守って記載してあげれば、2018/5現在の仕様では

ちゃんとデプロイできます。

 

本体ファイルさえ用意できていれば、パラメーターファイルだけ

分割して用意してあげることで管理は柔軟に対応できますね。ステキ。

 

 

では最後に2)のJson Parserについて触れていきましょう。

その名の通りJSON形式の出力をパース処理で必要な範囲だけ

くり抜く、というものです。

 

Linux環境ではjqと呼ばれるjson parserがメジャーですので

ARM templateの結果に対してjqを使う場合のTipsを記載しておきます。

 

jqは64bitOSなら以下からダウンロードできます。

$ wget http://stedolan.github.io/jq/download/linux64/jq

$ chmod 755 ./jq

 

以下Tipsです。

〇test.jsonのparametersに記載されているキー名のみ出力

$ jq '.parameters | keys' test.json | awk -F"\"" '{ print $2 }'

可用性セットの範囲だけ出力

$ jq '[.resources | select(.type == "Microsoft.Compute/availabilitySets")]' test.json

可用性セットに記載されている範囲のapiVersionの値だけ出力

$ jq '[.resources | select(.type == "Microsoft.Compute/availabilitySets") .apiVersion]' test.json

可用性セットに記載されている範囲のUpdateDomainの値だけ出力

$ jq '[.resources | select(.type == "Microsoft.Compute/availabilitySets") .properties.platformUpdateDomainCount]' test.json

可用性セットに記載されている範囲のVMResourceIDの値だけ出力

$ jq '[.resources | select(.type == "Microsoft.Compute/availabilitySets") .properties.virtualMachines.id]' test.json

ストレージアカウントが記載されている範囲の冗長方式の値だけ出力

$ jq '[.resources | select(.type == "Microsoft.Storage/storageAccounts") .sku.name]' test.json

 

jqはこんな感じにしておきましょう。出力結果にダブルコート

などの記号が入る場合もあるので、必要に応じてtrやsedで整形して

くださいね。

 

次にJMESPath(じぇむすぱす)を少し紹介しておきます。

JMESPathはAzure CLI2.0(azコマンドの方)がインストールされて

いる環境であれば利用できます。

 

Azure CLI 2.0 でのクエリ コマンドの結果 | Microsoft Docs

 

こちらのイメージとしては、jqのようにJSONファイルやJSON出力

をベースに加工するのではなく、Azureのコマンドラインの出力結果

(JSON出力)を範囲を絞って出力させる、というものです。

 

そこそこ利用しているものをTipsでまとめておきました。

 

ベースとするJSON形式は以下VM情報出力結果としています。

 $ az vm show -g ${resourceGroupname} -n ${vmName}

〇対象VMJSON出力の中でosProfileの範囲のみ出力

 $ az vm show -g ${resourceGroupname} -n ${vmName} --query osProfile

osProfile内にあるlinuxConfiguration、sshpublicKeysを出力

 $ az vm show -g ${resourceGroupname} -n ${vmName} --query osProfile.linuxConfiguration.ssh.publicKeys

〇jqと組わせてpublicKeysのkeyData値のみ出力

 $ az vm show -g ${resourceGroupname} -n ${vmName} --query osProfile.linuxConfiguration.ssh.publicKeys | jq '. .path'

 

 

ベースとするJSON形式は以下のネットワークインターフェース情報

出力結果としています。

 $ az network nic show –g ${resorceGroupname} –n ${nicName}

 

 

〇ipConfigurations内のprivateIpAddressのみ出力

 $ az network nic show –g ${resorceGroupname} –n ${nicName} --query ipConfigurations.privateIpAddress

ipConfigurations内のprivateIpAddressを値のみtsv形式で出力

 $ az network nic show –g ${resorceGroupname} –n ${nicName} --query ipConfigurations[].privateIpAddress --output tsv

 

以上ですが、いかがでしたか。

単純にJSONテンプレートを利用するだけなら必要はありませんが

カスタマイズしていく過程では上記のような文字列・JSON整形が

必要になってくるケースもあると思います。

 

是非コネコネとイジり倒して効率的なテンプレート作成を試してみましょう。

Azure VM(CentOS)のメンテ情報をDatabase for MySQLで管理する

GWも終わりBuildも始まり仕事モードに、、、ならんのですわ(汗

 

さてと、こんな日は緩くブログでも更新しましょうかね。

 

今回記事にする対象のサービスはPaaSサービスである

Azure Database for MySQLです。

 

これまでAzureでMySQLを使おうと思うとIaaSに展開されたVM

MySQLを個別でインストールするか、Azure Market Placeにあった

ClearDBを利用(今はないね)するか、といった2択でしたが、

今回PaaSサービスを選択する枠が増えました。

 

PaaSなのでRDBMSの宿命とも言えるクラスタ/冗長管理やスケール対応

などめんどい部分をお任せできる部分が良いですね。

※つっても利用できるmysqlのパラメータや、Read Replica対応がまだ

 ないなど、いくつか制約はあるようなのでコテコテに弄りたい方には

 まだ満足できない部分もあるかと思います。

 

基本的な仕様は以下に記載されていますのでご参考に。

 

 

前置きはその辺にして、早速本題にうつりましょ。

今回は、ただMySQL環境を用意するだけだとおもちろくないので

Azure Metadata Servicesのスケジュールメンテナンス情報を個々の

VMで定期的にDBに登録し、任意なタイミングで検索できるようにする

といった感じにしてみました。

 

まずはDatabase for MySQLをAzure Portalから作成します。

Azure Portalの「リソースの作成」から「database for mysql」で検索し

「Azure Database for MySQL」を選択します。

 

f:id:akazure:20180507113313j:plain

入力項目がいくつかありますが、ポイントは「サーバー管理者ログイン名」

と「管理者パスワード」、「価格レベル」の3つです。

ここではデフォルトの汎用目的の価格レベルを選択しています。

2vCPU、5GBストレージ、保持期間7日ですが、vCPUは最大32、

ストレージは最大2TB、保持期間は最大35日になってますね。

(2018/5現時点)

 

作成が終わったら「接続のセキュリティ」を覗きます。

f:id:akazure:20180507112514j:plain

 

上記の設定はcentclient101というVMのPublic IPからのみSSL接続を許可する

という設定です。Blob storageやSQL DatabaseのようにvNET統合(vNET

アドレスからの接続のみ許可)は、まだ未対応なので気長に待ちましょ。 

 

次に「接続文字列」を覗いてみましょうか。

f:id:akazure:20180507114642j:plain各言語ごとにどうやって接続するかのサンプルコードが並んでますね。

便利ですね!あ、でもLinux環境でmysqlコマンド使った接続サンプルが

記載されてないので、今回はそちらを試してみましょうか。

 

ということで先ほどSSL接続を許可したVM(centclient101)に一旦

ログインしましょ。mysqlコマンドを使うのでmysqlyum installします。

 

# yum search mysql

# yum install mysql

 

CentOS7xだとmariadb.x86_64がインストールされ、/usr/bin/mysql

インストール時に展開されます。

 

早速接続してみたいところですが、先ほどSSL通信のみ許可する形をとったので

以下のサイトからpemファイルをwgetで持ってきましょう。

Azure Database for MySQL に安全に接続するために SSL 接続を構成する | Microsoft Docs

 

では早速接続してみます。

f:id:akazure:20180507114301j:plain

 

うまく接続できましたね。

画像だとコピペできないので以下に記載しておきます。

 

/usr/bin/mysql -h metatestmysql.mysql.database.azure.com -u azure01@metatestmysql -p --ssl-ca=/var/tmp/BaltimoreCyberTrustRoot.crt.pem

 

※サーバー管理者ログイン名は「ログイン名@DB名」として指定します。

※-pの後ろにそのままパスワードを記載するとパスワード入力を求め

 られずにログインできます。(例:-pPassw@rd)

※BaltimoreCyberTrustRoot.crt.pemは/var/tmpにwgetで配置したもの。

 

とりあえず最初はデフォルトのデータベースしかないので、新たに

instancemetaという名前のデータベースを作成しました。

f:id:akazure:20180507114347j:plain

 

create database instancemeta character set utf8;

grant all on instancemeta.* to azure01@localhost;

 

データベースはこんな感じで、次はテーブルを作成します。

「use instancemeta」した後に以下のカラムでテーブル作成をします。

 

create table instancemetadata (
 id int auto_increment primary key,
 targetnode varchar(255),
 timestamp datetime,
 documentincarnation int(10),
 eventid varchar(255),
 eventstatus varchar(255),
 eventtype varchar(255),
 resourcetype varchar(255),
 resources varchar(255),
 notbefore varchar(255)
 );

 

※varcharは全て255(文字)にしていますが、容量ケチる場合は

 32ぐらいに設定するとよいと思います。

 

MySQL側はこんなところです。

次はAzure Instance metadataのスケジュールされたメンテ情報の

データ取得を行います。

 

オフィシャルサイトで確認しておくのは以下のサイトです。

Azure の Windows VM 向けのスケジュールされたイベント | Microsoft Docs

 

手っ取り早く疎通確認したい場合はcurlで以下のURLを叩きます。

curl http://169.254.169.254/metadata/scheduledevents?api-version=2017-08-01

 ※初回のみ少し時間がかかりますね。

 

出力結果はjson形式ですが、連想配列で返してくるので加工は少し

厄介です。よく使われるjsonパーサーのコマンドとしてjqを使って

いるので、以下からダウンロードし実行できるよう/usr/bin/に配置

しておきましょ。

 

https://stedolan.github.io/jq/

 

jqでjsonを整形した出力は以下のようになります。

※出力サンプルですが、4月19日17時26分10秒に出力された

ものです。

 

{
  "DocumentIncarnation": 28,
  "Events": [
    {
      "EventId": "35268F0A-F532-40CE-A6FD-FA5EE56E8782",
      "EventStatus": "Scheduled",
      "EventType": "Freeze",
      "ResourceType": "VirtualMachine",
      "Resources": [
        "centclient101"
      ],
      "NotBefore": "Thu, 19 Apr 2018 08:35:53 GMT"
    }
  ]
}

 

※特にメンテ情報がない場合はEventIdからNotBeforeまでの項目

 そのものが出力されません。

 

NotBeforeはGMTですので+9時間足すと17時35分53秒です。

つまり約10分後にcentclient101のVMでFreezeが起きるよ、

という情報です。

10分で何ができるかなぁって考えると、OS内ではsystemctlで

安全にdisableにするとか、azure CLI2.0を使って上位

Load Balancerからの振り分け対象から自ノードを外す、とか

ですかね。

 

とまぁこういった情報を定期的にcrontabで実行してデータベース

に入れるのはめんどい部分でもあるので、以下にサンプルを

配置しておきました。ご参考まで。

 

mysqlコマンドで定期的にMySQLへスケジュールイベントを登録する

サンプルのシェルは以下に配置しました。

sample/mysql.sh at master · akkoike/sample · GitHub

適当に変数の値やinsert into部分を変更してご利用くださいませ。

  

 

あとjava(1.8)の日時検索コマンドサンプルも以下に配置しておきました。

sample/SampleSelect.java at master · akkoike/sample · GitHub

javaの場合はJDBCコネクタが必要ですので、事前にyum

インストールしてCLASSPATHを通しておいてください。

 

※インストール

yum install -y mysql-connector-java.noarch

※ステータスがenableか確認

systemctl status mysql-connector-java

※jarライブラリの配置場所確認

rpm -ql mysql-connector-java | grep jar

 

※CentOS7.3ではmlocateがデフォでインストールされています。

 ファイルの配置場所がわからない時はlocateコマンドで部分一致

 検索を使うと便利です。

 「locate connector」

 (出力されない場合はupdatedbコマンドを叩いた後に実行しましょ) 

 

crontabでmysql.shを毎分実行しMySQLに登録された結果は以下です。

f:id:akazure:20180507152457j:plain

 

メンテ情報が出力された場合はこんな感じで見えます。

f:id:akazure:20180511105141j:plain

 

javaの検索実行結果は以下です。(CSVチックに出力)

f:id:akazure:20180507153221j:plain

 

時間帯を前方一致検索するとこんな出力になります。

f:id:akazure:20180511105223j:plain

 

といった感じで、スケジュールされたメンテ情報を定期的に

Database for MySQLへ登録し、後から検索・集計できるように

しておきました。

 

最後に、Database for MySQLに問題があった時のためにdumpファイルを

取っておきましょ。(最悪ローカルに入れたMySQLのDBに入れて

復元するため、です)

 

/usr/bin/mysqldump -h metatestmysql.mysql.database.azure.com -u azure01@metatestmysql -pPassw@rd instancemeta --ssl-ca=/var/tmp/BaltimoreCyberTrustRoot.crt.pem > 20180507_mysql.dump

 

OSSMySQLと同じ操作で同じように扱えるというのはいいですね。

LAMP構成のオンプレ環境をAzureへ移行したい方はご参考まで。

 

今回はこのへんで。

【お試し】Azureのシリアルコンソールをいじる

ども。おもしろいものが出てきたので更新しましょうかね。

 

Linuxユーザーにとってうれしい機能がAzureで出てきました。

Serial Console(シリアルコンソール)です。

 

まだPublic PreviewですのでSLAなどついていませんが(つくのか!?)

技術的に使えそうなのか試してみましょー。

 

といっても、シリアルコンソールは普段から接続して操作するものではない

ですよね。トラブルシューティングをたくさんやっているエンジニアから

すると、むしろ触れたくない(笑)機能かもしれません。

 

なぜなら利用シーンの多くは、「OSにログインできなくなった、どうしよう」

だからですね。自分も何度も経験があります。むかーしのように物理装置の

前にいってダム端をシリアルポートに繋いで、、、とか今のクラウド時代に

できないですから、困っちゃいますよね。

 

じゃぁ、なぜOSにログインできなくなったのか、大抵3つのケースが

多いでしょう。

 

1)SSHキーなくしちゃった、てへぺろ

2)/etc/fstabの記載間違えてリブートかけたら上がらなくなっちゃった、後悔系

3)原因不明で、VMが起動してこなくなり日が暮れちまう、パルプンテ

 

1)のてへぺろ系については、Azureポータルの「パスワードのリセット」から

SSH公開キーのリセット操作ができますので、そこで解決します。なので

わざわざシリアルコンソールから接続して/home/${USER}/.ssh/authorized_key

を直接vimで編集しなくても解決します。

 

1)以外のシチュエーションで使えそうか早速触ってみましょ。

 

最初にVM(起動中)をAzureポータルからイジってみました。

f:id:akazure:20180330155330j:plain

 

なんだか「ブート診断」をEnableにしろ、というエラーが出てますね。

ということで同じ左ペインにある「ブート診断」をONにして保存しましょう。

 

f:id:akazure:20180330155620j:plain

f:id:akazure:20180330155636j:plain

 

ブート診断の設定が完了したらもう一度シリアルコンソール(プレビュー)を

覗きます。

f:id:akazure:20180330155946j:plain

 

んふーー!

ステキですね、コンソール画面が出てきました。

ここで「あ、、、」っと思った方は即実行に移しましょう。

そうです、rootのパスワードは必ずLinux VM作成時に設定しておきましょうね。

後で困るのはご自分ですから。

 

マウント状態を見てみます。

f:id:akazure:20180330160840j:plain

 

シスボルはrwになっていますね。

このままだと面白くないので、ちょっと意地悪して強制的にEmergency Mode

にしてみましょうかね。

 

画像は割愛しますが、やったことは以下です。

 

1、該当のCentOSVMに1TBのデータディスクをAzureポータルからアタッチ

2、CentOS内で該当のパーティションをフォーマットしファイルシステム作成

3、/etc/fstabに記載してmount(/adddisk)し、該当領域にrwできることを確認済

4、この状態でAzureポータルから該当のディスクをホットデタッチ!

5、デタッチが終わったらAzureポータルからVM再起動を実施!

 

f:id:akazure:20180330171032j:plain

 

はい、SSHでログインしようとしても接続できなくなりました。

Azureポータル上では「実行中」のステータスのままです。

このままずっと待ってても立ち上がってこないので、シリアルコンソールで

覗いてみましょう。

f:id:akazure:20180330171141j:plain

 

はい、期待通りEmergency Modeになって、/adddiskのファイルシステム

読み込みに失敗しているエラーが出て止まってますね。

rootのパスワードを入力してログインし、vimで/etc/fstabに記載した

デタッチ済の行をコメントアウト。最後に再起動。

 

f:id:akazure:20180330171429j:plain

 

kernelからinitプロセスの起動からデバイスの確認からメッセージが大量に

流れてきますが、正常に起動したようです。

 

f:id:akazure:20180330171608j:plain

 

最後にSSHログインをターミナルから試みました。

 

f:id:akazure:20180330171732j:plain

 

ちゃんと繋がりましたね!

ということで、OS内の設定をやらかしてしまった時の後悔系については

シリアルコンソールから対処が可能(rootのパスワード設定忘れずに)

ということがわかりました。

 

他にもAzureの裏側でIn-place VM migrationが起きた時にシリアル

コンソールから何かメッセージが見えるか、とか気になる点も多い

と思いますが、任意に再現できるものではないので、何かわかったら

また記事にでもしましょうかね。

※Hyper visorより上位からなのでメッセージどころか単純にフリーズ

 している状態な気もしていますががが。

CentOSを複数台デプロイするテンプレート

 

いつも使っている自作CentOSテンプレをGithubにあげておきました。

 

作成したいCentOS の台数指定するだけで、仮想ネットワーク/サブネット、

22Port/TCPのみ許可したファイアウォール設定、ストレージアカウント(LRS)、

可用性セット、タイムゾーン変更(日本)を含めて複数台一括デプロイする

テンプレです。

 

※rawからダウンロードしてお好みで修正くださいませ。

以下補足です。

 

ResourceGroupは事前に作成しておいてください。

東日本、西日本、米国西部、東南アジア、オーストラリア東南部、

UKのリージョンで確認済です。

 

そのまま利用する場合はSSHキーだけご自分のものを入れればデプロイされます。

以下任意変更可能な値(parameters指定)です。お好みで。

 

SSHでログインするユーザー名

SSHキー入力

VM台数

VM

VMサイズ

CentOSのバージョン

ストレージ冗長方式

仮想ネットワークのアドレス帯

サブネットアドレス帯

VM拡張機能でOS起動後に実行するスクリプトURL

 

以下補足

 managed-diskをご希望の場合は以下を参考に修正ください。

https://docs.microsoft.com/ja-jp/azure/virtual-machines/windows/using-managed-disks-template-deployments

 

 VM Extension機能のスクリプトですが、githubに置きたくない場合は

 以下を参考にblob storageにスクリプトをおいてSASのURLでアクセス

 してください。

 (blobではオブジェクトに対する読み込み権限だけ付与してください)

 

https://github.com/Azure/azure-linux-extensions/tree/master/CustomScript

 

 いじょ。

 

【お試し】Azure blob storageへvNETアドレスからのみ許可する

めずらしく連続更新です。

 

今回はBlob storageへのアクセスを仮想ネットワーク(vNET)からのみ

接続させる、というセキュアな経路を設定する機能紹介です。

 

先日アナウンスされた記事は以下です。

Announcing Preview of Azure Storage Firewalls and Virtual Networks | Blog | Microsoft Azure

 

 

概要は以下の日本語サイトを見て把握しましょう。

Azure Storage ファイアウォールおよび仮想ネットワークの構成 (プレビュー) | Microsoft Docs

 

残念ながらこちらもまだ日本リージョン(東西)へ展開されていませんので

展開されるまで待ちましょう。むむむむ。

 

では早速いきましょう。以下試したリソースは米国東部リージョンです。

f:id:akazure:20171017094711j:plain

 

違いを区別するために仮想マシン作成時に作ったストレージアカウントは

今まで通りファイアウォール設定を入れていない「nonaclblob001」とし、

後で作成した「blobacl002」はファイアウォール設定を入れるストレージ

アカウントとして用意しました。

また、仮想ネットワーク(vNET)のアドレスは192.168.0.0/16とし

1つ192.168.0.0/24のサブネットを切っています。仮想マシンはそこに配してあります。

 

以下はblobacl002作成時にファイアウォール設定を入れる画面です。

f:id:akazure:20171017094548j:plain

 

注目すべきは下段にある仮想ネットワーク(プレビュー)の個所ですね。

既に作成済のvNETをプルダウンで選択できる状態になっています。

また、サブネットもvNET作成時に用意したものを選択します。

ですので正確にはvNET ACLというよりSubnet ACLですかね。

 

設定したストレージアカウントのダッシュボードは以下です。

f:id:akazure:20171017095327j:plain

 

ちゃんと設定したvNETからアクセスするように見えています。

あと、個別にIPaddressかCIDRを入れて許可させることもできそうです。

※ここ重要。この後ハマるんでw

 

さらに「信頼されたMicrosoftサービスによるこのストレージアカウント

へのアクセスを許可する」なるものにデフォルトでチェックされています。

 

し、、、信頼された??と懐疑的な方はこの記事の冒頭に入れた日本語概要

のURLをもう一度読みましょう。下の方にどこからを許可してる、というのが

記載されていますので。

 

blobacl002が作成できたので、早速Azureポータルから見てみ。。。

f:id:akazure:20171017100033j:plain

 

はう!!

 

んじゃAzure Storage Explorerで覗いてみるかぁ。

f:id:akazure:20171017100320j:plain

 

あわわ!

 

既にお気づきの方も多いと思いますが、blob storageのファイアウォール

設定でvNETからと信頼されたMicrosoftサービスからのみアクセスを許可

していますよね。つまりAzureポータルやStorage Explorerの接続元と

なっている「あなたが」利用しているインターネットに出てるソースIP

を許可していないのでアクセスできない状態です。そりゃそうだ、な話。

 

ということでご自分の環境で利用しているアドレスをファイアウォール

設定で許可してあげましょう。

 

以下のサイトへ行くと利用しているソースIPがわかります。

アクセス情報【使用中のIPアドレス確認】

 

他にもLinuxターミナルだと以下のコマンドでわかります。

 

curl inet-ip.info

 

 

さて、アドレスがわかればblob storageのファイアウォール機能を

もう一度開き、そのアドレスからの許可を入れておきます。

 

最後に、「本当にvNETアドレスからのみ受け付けてんだよね?」という

確認をしておきましょ。

 

まずストレージアカウントの「診断」をONにします。

f:id:akazure:20171017100955j:plain

 

ご自分のソースIPがわからず、ワタワタする方にはAzure CLI(2.0)では

以下のコマンドで診断設定が有効となります。

 

 

az storage logging update --log r --retention 30 --services b

 

 

※logはr(readの時)、30日分のログ保存期間、対象はb(blob)サービス、

 という意味の引数です。 

 

診断設定を入れ、storage explorerで覗くと、$logsというコンテナの下に

blob storageへのアクセスログが自動的に配置されていることがわかります。

f:id:akazure:20171017101304j:plain

 

 

 

 

中身を見てみましょう。

f:id:akazure:20171017101410j:plain

 

説明を端折ってますが、何度かvNET内に作成した仮想マシンから

Azure CLIでblobacl002のblobへファイルをアップロードしたりリスト

出力したりしています。もちろんスマホからも覗こうと何度か試してます。

 

うむ、ちゃんとvNETで切った仮想マシンのアドレス(192.168.0.4)から

受け付けたログだけが見えていますね。ステキ♪

 

余談ですが、このストレージアカウントへ診断機能を付けてアクセスログ

を出す仕掛けは、利用しているAPIのバージョンを確認する時にも利用

できます。APIバージョンのサポート切れ、みたいなアナウンスがあった

時に、いま自分が利用しているblob storageへアクセスしているAPI

バージョンって、なんだっけ?という時にアプリや設定ファイルを1つ

ずつ虱潰しに確認する手間は避け、この診断ログを30日分ためて

このテキストログから利用バージョンだけをくり貫いて確認する、と

いった便利な使い方もできます。(1か月稼働しないバッチとかだと

モレるので40日保存の解析がいいですかね)

 

以上でっす。 

【お試し】Azure Availability Zoneをいじる

ども。ちょっとLinuxネタから外れますが、Microsoft Igniteでも話題と

なった可用性ゾーン、Availability Zone(Public Preview)なるものを少し

見てみました。

 

はじめて触ろうとされる方の参考までにー。 

 

以下参考となるサイトの一覧ですので、まずはどういうものか理解

しておきましょう。

 

可用性ゾーンの概要 | Microsoft Docs

 

まだプレビューですので、利用できるゾーンやVMサイズに制限が

あり、利用しているサブスクリプションに対して利用申請しないと

使えなさそうです。

※2017/10/16現在、残念ながら日本リージョン(東西)ではまだ利用

 できないようです。むむむ。

 

ということで米国東部2のリージョンを使い、D1v2 Standardで軽く

CentOSを作成してみました。

 

まずは可用性ゾーンを利用するために以下から申請します。

 

http://aka.ms/azenroll

f:id:akazure:20171016121917j:plain

自動的にAzureポータルへ遷移し、可用性ゾーンを有効とするサブスク

リプションをチェックし有効化を押します。

 

f:id:akazure:20171016122440j:plain

15分ほどすると無効の個所が有効となりますが、1時間ほど放置して

おきましょう。

※見た目有効になってますが、いきなり使おうとしても使えなかったので。

 

少し時間を置いたあと、新規作成から以下を選択しました。

リージョン:米国東部 2

VMサイズ:DS1v2 Standard

OS:CentOS7.3

 

仮想マシン作成時の「設定」を見ると、可用性ゾーンが1,2,3と選べる

ようになっていますね。

f:id:akazure:20171016122617j:plain

 

米国東部 2のリージョンには3つのデータセンターが存在している

というのがなんとなく想像できます。あと、可用性ゾーンを選択すると

可用性セットは選べなくなります。

 

とりあえず1を選んでみました。

 

Azure ポータルのダッシュボードで作成した仮想マシンを見てみます。f:id:akazure:20171016123221j:plain

 

可用性ゾーンと記載された項目が「1」になっているのがわかります。

折角なので、CloudShell(Azureポータル上で開くターミナル)で同じく

プレビューとなったPowerShellから設定情報を覗いてみましょ。

 

f:id:akazure:20171016123515j:plain

 

Bashと違って青い背景のあたりPowerShellっぽいですね、そそられ

ませんがw

 

以下のコマンドレットを叩くとゾーンが1になっていることがわかります。

 

 

Get-AzureRmPublicIpAddress -ResourceGroupName {Resource Group Name}

 

 

ちなみにbash(Azure CLi2.0)だと以下で確認できます。

 

 

az vm show -n {VM Name} --show-details --resource-group {Resource Group Name}

f:id:akazure:20171016123938j:plain

 

最後に、作成したResource GroupのARM templateをみてみます。

記載されているのはResourcesの中の3か所ですね。

 

Microsoft.Compute/disksの定義に1か所。(zonesのところ)

f:id:akazure:20171016124425j:plain

 

次はMicrosoft.Compute/virtualMachinesの定義。

f:id:akazure:20171016124519j:plain

 

最後にMicrosoft.Network/publicIPAddressesの定義。

f:id:akazure:20171016124553j:plain

 

可用性ゾーンをARM templateから設定することも簡単にできそうですね。

日本リージョンでの展開が楽しみですねー。日本で展開されたら

データセンターをどうやって1から2や3へ切り替えるのか、など

試したいところです。

 

あと、Azure LoadBalancer Standard SKUなるものも同じくプレビュー

となっていますが、このデータセンター間にまたがるバランシング機能

が拡充されています。Availability Zoneを意識したL4LBのバランシング

機能、といったところでしょうか。これも楽しみですね。

 

ということで今回はこの辺で。

カスタムイメージを基にスケールするVMSSと2種類のロードバランサを一括構築

ども、最近更新が、、、さぁAzureブログがんばるぞー!!

 

今回のテーマはVirtual Machine Scale Set!略してVMSS。

といってもVMSSをデプロイして自動スケールスゲー!!な話はするつもり

はなく、もちっと実用的なもの(?))を用意してみました。

 

VMSSをベースにL4LBであるALBとL7LBであるApplication Gateway

(以下AppGW)の2つを上段に構え、Inbound通信はAppGW経由、Outbound

通信はALB経由にし、VMSSの各ノードはカスタムイメージから持ってきた

nginx(CentOS7)が起動している状態のものを展開しつつ、なおかつ

AutoscalesettingsでCPU60%以上になったらVM数を増やす、50%以下

になったら1VMずつ減らす、という環境をARM templateで一括作成

しちゃえというものです。

 

・・・。

 

文章で記載するとさっぱり伝わらないですね(はぅ

 

どんな要件だとこれに行きつくのか、、という話をしたほうがよさげですね。

 

〇サーバー負荷に応じて自動でVMを増やしたいし減らしたい

〇セッションアフィニティの管理やWAFの機能も併用したい

〇外向けのOutbound通信はStaticなIPとして固定化し、受け皿側では

 StaticなIPで許可設定をいれたい。

〇スケールする度に毎回WEBサーバーの構築とかだるいからヤダ

 

なんとなく初めてクラウドを利用される方が描く期待の構成っぽく

聞こえますが、そんなご要望に応える環境を試してみました。

 

 

とりあえずブツは以下のgithubに配置しておきました。

手っ取りばやく試したい方はこれをテンプレートデプロイで

azureにぶち込むとわかります。

 

 

ちなみにARM templateは便利ですが、中身を理解していない状態で

利用すると応用もきかずエラーが出た時にアタフタしますので

軽くポイントだけ説明しておきます。

  

まずparametersの個所から。

sshKeyData変数の部分はssh-rsaの文字列の後ろに半角スペースを入れた後、

公開キーの文字列をベタっと張り付けてください。

f:id:akazure:20170912194103j:plain

 

このsshKeyData変数はresourcesの個所で処理していますが、CentOS

作成したユーザー(ここではazure01ユーザ)の/home/.ssh/ディレクトリ配下

にauthorized_keysというファイル名で格納しています。公開鍵認証する際に

照合する場所ですね。

 

addressPrefix = vNETのアドレスセグメント

subnetPrefix = 上記vNET配下のサブネットを1つ

appGwSubnetPrefix = application gateway用サブネット(上記vNET内)

 

defaultvalueでは192.168.0.0/16のvNET配下に/24を2つ指定していますが

間違えても異なるvNETアドレスセグメントの範囲をサブネットに入れない

でください。(デプロイ検証は成功しますが、デプロイ開始後にエラーに

なります)

 

imageNameにカスタムイメージで保管してあるresource idをベタっと

はりつけます。

f:id:akazure:20170912194704j:plain

 

defaultvalueで指定した文字列の中で'-'で括った大文字部分は利用する人

の状況に合わせて差し替えてください。

SubscriptionIDやイメージが保管されているResourceGroupやイメージ名です。

カスタムイメージの作成方法は以下がわかりやすくて良いと思います。

CentOSだとOS内のコマンド一発とAzure Portalの操作だけで完結します。

Check! Azure 仮想マシンで、Linux ベースのカスタムイメージを作成する - Qiita

また、カスタムイメージのresource idはAzure Portalの概要から文字列が確認

できますので、それをコピペすると楽ちんです。

 

次にvariablesです。

こちらは固定定義となる部分ですが、必要に応じてparametersへ移動して

ください。ここでは様々なコンポーネントの名前を全て固定で入れてます。

AppGWに付けるPublicIPは80port/tcpのみ許可する設定を入れてます。

InstanceCountは2にしていますので、VMSSの初期ノード数は2VMです。

こちらは変更しないでください。任意な初期台数で指定できるresourcesの

書き方にはしていませんので。(VMSSでネットワーク定義している

NiCの数は2本固定で入れてますから)

 

最後resourcesです。

利用しているtypeとAPI versionは以下です。

 

Microsoft.Network/virtualNetworks  2017-04-01
Microsoft.Network/publicIPAddresses  2017-04-01
Microsoft.Network/applicationGateways  2017-04-01
Microsoft.Network/loadBalancers   2017-04-01
Microsoft.Compute/virtualMachineScaleSets 2017-03-30
Microsoft.Insights/autoscaleSettings  2015-04-01 

 

Public IPのみ2か所定義しています。ALB用とAppGW用の2本です。

f:id:akazure:20170913114825j:plain

 

AppGWに付けるPublic IPはDynamic(動的アドレス)しか付けられない仕様ですが

ALBに付けるPublic IPはStatic(固定アドレス)で定義しています。

これでVMSSから見たoutbound通信は固定のグローバルアドレスとします。

 

AppGWではフロントエンドのポートを定義し、バックエンドプール(VMSS側へ

振り分ける対象ノードを定義しています。

f:id:akazure:20170913115153j:plain

大丈夫ですよ、後で確認画面見せますが、3台目、4台目とスケールアウトしても

ちゃんとAppGWから振り分け対象に自動的に入りますし、sshログインも増加した

サーバーへ入ることができますから。

 

VMSS側では以下のようにイメージのresource idを指定します。

f:id:akazure:20170913115521j:plain

イメージを一般化(Generalize)する前に、systemctl enable nginx(CentOS7.x)を

しておかないとOS起動時にnginxは起動されませんので注意ください。

 

冒頭でも触れた公開キーの埋め込み方法です。

f:id:akazure:20170913115832j:plain

公開キーはAzureから発行することは現状できませんので、puttyGenなどで自作

してくださいね。

 

autoscalesettingsは閾値や台数のスケール管理をする部分です。

f:id:akazure:20170913120013j:plain

 

VMSSノードは最低2台、最大5台としてます。また、CPUの平均値(5分だった

かな)が60%以上続く場合は1台ずつ増加させ、50%以下平均になると1台ずつ

減少させるように記載しています。

 

全てのデプロイは15分程度で終わります。ちなみにARM templateは40分で

タイムアウトしますので全ての処理は40分以内に終わる処理でなければ

いけません。もちろん各コンポーネントは非同期で処理実行されるため、タイム

アウトした後はできたところまでで切り離され、ロールバックする概念は

ありません。そこんとこ厳しいある。

 

デプロイが終わると各リソースはこんな風に見えます。

f:id:akazure:20170913120911j:plain

 

ではVMSS側にsshログインするので、ALB(上ではLoad balancer)を開きます。

※今回はsandbox環境を用意していないので、直接ALBにつけたPublic IPから

 SSHログインします。(22ではなく50000ポートでログインします)

 

f:id:akazure:20170913194124j:plain

 

英語表記になっちゃってますが、受信NAT規則なるタブから2台のVMのPublic IPと

ポート番号が確認できます。

 

TeraTermでログインしてみます。

f:id:akazure:20170913194312j:plain

 

f:id:akazure:20170913194417j:plain

 

ちゃんとnginxが起動した状態になっていますね。カスタムイメージから

展開されていることがわかります。

 

ちなみに省略しますが、このVMSSノードからcurlwgetで他のグローバル

アドレスへ通信した場合、受け側のWebエンジンのaccess_logからSource IP

がALBにつけたPublic IP(static)になっていることがわかります。

これで受け側での許可フィルタリングも問題なくできます。

 

では次にAppGWのリソースを覗き、AppGWについたPublicIP(+ domain)を

確認します。

f:id:akazure:20170913194955j:plain

 

軽くマスクしておきましたが、このドメイン or IPアドレスをブラウザで確認

してみましょう。

 

f:id:akazure:20170913195105j:plain

はい、ちゃんとnginxの初期ページが表示されていますね。

念のためVMSSノード側の/var/log/nginx/access_logを見てみましょう。

 

192.168.1.11 - - [13/Sep/2017:10:52:09 +0000] "GET / HTTP/1.1" 304 0

"-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0)

like Gecko" "106.73.2.64:5436"

 

はい、何度かブラウザアクセスするとわかりますが、2台のどちらにも

上記ログが振り分けられて吐き出されていることがわかります。

VMSS側から見るとAppGWに付けたSubnetのプライベートアドレス

から振り分けられていることがわかりますね。

 

では最後に意図的にCPU負荷をかけてVMSSがスケールするか、

スケールしたノードへログインでき、AppGWから振り分けされる

状態になっているか、を確認してみましょう。

 

まずはVMSSの現状を見ておきます。

f:id:akazure:20170913200343j:plain

 

CPU負荷もまったくかかっていない状態ですので、初期ノード数の2台が

いることがわかります。

 

負荷かけてみましょう。

 

cd /var/tmp

wget http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/stress-1.0.2-1.el7.rf.x86_64.rpm

rpm -ivh stress-1.0.2-1.el7.rf.x86_64.rpm

stress -c 1

 

 

stressコマンドはCentOS7.xにプリインストールされていないため

盛ってきました。また、今回のVMサイズはStandard_A1でやってますので

vCPUは1つです。なのでstressコマンドの引数に -c 1を指定しています。

 

CPU Percentageのグラフが追い付いていませんが(笑)、ちゃんと

CPUの負荷を検知し3台目を追加しようと動き始めていますね。ステキ。

f:id:akazure:20170913200901j:plain

 

ちなみにこの状態で焦って3台目にログインしようとしてはいけません。

まだデプロイ中なのでsshログインできません。もう少し待ちましょう。

 

ALBの受信NAT規則を見ると3台目(どころか4台目まできてますねw)の

振り分け先が追加され、ポートも50003番で追加されているのがわかります。

f:id:akazure:20170913201325j:plain

 

はい、増加した3台目にログインでき、nginxが起動している状態が確認

できました。

f:id:akazure:20170913202705j:plain

 

ちゃんと/var/log/nginx/access_logをtailで見ながらブラウザでnginxの初期

画面を更新していると、振り分けられているログを確認することができ

ました。

 

 

192.168.1.7 - - [13/Sep/2017:11:27:34 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko" "106.73.2.64:62770"

 

 

以上になりますが、いかがでしょうかね。

そもそもステートレスな環境にステートフルなものを組み合わせていること

事態に違和感を覚えなくもないですが(笑)、割とエンタープライズ

お客様を相手にしていると、こういった構成じゃないと要件を満たすことが

難しい場合もあります。ご参考まで。