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

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

特定のログからWebシナリオテストを自動実行する

前回の記事内容の派生形となります。

 

 

実現イメージは以下ですが、前回との変更点は赤文字/赤線の部分です。

 

f:id:akazure:20190327112808j:plain

 

変更点の補足です。

④ Azure Automation Runbook Python2 から、事前に用意しておいた

  Blob ファイルを取得しています。ファイルの中身は以下です。

 

https://www.google.com/
https://www.microsoft.com/ja-jp
https://hogehogekoike.com
https://aws.amazon.com/jp/

 

 ここでは正常にHTTPの応答を返すか否かの対象となるサイトURLを

 1行ずつ記載しています。

 (3行目のhogehogekoike.comは存在しないURL)

 

⑤Blob ファイルに記載されたURLに対して1行ずつHTTPのスポンスを

 取りに行っています。

 

⑥各URLのHTTPレスポンスの結果をメールの本文に入れてメール通知します。

 

ある程度想像できた方も多いと思いますが、24/365の稼働を提供している

自社のWebサービスにおいて、裏側で構成されているWebのシステムから

致命的なログが確認されたとき、多くのエンジニアは監視オペレータから

の呼び出しや緊急連絡網からの確認依頼、障害対処依頼がきますよね。

 

担当エンジニアは原因の究明や一次対処、サービス正常性確認などを

実施されていると思いますが、これをAzure PaaSを使ってすべて自動化

してしまおう、という一例です。営業時間内のオペレーションであれば

特に問題はないのですが、夜間や休日にサービス影響がない監視連絡ほど

