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」を選択します。
入力項目がいくつかありますが、ポイントは「サーバー管理者ログイン名」
と「管理者パスワード」、「価格レベル」の3つです。
ここではデフォルトの汎用目的の価格レベルを選択しています。
2vCPU、5GBストレージ、保持期間7日ですが、vCPUは最大32、
ストレージは最大2TB、保持期間は最大35日になってますね。
(2018/5現時点)
作成が終わったら「接続のセキュリティ」を覗きます。
上記の設定はcentclient101というVMのPublic IPからのみSSL接続を許可する
という設定です。Blob storageやSQL DatabaseのようにvNET統合(vNET
アドレスからの接続のみ許可)は、まだ未対応なので気長に待ちましょ。
次に「接続文字列」を覗いてみましょうか。
各言語ごとにどうやって接続するかのサンプルコードが並んでますね。
便利ですね!あ、でもLinux環境でmysqlコマンド使った接続サンプルが
記載されてないので、今回はそちらを試してみましょうか。
ということで先ほどSSL接続を許可したVM(centclient101)に一旦
ログインしましょ。mysqlコマンドを使うのでmysqlをyum installします。
CentOS7xだとmariadb.x86_64がインストールされ、/usr/bin/mysqlが
インストール時に展開されます。
早速接続してみたいところですが、先ほどSSL通信のみ許可する形をとったので
以下のサイトからpemファイルをwgetで持ってきましょう。
Azure Database for MySQL に安全に接続するために SSL 接続を構成する | Microsoft Docs
では早速接続してみます。
うまく接続できましたね。
画像だとコピペできないので以下に記載しておきます。
/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という名前のデータベースを作成しました。
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ライブラリの配置場所確認
※CentOS7.3ではmlocateがデフォでインストールされています。
ファイルの配置場所がわからない時はlocateコマンドで部分一致
検索を使うと便利です。
「locate connector」
(出力されない場合はupdatedbコマンドを叩いた後に実行しましょ)
crontabでmysql.shを毎分実行しMySQLに登録された結果は以下です。
メンテ情報が出力された場合はこんな感じで見えます。
時間帯を前方一致検索するとこんな出力になります。
といった感じで、スケジュールされたメンテ情報を定期的に
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
OSSのMySQLと同じ操作で同じように扱えるというのはいいですね。
LAMP構成のオンプレ環境をAzureへ移行したい方はご参考まで。
今回はこのへんで。