出たくない電話はないですからね(汗

 

では本編に入ります。

 

 

前回の記事も試されて、かつ、せっかちな方(笑)は、以下の

pythonコードをAzure Automation Automation Runbook (python2) に

べたっと張り付けましょう。

(標準ライブラリのみで動作するように記載しています)

 

https://github.com/akkoike/sample/blob/master/automationpython.py

※{}の個所のみ、ご自分の環境に合わせた文字列を入れてください。

例:

storage_resource_group = "{RESOURCE_GROUP_NAME}"

⇒ storage_resource_group = "hogehoge-rg"

 

47行目まではAuto Credentialの部分ですので変更不要です。

49行目から68行目まではblob storageの 定義とインスタンス化です。

コメントアウト部分はデバッグ用で残しておきました。

 

69行目から79行目までがURLを1行ずつ持ってきてHTTP(GET)を

発行し、その結果を変数に代入している部分です。

単純なBasic認証ならrequest.post(url,auth=('user','passwd'))と

指定すればいけそうですね。

 

80行目から最後の101行目まではSendGridへメール送信する部分

です。サブミッションポート(587)のTLS通信でメール送信しています。

 

では試してみましょう。

 

まずLog Analytics(Azure Monitor Logs)では、以下のクエリを

発動条件にしています。

 

f:id:akazure:20190327131730j:plain

Syslog
| where Computer == "centlog002"
| where SyslogMessage contains "critical error"

 

Runbookの発動をAzure MonitorのAlert ruleで指定します。

f:id:akazure:20190327131856j:plain

 

閾値は0件「より大きい」(つまり1以上)にしています。

 

では対象VMのcentlog002にて、「critical error」をrsyslogdへ飛ばしてみます。

 

f:id:akazure:20190327150038j:plain

logger -p authpriv.crit "web service critical error , please check"

 

しばらく待つとLog AnalyticsのクエリログにHITし、Azure Monitorの

Alert Ruleに引っかかり、runbook pythonが処理され、以下のような

メールが飛んできます。

f:id:akazure:20190327150305j:plain

 

各URLのレスポンス結果がメール本文に入っていますね。

もちろんすべて200 OKならメールを通知させる必要もないので

その場合はPythonの中身を自由にカスタマイズしてください。

 

最後に、補足です。

Webのシナリオテストを実行する、というだけなら他にもよさげな

ものがいくつかあると思います。以下はご参考まで。

 

1、Azure DevOpsのCI/CD機能を使う

  今回は試していませんが、gitへnull commitするトリガーで

  いくつかのサイトへのHTTPレスポンスを計測する、といったことも

  できると思います。

 

2、Logic Appsを使う

  以下のように組み立ててれば、簡易版のシナリオテストも

  実行できました。

 

f:id:akazure:20190327151014j:plain

f:id:akazure:20190327151027j:plain

 

 ※ただ、確認したいURLが数百あると、1つ1つアクションを追加する

  のも面倒ですし、blobに置いたURLリストをJSON形式に変換する必要

  がありそうだったため、今回はこちらを使いませんでした。

 

3、Azure functionsで実装する

 今回行ったAzure Automation Runbook pythonは、functionsで実装しても

 大差ありません。お好みで選んでよいと思います。

 

4、SeleniumなどのOSSをOS内で実行する

 Seleniumによる自動化のよいところは、細かいブラウザ内の制御を

 自作できる部分です。

 例えば以下のような記載になります。(簡単なサンプルです)

 

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
 
driver = webdriver.Chrome(executable_path='C:\\Users\\akkoike\\AppData\\Local\\Programs\\Python\\Python37-32\\Scripts\\chromedriver.exe')
# chrome browser
driver.get('https://www.google.co.jp/')
# input keyword to textarea
driver.find_element_by_name("q").send_keys("まいくろそふと")
# search return
driver.find_element_by_name("q").send_keys(Keys.ENTER)
# click link by classname
driver.find_element_by_class_name("LC20lb").click()
driver.back()

 

 ※事前にChromeドライバのダウンロードと配置、pipでselenium

  インストール(pythonの場合)しておく必要があります。

  ここではchromeブラウザを起動し、google検索フィールドに

  「まいくろそふと」と入力しリターン。検索ヒットした1つ目の

  リンク先をクリックし、最後に「戻る」を押す、といった簡単な

  ものです。

 

ポップアップ認証サイトや、Basic認証以外の認証を経由した

サイトへのアクセスも含めてシナリオテストへ反映したい、という

場合なんかはSeleniumでやった方が楽な部分も多いですね。

(といっても座標指定など結構、力業な部分が多いですがw)

ただ、PythonユーザーだとMicrosoft Edgeブラウザはドライバが

提供されていませんので注意が必要です。(C#Javaが提供中)

 

今回はこんなところで。

Log Analytics(Azure Monitor Logs) + Azure Monitor Alert Rule + Runbook PowerShell + SendGrid

タイトルで、ある程度何やろーとしているか想像できる方は

きっともうAzureの初心者ではなさそうですね。

そしてやろうとしたけどなんだかうまくいかねぇーって泣きそうな

顔してる方もいらっしゃるかと思うので疎通とった記事をまとめて

おきますかね。

 

今回の記事でやりたいことは以下です。

f:id:akazure:20190308171511j:plain


 

やりたいのは、特定のログを定期的にチェックし、閾値を超えて検知

された場合は、一次処理を行った上でメールで終わったよ通知したい、

というものです。

 

①、ここは純粋にLog Analytics(Azure Monitor Logs)のワークスペースVM

  入っているomsagentからのログを飛ばすだけ。

②、Log Analyticsのワークスペースで検索したクエリ(Kusto)から、特定の

  ログを抽出し、その件数を閾値にアラートルールを作成。

③、アラートルールではAzure Automationアカウントに登録してある

  Powershell Runbookを実行するように指定。

④、Runbook内に登録したPowershellでは、特定のAzure VMのステータスを

  確認。

⑤、VMステータスをメール本文に入れてSendGridへ送信。

⑥、管理者(ここでは私)がメールの通知を受け取ってハッピー。

 

この①~⑥を自動実行(定期実行)したいわけですね。

ということでAzure上で必要なコンポーネントを並べると以下です。

 

● Azure Log Analytics (Azure Monitor Logs)

● Azure Monitor

● Azure Automation

Powershell スクリプト

● SendGrid

 

じゃ早速いってみましょー。

 

今回疎結合された単体テストができるよう進めているので、以下の

2系統で進めます。

 

1系統:Automation powershell runbookの動作(④~⑥)

2系統:Log Analytics (Azure Monitor Logs) とAzure Monitorの設定(①~③)

 

まず最初に準備するのはAzure MarketPlaceにあるSendGridです。

ここは単純にFreeプラン(無償)でアカウント作ってパスワード設定

するだけなので割愛します。

smtp serverと587 submissionポート接続用にユーザー名とパスワード

 はどこかにメモっておいてね。(SMTP認証するんで)

 

次にAzure Automationを用意しておきましょ。Azutomationアカウント名

は任意で作成しておいてください。

 

最初にやるべきは「Azure モジュールの更新」!!

これをやっておかないと、1.2.1といった超絶古いバージョンのpowershell

モジュールを使った処理がAuzre Automation側で実行されるので

1.2.1の記載をしなければ動かないです。また、ローカルPCで動いてる

hogehoge.ps1が5.7.1とかのバージョンで動作していると、動かないん

だけどー?って事態になります。(結構落とし穴w)

 

f:id:akazure:20190308095521j:plain

更新するとこんな感じです。(10分ぐらいで終わります)

最新すぎるだろ!って突っ込みはスルーして進めますw

 

続いてRunbookを開いてPowershellをコネコネしていきます。

f:id:akazure:20190308095804j:plain

Runbookの作成、から、powershellを選びます。

Python2やグラフィックpowershell ワークフローなんかも選べます。

※Python3マダー

 

で、ぶちこむPowerShellはこんな感じ。

powershell/automationpowershell.ps1 at master · akkoike/powershell · GitHub

 

入れる変数の説明だけ少し。

$rg_name = ""
$target_vm_name = ""

   ポンチ絵でいう④の部分です。対象となるVM名とRG名を入れましょう。

# Setting for E-mail
$SmtpServer = 'smtp.sendgrid.net'
$Port = 587
$UserName = ''
$Password = ''
$MailFrom = ''
$MailTo = ''
$Encode = 'UTF8'
$Subject = 'テストメール from runbook'

  メールの設定です。MailFromは確実にエラーメールが届くように

  存在するメールアドレスを入れないとRFC的にしばかれます。

 

じゃテストウィンドウからテスト実行しましょ。

f:id:akazure:20190308102213j:plain

ロードして実行されて宛先のメールアドレスにTest Mailという件名のメールが

届いたでしょうかね。本文には対象としたVMの稼働状態を示す文字列が1行だけ

記載されているはず。

※メールこないんだがー、って時は、runbookが正常に終わったのかどうかを

 確認してください。正常に終わっててこない場合は、メールの問題か

 宛先アドレス側で設定されているスパムフィルタの問題などが考えられる

 かな。SendGridポータルで確認してください。

 

ここまでうまくできれば、1系統は終わり。

最後にAutomationのrunbookの画面で「公開」を押しておきます。

※「開始」ではない点注意です。開始は単体で実行してみる、という意味合い

 です。

 

続いて2系統目に入ります。

 

リソース追加からLog Analyticsと検索し、WorkSpaceを1つ作成します。

対象VMのログ設定がまだされていない場合は以下のように設定します。

f:id:akazure:20190308132820j:plain

 

ここではazure01とcentlog001というVM名の2つがLog Analytics WorkSpaceへ

ログを取り込む設定がされていることがわかります。

※しばらくほっておくと左ペインの「ログ」からHeatbeatなどのログが飛んで

 きていることがわかります。また、対象VMを選択した後、Azure Portalから

 該当のVMへ自動的にエージェントをインストールしてくれます。

 LinuxVMならomsagentというプロセスが上がります。

 

ではログ検索にいきましょう。

ここでは単純に「今から10分前までのデータでHeartbeatで出力されたレコード」

を一覧で出しています。

f:id:akazure:20190308133624j:plain

 

Splunkでもそうですが、Log AnalyticsでもKusto(くすと)と呼ばれる

専門の言語をつかって検索クエリをかける必要があります。

 

Heartbeat

| where TimeGenerated > ago(10m)

 

※Heartbeatテーブルの中でTimeGeneratedの時間が10分前のもの、という

 指定です。

 

Linuxのログだとsyslogやカスタムログでも構造的にシンプルな構造に

入っていますが、Windows ServerのAuditlogsやActivityLogsなんかは

ツリー形式で登録されていたりします。

その場合は、mv-expandやprojectという関数を使って整形するとよいです。

 

AuditLogs
| where OperationName == "Add group"
| where TimeGenerated > ago(365d)
| extend localtime = TimeGenerated+9h
| mv-expand TargetResources
| mv-expand InitiatedBy
| project DisplayName = TargetResources.displayName , InitiatedBy.user.userPrincipalName

※AuditLogsテーブルの中で、OperationNameがAdd Groupになっている

 レコードを対象に、JSTで365日前までのデータを対象にする。

 ツリー構造になっているレコード(>TargetResourcesみたいな表示)に

 なっているものは、TargetResourcesとInitiatedByの2つをmv-expandで

 1行に整形し、project関数を使って表示したいdisplaynameとuserPrincipal

 Nameの項目だけを出力する、という命令。(わけわからんよねw)

 

ま、今回はここは難しいクエリにせずにHearbeatの件数を閾値

アラートルールを設定しましょ。

 

f:id:akazure:20190308163721j:plain

 ログ検索した画面の右上にNew alert ruleというボタンがあるので、そこを

クエリ結果が出た状態のままクリックします。

 

f:id:akazure:20190308164248j:plain

 

「条件」を押すと、先ほどかけたクエリがそのまま適用された状態に

右側へブレードが移ります。

基準では、このクエリが出力された結果の”行数”が1以上の場合、っと設定

しています。

最後の評価基準では、このクエリをかける対象範囲を今から30分前までの

データを対象とし、5分間隔で定期実行する、という設定の意味です。

 

完了を押して、次のアクショングループの設定にいきます。

 

f:id:akazure:20190308165827j:plain

 

ここでは1系統目で用意していたRunbook powershellを指定していきます。

特に迷うところはない、かな。

 

最後に「アラートの詳細」で、「アラートルール名」と「説明」を

適当に入力して、「最後にアラートルールの作成」ボタンを押します。

 

以上です。5分間隔で以下のようなメールが飛び続けますw

 

f:id:akazure:20190308170218j:plain

停止するときは以下のようにLog Analytics WorkSpaceの画面で

「警告」>「アラートルールを管理します」「無効化」で停止しましょう。

f:id:akazure:20190308170355j:plain

 

今回はテスト的に疎通を取ることに注力しましたが、いくらでも応用はできます。

VMのステータスを見て、VMを起動、停止するもよし、VM以外のリソースを

コントロールする処理をPowerShellで記載すれば、とあるログの結果から一次処理

を実行する、といったことができます。

また、今回はAutomation Runbook Powershellで行いましたが、アクショングループ

を設定する際にAzure Functionを呼び出すこともLogic Appsを呼び出すことも

できます。このあたりは好みで。

あとLog AnalyticsではHeartbeatテーブルを対象にしましたが、Linuxであれば

rsylogd経由のFacilityに対して独特のログを飛ばし、その独特のログの件数を

閾値に処理を行う、といったことや、Azure VM OS内の個別のログファイルを

対象(カスタムログ)にLog Analytics WorkSpaceへ飛ばすこともできます。

 

「ログから、とある処理を自動実行したいんだけど」

といった状況があれば、上記は1つの解決策ですね。べんりやね~~♪

 

Azure上のZabbixサーバーからPing監視を試す

久しぶりの更新です(ぐはっ)

 

たまに、ですが、オンプレで動いている監視機能要件をAzure

へ切り替えたいんだけど、といったこれまで使っていた監視

システムをベースに、それぞれどうするよ的な話がありますね。

 

もちろんAzure MonitorやLog Analytics、Application Insightなど

監視だけでなく統計、可視化、自動対応などなど様々なソリュ

ーションサービスを組み合わせることでできることも多いですが

「今までやってきた機能要件」をマスト要件とした場合、Azure

だと、、、っと相いれない状況になってくることもあります。

 

代表的なものの1つとしてping(ICMP)の死活監視やSNMP

ネットワーク監視がありますが、いまどきpingで死活監視と

いう会話はなくなってきている一方で、オンプレではそう

やってたのでそのままクラウド上にも、という話や、まずは

AS Isで移行したく、といった話もありーの、なかなか避け

て通りづらい代物でもあります。

 

これから触れる内容はAzure上でZabbixを使いping監視を

やってみるか、というものですが、誤解してほしくないのは

pingを推奨しているわけではない点です。

むしろpingは無くても構わない、ぐらいの感覚でいます。

 

過去pingを悪用された攻撃が話題になりセキュアなやり方では

ない点や、pingはそもそもNiCまでのパケット通信をやりとり

するネットワーク経路を見てるだけで、といった本質的な

観点から「正しい、だから違う手段で」と解釈できる方は

この記事は無用ですので、あらかじめ。

 

でも一方で、Azureでping監視って、そもそも推奨してない

のはわかったけど、やればできるの?とか、AWSでは

セキュリティグループの設定でICMPを許可するってやれば

ICMP通信も個別で許可できるんだけど、AzureのNSG

では現実解として許可できないよね?とか、まぁ、素朴な

疑問を持つ方、自己責任で納得性がほしい方もいらっしゃる

のも事実です。

なので推奨はしないけど、Azureだとこうやればできるけどね

という情報を少し出しておきます。

 

今回やるやり方はZabbixサーバーをAzure上に立て、Azure VM

にZabbix agentを入れて行う監視方法ですが、先に答えを

言っちゃうと、ポイントはOver Internetで通信しない、という

点と監視サーバーは監視対象の同一リージョンには配置しない

という観点です。

 

AzureではLBのVIPもそうですが、そもそもinboundもoutbound

もどちらもping(ICMP)を非推奨としていますので、プロトコル

ポートの制限のないプライベートネットワーク間で監視する

という方針です。

 

でははじめましょ。

 

まずZabbix サーバーを東アジアリージョンで構築します。

監視対象のメインは東日本リージョンと西日本リージョンに

展開されたVMと想定しています。

 

以下、Zabbixサーバー側の環境です。

 

 ・OS:CentOS 7.5

 ・VM Size:D2v3 (Hyper Threadingのやつ:特に意図なし)

 ・Disk: Managed-disk

 ・NiC: 1つ

 ・vNET+Subnet: 10.1.0.0/16 + 10.1.0.0/24

 ・Storage Account: 1つ(診断用)

 ・可用性セット: 1つ(FD3,UD5)

 ・NSG: Public IPに付けた22port/tcpのみ許可

 

Zabbix WebUIにアクセスしZabbixサーバー本体のシステム

情報を見た画面が以下です。

f:id:akazure:20180828173223j:plain

 

構築方法は以下の記事がきれいにまとまってました。

Zabbix 3.0をCentOS 7にインストール

 

Zabbix 4.0は少し提供が遅れているのかな?待ち遠しいですが

ここは3.0でとりあえずやってます。

 

また、上記手順にない部分として以下は適当に対応しておき

ました。

 

〇Adminでのログインパスワードの変更

〇swap領域の設定(CentOS側でswap領域を作成)

 # dd if=/dev/zero of=/var/swapfile bs=1M count=2048
 # chmod 600 /var/swapfile
 # mkswap /var/swapfile
 # vi /etc/fstab

  ⇒ /var/swapfile none swap defaults 0 0
 # swapon -a

  ※これやっとかないとzabbix WebUIではswap領域がねぇ!

   って言われちゃうんで。

〇WebUI画面のカラー変更 

 

ここまでは、とり合えず東アジアリージョンにZabbix

サーバーが1台立った、というだけです。

 

Zabbixサーバー冗長化については多くの記事がありますので

ここでは触れていません。手っ取り早く金かけて解決するなら

Zabbix Enterpriseでサポート契約(有償)することでデータ

移行ツールが手に入るため、そちらを利用して冗長構成を

組むとよいかもしれませんね。

 

また、MariaDBではなくAzure Database for MySQLのPaaS

をZabbixサーバーのDB領域としてご利用される場合は以下の

記事が参考になります。ご参考まで。

Azure Database for MySQL を Zabbix のバックエンドで使ってみる

 

では次に東日本リージョンと西日本リージョンに展開されて

いるAzure Linux VMにZabbix agentを入れたいわけですが

その前にやっておくことが1つあります。

 

Global vNET Peeringの設定です。

Global vNET Peeringは、異なるリージョン間のアドレス帯の

異なるvNET同士をピアリングする、かつ通信はMicrosoft

バックボーン経由で、という超絶目からうろこな機能です。

 

ただ、現時点ではAzure ADテナントが同一である必要がある

ようなので、同じテナント内で管理されているサブスクリプ

ションや1サブスクリプション内で、異なるリージョン間の

vNETをピアリングする場合に有効です。

 

手順はAzure Portalの操作だけで完結しますが、ポイントは

ピアリングしたい元となるvNET側と先となるvNET側の双方で

ピアリングの設定を行うことで、はじめてピアリング接続が確立

するよ、という点です。(片方だけ設定してもダメよ)

 

以下、Zabbixサーバー側のvNETでピアリングする際の画面です。

f:id:akazure:20180829135058j:plain

 

f:id:akazure:20180829135331j:plain

 

f:id:akazure:20180829135403j:plain

 

片方だけの設定だと「ピアリング状態」が「開始済み」になって

いますね。これは双方で設定すると「接続済み」に変わります。

 

今回はvNETセグメントを以下のように設定しておきました。

 

〇東アジアリージョンvNET(Subnet)

 10.1.0.0/16 (10.1.0.0/24)

〇東日本リージョンvNET(Subnet)

 192.168.2.0/24 (192.168.2.0/25)

〇西日本リージョンvNET(Subnet)

 172.10.0.0/24 (172.10.0.0/25)

 

※Global vNET Peeringの状況

10.1.0.0/16 と 192.168.2.0/24 間でGlobal vNET Peering

10.1.0.0/16 と 172.10.0.0/24   間でGlobal vNET Peering

 

どちらも「接続済み」ステータスが確認できれば、Zabbix agent

のインストールにいきます。

 

以下の記事がまとまってて参考になります。

Zabbixエージェントの設定 (CentOS編)

 

※最後のfirewall-cmdの個所ですが、ここはポートを追加して

 いますので、最後に「firewall-cmd --reload」を叩いて反映

 させましょう。

 あと、最後に以下でagentを起動/確認しましょう。

 

# systemctl start zabbix-agent

# systemctl enable zabbix-agent

# systemctl status zabbix-agent

 

ここまででサーバー側/OS側の作業は終わりです。

あとはZabbixのログイン画面にAdminでログインして

設定>ホスト>ホスト追加 から東日本リージョンと

西日本リージョンのVMを指定してあげましょう。

テンプレートは標準にあるTemplate OS Linuxでとりあえず

よいでしょう。

 

ちなみにTemplate OS LinuxにはZabbix agent pingという

のが含まれていますが、ここではあえてicmppingをアプリ

ケーション+イベント登録して実装してみました。

 

以下のping-checkという名前が東西の仮想マシンに適用した

時の画面です。

f:id:akazure:20180829135523j:plain

 

グラフで見ると以下のようにちゃんと取れているようです。

f:id:akazure:20180829135629j:plain

 

念のためAzure Portalから西日本リージョンの仮想マシンを停止させた

時のグラフです。ちゃんと1から0に変わってますね。

f:id:akazure:20180829135739j:plain

 

pingのテンプレートについては以下が参考になります。

Zabbix 3-1. サーバ死活(Ping)監視テンプレート設定 | あぱーブログ

 

バージョンが異なるので見た目が違う部分はありますが

基本的な流れは上記の通りで設定できます。

 

最後に、注意点を1つ伝えておきます。

オンプレでは専用の回線を直結して、といった環境のため占有

リソースで組み立てられていますが、パブリッククラウドでは

共有リソースになるため、一時的にスループットが落ちたり

裏側のメンテナンスによってデータの反映が遅れるケースは

あります。

 

Zabbixは柔軟にカスタマイズできる分、監視するポーリングの

頻度やリトライの閾値などを監視項目別に設定できますが、

オンプレで正常だったから、という理由でそのままの閾値

パブリッククラウドへ展開すると、エラー検知の頻度が上がり

都度細かく調査しても結果的にサービスへの影響はほとんど

ないのに過剰検知されたため調査時間や対応時間だけが無駄に

かかった、とか、冗長構成とってたけど死活監視で死んだと

判定されたためPrimaryが切り替わった、といったことが発生

します。パブリッククラウド上で監視するための閾値設定に

ついては、オンプレとは別軸で再度見直す&試験運用する

ことをお薦めします。

 

以上ですが、要点をまとめると以下です。

 

〇監視システムは監視対象リージョンとは異なる地域に

 配置すべし

NSGで制御できないプロトコルを使った監視は

 Over InternetのPublic IPの経路で監視せずにPrivate IP間

 で監視すべし

〇Azure Global vNET Peeringを活用すべし

〇監視閾値は利用するパブリッククラウドの稼働状況を

 試験運用期間を通じて見定めていくべし

〇Azureが提供される機能に満足できない場合はOSS

 積極的に試すべし

 

今回はこのへんで。

 

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

 

 いじょ。