Ubuntu14.04にCloudMapperをインストール

同僚が社内チャットで教えてくれたCloudMapperが面白そうだったのでインストールして試してみました。

www.publickey1.jp

インストールするまで微妙にハマったのでメモを残します。

CloudMapper を動かすまで

$ sudo apt-get install autoconf automake libtool python-dev jq python-pip
  • AWS CLI のインストール
$ sudo pip install awscli
$ aws configure  
AWS Access Key ID [None]: (各自の環境に応じて)  
AWS Secret Access Key [None]: (各自の環境に応じて)   
Default region name [None]: (各自の環境に応じて)  
Default output format [None]: (各自の環境に応じて)  
  • CloudMapperのインストール
$ git clone https://github.com/duo-labs/cloudmapper.git
$ cd cloudmapper/
$ pip install -r requirements.txt
  • 後々必要になるpipモジュールのインストール
    • この後の手順でいろんなPythonスクリプトを実行するが、pipライブラリが足りなければその都度エラーで怒られるのでインストールしていく
    • 自分の環境の場合、以下の3つを入れたら最後まで進めました
$ sudo pip install boto3 pyjq netaddr
  • AWSのアカウント情報をCloudMapperの設定ファイルに書く
    • config.json.demo を config.json にコピーして自分のAWSのアカウントIDに書き変える
    • name は自由につけてOK。例えば dev とします
    • ciders のところはよくわからず。変更しなくても動作はしてるっぽい?
$ cat config.json
{  "accounts":
    [
        {"id": "xxxxxxxxxxxx", "name": "dev", "default": true}
    ],
    "cidrs":
    {
        "1.1.1.1/32": {"name": "SF Office"},
        "2.2.2.2/28": {"name": "NY Office"}
    }
}
  • AWSアカウント内の構成情報を集める
$ python cloudmapper.py gather --account-name dev
  • CloudMapper表示用にデータを整形する
$ python cloudmapper.py prepare --account dev
  • Web サーバを立ち上げて公開する
$ python cloudmapper.py serve
  • これだとローカルホストから http://127.0.0.1:8000 でならアクセスできるものの、リモートからアクセスできない。 リモートからアクセスする場合は --public オプションをつける。
$ python cloudmapper.py serve --public

結果

f:id:kmiya_bbm:20180223171914p:plain

ちゃんと情報取れてそう! 吐き出された図はそのままでは見にくいところもあるので、手でグリグリ修正するほうが良さそうです。

Amazon Cognito の SDK for JavaScript と CLI と API と、それらに対応するIAMポリシーを整理する

Cognito まわりのSDKCLIは、AWSのサービスの中でもなんだかすごくややこしい気がする。
公式ドキュメントを読み込んだところ、まとめるとたぶん下の表みたいになるはずなんだけれど、合っているか非常に自信がない。

SDK for JavaScript CLI API IAM
User Pool AWS.CognitoIdentityServiceProvider aws cognito-idp Amazon Cognito User Pools API cognito-idp:**
Federated Identities AWS.CognitoIdentity aws cognito-identity Amazon Cognito Federated Identities API cognito-identity:**
Sync AWS.CognitoSync aws cognito-sync Amazon Cognito Sync API cognito-sync:**

さらに Higher-Level Client SDKs としてAmazon Cognito SDK for JavaScript amazon-cognito-identity-js というSDKがあり、SDKs for Amazon Cognito User Pool App Integration and Federation ?として Amazon Cognito Auth SDK for JavaScript amazon-cognito-auth-js というのがある模様。

docs.aws.amazon.com

きびしい・・・。

AWS re:Invent2017 の会場でソリューションアーキテクト - アソシエイト を受験して合格した

年末年始のバタバタにかまけてすっかりブログを書く機を逸してしまいましたが、昨年、念願だったAWS re:Invent に初めて参加しました。 イベント自体からも他の参加者からもいろんな刺激を受けまくって、とても充実した一週間でした。

あまりにも刺激を受けすぎて、当初全く受験する予定のなかったAWS認定試験を、その場の勢いでre:Invent最終日に滑り込みで受験したのでその顛末を記そうと思います。
なお、試験対策的な情報は一切ありません。実際受験する流れはどんな感じなのかについての単なる自分用の記録ですが、もしもAWS認定試験に興味がある方のお役に立つことがあれば望外の喜びです。

受験のきっかけ

re:Invent最終日の前日(11/30)、前々から興味はあったAWSの認定試験を受けてみようと急に決めました。そう思い立った要因はいくつかあったのですが、AWS re:Inventの会期中ずっとAWSの情報漬けになっていたので、それらのアウトプットとして何か形に残したくなったのと、道中で知り合って滞在中ずっと仲良く付き合ってくれた日本からの参加者の方の一人がソリューションアーキテクト のプロフェッショナルを持ってらしたのに刺激を受けたのが大きいです。ラスベガスとre:Inventの空気感で受験費用がなんか安いと錯覚できたのもあったかもしれません。いや、確実にありました。勢いは大事だなと思います。

受験までの流れ

で、いきなり Mirage の試験会場に行って「今から試験受けられる?」と聞いてみましたが、事前に登録が必要なことがわかりました。そのへんは通常の認定試験のフローと何ら変わらないようです。

webからAWS認定アカウントの作成と試験予約を行うことができます。 AWS認定アカウントのマイページにある「新しい試験の予約」というボタンから試験の会場と日程を決める画面に遷移します。 普通なら、ここで自宅から近い会場を選択すれば良いわけですが、今回はre:Inventの会場で受験するため The Mirageを探す必要があります。

The Mirageの住所は以下の通り。

3400 S Las Vegas Blvd
Las Vegas, NV 89109

個人的には試験そのものよりもこの事前登録のほうが難しかったと感じました。

当日のうちに受験したかったのですが、あいにくその日の日程は埋まっていたため翌日12/1の午前中の日程に申し込みました。

受験当日

試験開始時間の30分前には受付に来るよう言われていたのですが、到着するとすでに受付には結構な行列ができていて、なるほど30分の余裕は必要かなと思いました。受付では写真付きの身分証明書を2つ提示すること求められますが、re:Inventの会場では re:Inventの参加証 + パスポート でOKでした。無事に受付が済むと、番号が書かれた紙のカードを貰えます。これが試験会場で着席する席の番号となっています。 会場が乾燥しているからか、受付では自由にもらえるトローチが用意されていました。

f:id:kmiya_bbm:20180112125817j:plain 受け付け・待合場所の様子

時間になると待合室に試験監督の方が来て受験者に注意事項をアナウンスします。それが終わると、別室の試験会場に移動します。自分が受験した回の受験者は30人ほどはいたでしょうか。結構な人数がいた気がします。

スマホなどは電源を切らなければいけないので写真は撮ってないのですが、試験会場はかなり広い部屋にデスクトップPCが置かれた長机が何列かズラーっと並んでおり、自分の番号の席を自分で探します。隣の席との間につい立て等はなく、本当に長机にPCが並べて置いてあるだけ、という感じでした。

リュックなどの大きな荷物は壁際の棚に、ウェストポーチのような小さな荷物は自席の椅子の下におきます。バッグを持っていない場合は、受付で透明なビニール袋がもらえるのでそこにスマホや財布を入れて自席の椅子の下に置きます。

最初、自席のPCで、試験を受けるためにAWS認定アカウントにログインして間違いがないか確認するよう指示が出るのですが、その後は試験開始の合図等はなく、各々試験を始めていました。これには最初ちょっと戸惑ったのですが、試験時間が異なるアソシエイトレベルとプロフェッショナルレベルの受験者が同じ試験会場にいたっぽいことと、試験を開始したところからPCの画面上に残りの試験時間が表示される形式になっていたことから、各々勝手に試験を始めてよかったのだろうと安心しました。

試験の内容については公式の情報や参考書、いろんな方のブログに載っているので割愛しますが、自分の場合はEBSについての知識があやふやで勉強し直す必要を感じました。

全ての問題の回答と確認が終わったら、PC上で終了ボタンを押して合否の結果を確認します。そして挙手して試験監督さんに退出する旨を申告します。 合否はすぐに表示されるのですが、合格していても試験会場なので声に出して大喜びすることが出来ず、試験会場を退出するまでひとりニヤニヤしていました。 試験会場を退出したら、受付に戻って合格した旨を伝えます。受付の人たちがハイテンションで祝福してくれたのでとても嬉しかったです。その場でTシャツがもらえるので、サイズを申告して受け取ります。

f:id:kmiya_bbm:20180112131537j:plain
かわいいドット絵が描かれたTシャツ。やったー

合格すると

Tシャツやステッカーなどの記念品がもらえるほか、会場内に設置されている認定者ラウンジに入ることができるようになります。 認定者ラウンジはAWS Summit Tokyoなどでも設置されていますが、どの種類・レベルでもいいので1つでもAWS認定を持っていれば入ることができます。 中では電源や軽食、ドリンクなどが用意されている他、認定者同士で交流しやすくするためか休憩スペースやゲームなども設置されています。
f:id:kmiya_bbm:20180112221004j:plain f:id:kmiya_bbm:20180112221048j:plain

随感

AWS re:InventというAWSの各種イベントの中でも最も熱量が高いであろう空気感に当てられて受験しましたが、無事に合格できてよかったです。

IT系の資格というのはなかなかとらえ方が難しく、資格を持っていれば実力があるというわけでもないですし、実力はめちゃくちゃあっても資格の類を一切取ってない人もいます。自分が勤めている会社は製造業で、IT企業や、ましてSIerの会社ではないので、IT系の資格は受験料も自腹ですし、合格しても一時金や昇給などの実利はありません。
それでも自分はIT系の資格試験に挑戦すること、合格することには一定の意義があると思っています。

  • 業務 +αの勉強をする習慣をつけることができる
  • 業務では触れない分野の知識も試験のために勉強することがあり、見識が広がる
  • 合格すると、一定の知識量や実力を必要とする資格に合格できる程度の「学習力があること」を対外的にも自分自身にも示せる

つまり、継続して学ぶ習慣をつけるきっかけとして資格試験というのはいいモチベーションになるのではないかと考えています。

今回、AWSの認定試験を受験すること自体は突発的に決めたことでしたが、AWSなどのクラウドサービスについて調べたり学んだりすることはずっと続けていた(AWSは東京リージョンができる前から追っていた)ことであり、アソシエイトレベルではありますが今回ソリューションアーキテクトの認定に合格できたのは継続的な学習の成果だと思っているのでとても嬉しかったです。

まとめ

AWS re:Invent2017の会場でAWS認定試験を受験したときの流れをまとめました。
AWSの認定資格は初級レベルでもなんでも1つ持っていれば認定者ラウンジに入ることができたり記念品がもらえたりするので、普段AWSを利用している方は認定試験を受けてみるのもよいのではないでしょうか。

AWS Lambdaを1分間隔より短い間隔で定期実行させる

やりたいこと

タイトルの通りです。

AWS LambdaのトリガとしてCloudWatch Events Schedule を指定することで、Lambdaを定期実行することができます。

docs.aws.amazon.com

しかし、Unix系OSのCronと同様、1分間隔より短い間隔を指定することはできません。

Rate または Cron を使用したスケジュール式 - AWS Lambda

現状 CloudWatch Events Schedule によって1分間隔で起動させているLambdaを、10秒間隔、15秒間隔など秒単位で定期実行したい要件があり、実装方法を検討したのでその結果を残します。

Lambdaを定期的に起動するLambdaを導入してみた

1分毎に起動して、指定したLambdaを指定した間隔で起動し、1分後に終了するLambdaを作れば良いのでは、という案を思いつきました。 10秒間隔で Lambda を定期実行させる Lambda をNode.js v6.10 で素朴に作ってみました。

gist.github.com

funcName に1分間隔より短い間隔で定期実行させたいLambdaの名前を指定します。 このLambda を CloudWatch Events Schedule で1分間隔で定期実行させることで、このソースコードの例では10秒間隔で指定したLambdaを定期実行することができます。

注意点

  • funcName に指定した Lambda (10秒間隔で実行したいLambda)のトリガとしてCloudWatch Events Scheduleの定期実行設定が残っていると多重起動してしまうので、そちらのトリガは削除しておかないといけません
  • この「10秒間隔で Lambda を定期実行させる Lambda」に割り当てるIAMロールへは、InvokeするLambda(10秒間隔で実行したいLambda)に対して lambda:InvokeFunction Actionを実行できる権限を付与しておく必要があります
  • この「10秒間隔で Lambda を定期実行させる Lambda」のタイムアウト値は 60秒以上を設定する必要があります

...あれ?

できたはできたけど...

注意点の最後に挙げた項目が Lambda の、というかイベント駆動で動くFaaSの旨味を思いっきり消してしまっている気がします。 要するにこの「10秒間隔で Lambda を定期実行させる Lambda」は1分間起動し続けていなければならず、それもうEC2でも良くね?という気持ちが芽生えてきます。

実際にLambdaとEC2でそれぞれ1日中稼働させた場合のコストを比較すると、

Lambdaで運用

  • メモリ割当 128MB、1回あたりの課金時間を 61,000ms(61秒)とする
    • 実際には60,600ms くらいで終わることも多いのですが、ここでは多めに見積もります
  • 1日の実行回数は 1440回
    • 60(min) × 24(h)
    • 毎月最初の 1,000,000 回は無料、かつ、それ以上実行しても $0.0000002 /回 という安価さなので計算から除外する

料金 - AWS Lambda(サーバーレスでコードを実行)|AWS

$0.000000208(/100 ミリ秒) × 610(100ミリ秒/回) × 1440(回) =$0.1827072

EC2で運用

  • オンデマンド料金で算出する
  • インスタンスタイプは一番小さい t2.nano、台数は1台とする

オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS

  • 東京リージョンの場合

$0.0076(/1h) × 24(h) = $0.1824

$ 0.0058(/1h) × 24(h) = $0.1392

結論

費用面だけ見ると、EC2(t2.nano)を常時起動していても対して変わらない、むしろ安い場合もある。という結果になりました。 しかし、EC2上で秒単位で起動するworkerを動かす場合と比較して、Lambdaで実行するのには以下のメリットがありそうです。

  • 実装が簡単
  • コケても次回(1分後)の実行に影響が出ないので一度軌道に乗れば運用は楽
  • そもそもLambdaの実行のためにEC2を動かすのはなんかスッキリしない

逆に、何らかの用途ですでに常時起動しているEC2がいる場合はコストを考えて秒単位で起動するworkerを相乗りするのも手ですね。

・・・ひどく当たり前の結論になってしまいました。
秒単位でLambdaを定期実行したいときって、どうするのがスマートなのでしょうね??

Mackerelの公式プラグインをAWS Lambdaで実行してAmazon RDS for MySQL を監視する

Mackerelの公式プラグイン集や公式チェックプラグイン集は、各種ミドルウェアの詳細監視ができたり、AWS Integrationを使わなくてもRDSやELBなどのマネージドサービスのメトリック情報を取得することができたりと、大変便利なものです。

github.com

このプラグインAWSのEC2など mackerel-agentがインストールできる環境からは簡単に使うことができるのですが、例えばAWS上に Web-アプリケーション-DB の3層アーキテクチャを構成している場合に、EC2がAutoScaling対象のWebサーバやアプリケーションサーバしかないことがあり、DB(RDS)を監視するのにこのプラグインをどのEC2から使うか、少々悩ましいことがあります。

  • AutoScaling対象のEC2全てからプラグインを実行する場合
    • チェックプラグインの場合、RDSに異常が発生するとAutoScaling対象のEC2の台数分(重複して)アラートが上がってしまう
  • AutoScaling対象のEC2とは別に、RDS監視用のEC2を用意する場合
    • 監視用EC2に障害が発生するとRDSの監視が止まってしまうので、冗長構成にするなど監視用EC2の可用性を高める工夫をしなければならない
    • 監視用EC2自体の監視も必要になるため、Mackerel監視対象のホスト数が増えてしまう = コストが増えてしまう ことになる

そこで、この便利なプラグインAWS Lambdaから定期的に実行できれば、安く*1、アラートも重複せず、安定してRDSなどのマネージドサービスを監視できるのでは、と考えました。

この記事では、MySQLのメトリックを取得する mackerel-plugin-mysql を使ってAmazon RDS for MySQL を監視する例をまとめます。

事前準備

AWSやMackerelのアカウントは取得済みとします。
またAWS上にすでにシステムは稼働しており、監視対象の RDS for MySQLの構築やその他セキュリティグループ等の設定は済んでいるものとします。

公式プラグインのバイナリを用意する

AWS Lambdaで実行できる形式のバイナリファイルを作成するため、一時的にEC2を立ち上げます。
まずはAWS公式サイトの情報を元に、AWS Lambdaの実行基盤となっているAmazon LinuxのAMIイメージを探します。 2017/10/15 時点だと amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2 です。

docs.aws.amazon.com

当該AMIを使ってEC2インスタンスを起動します。

  • インスタンスタイプは t2.micro で十分です
  • VPCやネットワーク、セキュリティグループについては、監視対象のRDSと通信できるようになっている必要があります

起動したEC2にSSHでログインし、mackerel-agent, 公式プラグイン集 mackerel-agent-plugins をインストールします。

$ curl -fsSL https://mackerel.io/file/script/amznlinux/setup-all-yum.sh | MACKEREL_APIKEY='<YOUR API KEY>' sh
$ sudo yum install mackerel-agent-plugins

Mackerelのプラグインが正しくインストールされたかを確認するため、手動でpluginのコマンドを実行してみます。
-host オプションで指定するRDSのエンドポイントはAWSマネジメントコンソールのRDSのメニューから確認してください。

$ mackerel-plugin-mysql -host=sample-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -username=<USER_NAME> -password=<PASSWORD>

以下のように、{metric name}\t{metric value}\t{epoch seconds} (\t はタブ文字) の形式でたくさんの情報が標準出力に表示されれば成功です。

mysql.innodb_buffer_pool.pool_size      38208.000000    1507986274
mysql.innodb_buffer_pool.database_pages 2717.000000     1507986274
mysql.innodb_buffer_pool.free_pages     35484.000000    1507986274
mysql.innodb_buffer_pool.modified_pages 0.000000        1507986274
mysql.innodb_row_lock_waits.Innodb_row_lock_waits       0.000000        1507986274
mysql.innodb_adaptive_hash_index.hash_index_cells_total 1238989.000000  1507986274
(中略)
mysql.innodb_semaphores.spin_waits      0.000000        1507986274
mysql.innodb_semaphores.spin_rounds     0.000000        1507986274
mysql.innodb_semaphores.os_waits        0.000000        1507986274

MackerelにRDS用のホストを登録し、メトリックを投稿する

先ほど立ち上げたAmazonLinuxのEC2に、Mackerel の CLIツールである mkr コマンドをインストールします。

$ sudo yum install mkr

Mackerelに監視対象のRDSをホストとして登録します。
以下の例ではホスト名をtest-RDS、Mackerel上のロール名を TEST:DB としてホストを作成しています。

$ mkr create test-RDS -R TEST:DB
   created SAMPLE12345

成功するとHostIDが表示されるので、これを控えておきます。 今回だと SAMPLE12345 です(実際には11文字のランダム文字列)。
Mackerelの画面でもホストとサービス・ロールが登録されていることが確認できます。

f:id:kmiya_bbm:20171014223900p:plain

続いて今登録したホストのカスタムメトリックとしてRDS上のMySQLのメトリック情報を投稿します。 先ほど動作確認に使ったコマンドの結果をパイプで mkr throw に渡してMackerelに投稿します。

$ mackerel-plugin-mysql -host=sample-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -username=<USER_NAME> -password=<PASSWORD> | mkr throw --host SAMPLE12345

以下のような結果が標準出力に表示されれば成功です。

thrown SAMPLE12345 'custom.mysql.join.Select_full_join      0.000000        1507987901'
thrown SAMPLE12345 'custom.mysql.join.Select_full_range_join        0.000000        1507987901                                           '
thrown SAMPLE12345 'custom.mysql.join.Select_range  0.000000        1507987901'
thrown SAMPLE12345 'custom.mysql.join.Select_range_check    0.000000        1507987901'
(中略)
thrown SAMPLE12345 'custom.mysql.innodb_buffer_pool_read.read_evicted       0.000000        15                                           07987901'
thrown SAMPLE12345 'custom.mysql.innodb_buffer_pool_read.read_random_ahead  0.000000        15                                          07987901'
thrown SAMPLE12345 'custom.mysql.innodb_checkpoint_age.uncheckpointed_bytes 0.000000        15                                          07987901'

Mackerel上で見てもメトリックが投稿されグラフが作成されていることがわかります。

f:id:kmiya_bbm:20171014223725p:plain

ここまでの手順で作成したプラグインや mkrコマンドのバイナリファイルを、普段お使いの開発マシンなどにコピーしておきます。
このAmazonLinux EC2についてはLambda上で実行できる形式のバイナリファイルを作成するのが目的だったので、もう停止・削除してしまって構いません。

AWS Lambdaから実行できるようにする

今までの手順で作成した (Lambdaの実行基盤であるAmazonLinux 上でインストールして生成された) mackerel-plugin-mysql と mkr のバイナリファイルをLambdaのコードと一緒に固めてアップロードし、ハンドラ関数の中でそのバイナリファイルを実行するようなLambdaファンクションを作ります。それをCloudWatch Eventsで定期スケジュール実行すればよいことになります。

今回はCloudWatch EventsやIAM Role等の周辺設定を自動で行うため Serverless Framework (v1.23.0)を使って Node.js 6.10 のLambdaファンクションを実装しました。 Serverless Framework のインストール手順やサービス作成手順等は公式サイトやネット上に情報がありますので割愛します。

(任意のディレクトリ)/
 ├ .gitignore
 ├ bin/
 │ ├ mackerel-plugin-mysql
 │ └ mkr
 ├ handler.js
 ├ package.json
 └ serverless.yml

  • serverless.yml
service: sls-postCustomMetricToMackerel # 任意のサービス名

provider:
  name: aws
  runtime: nodejs6.10
  region: ap-northeast-1 # 監視対象のRDSがあるリージョン

functions:
  mackerel:
    handler: handler.postCustomMetricToMackerel
    name: ${self:service}
    events:
      - schedule: rate(1 minute)  # CloudWatch Eventsで1分毎にスケジュール実行
    environment:
      DBHOST: sample-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com  # 監視対象のRDSのエンドポイント
      DBUSER: sampleuser  # 監視対象のRDSの接続ユーザ名
      DBPASS: S@mple      # 接続ユーザのパスワード
      MACKEREL_HOSTID: SAMPLE12345 # 監視対象のRDSのMackerel上のHostID
      MACKEREL_APIKEY: # MackerelのAPI KEY
    vpc:
      securityGroupIds:
        - sg-xxxxxxxx      # 監視対象のRDSにMySQL接続できるセキュリティグループを指定
      subnetIds:
        - subnet-yyyyyyyy  # 監視対象のRDSにMySQL接続できるサブネットを指定
        - subnet-zzzzzzzz  # 監視対象のRDSにMySQL接続できるサブネットを指定

簡単のため、DBの認証情報をそのまま環境変数に渡していますが、実運用上はKMSなどで暗号化して渡し、Lambdaの中で復号して使うのが良いでしょう。

  • handler.js
'use strict';

const exec = require('child_process').exec;

const dbhost = process.env.DBHOST;
const dbuser = process.env.DBUSER;
const dbpass = process.env.DBPASS;
const mackerelhostid = process.env.MACKEREL_HOSTID;
const mackerelApi = process.env.MACKEREL_APIKEY;
const basedir = process.env.LAMBDA_TASK_ROOT;

const cmd = `${basedir}/bin/mackerel-plugin-mysql -host=${dbhost}
               -username=${dbuser} -password=${dbpass}
             | MACKEREL_APIKEY=${mackerelApi}
               ${basedir}/bin/mkr throw --host ${mackerelhostid}`;

module.exports.postCustomMetricToMackerel = (event, context, callback) => {
  let child =  exec(cmd, function(err, stdout, stderr){
    if (!err) {
      console.log('standard out: ' + stdout);
      console.log('standard error: ' + stderr);
      callback(null, 'Success!');
    } else {
      console.log("error code: " + err.code + "err: " + err);
      callback(err);
    }
  });

};

sls deploy コマンドでデプロイすると、LambdaファンクションとそのトリガとなるCloudWatch Events、Lambdaファンクションに割り当てるIAM Roleが作成されます。 AWS Lambdaのコンソールからテスト実行して成功すれば、あとは放っておくだけで1分毎に RDS for MySQL のメトリック情報がMackerelに投稿されます。

f:id:kmiya_bbm:20171015213920p:plain

まとめ

Mackerelの公式プラグインAWS Lambdaで定期実行する仕組みを試作しました。これにより、監視専用のEC2インスタンスを立ち上げることなくRDSなどのマネージドサービスの監視を行うことができました。
ただし、実運用に投入する際はCloudWatch AlarmなどでこのLambdaファンクションが正常に実行されているかなどを監視する必要があります。

*1:AWS Integrationを使わないので、MackerelのFreeプランでも利用できます

Mackerel Day #mackerelday に参加してきました

昨日(もう一昨日になっちゃった)開催されたMackerel Dayに参加してきました。

mackerelio.connpass.com

とても有意義で楽しいイベントだったので、手元のメモをここに残します。 スピーカーの方の本名を書いて良いものなのかどうかわからなかったので、Connpassページにお名前が記載されている方のみお名前も書いています。

Mackerelリリース3周年の振り返りとこれからの成長について

Mackerel プロデューサー 杉山 id:sugiyama88 さん

  • 現在166週連続リリース中
  • 直近の主要なリリース
    • Azureインテグレーション
    • グラフボード機能
      • Services のページ内に任意のグラフを集めたタブを作成可能
    • システムプラットフォームの堅牢化
    • AWS DevOps Competency
      • 日本企業で初認定

Mackerelは構成管理系の機能が拡充してきていて、もはや監視ツールというよりは動的に変化するシステムにリアルタイムに追従できる「現状把握」の「プラットフォーム」になってきているな、と感じました。

アプリケーションエンジニアがMackerelで楽しく監視構成している事例

www.slideshare.net

  • 導入背景
    • インフラをオンプレからクラウド(AWS)に移行していった
    • それに伴いサービス運用の責任分界点が変わった → アプリ開発者がインフラもやることになった
    • 監視サービスを独自にホストするのは厳しい
  • 最初はCloudWatch + Lambda → Slack通知 でやっていた
  • 導入にあたり、自分たちが運用するにあたっての利便性 を観点にいくつかのツールを比較検討した
  • 監視構成
    • TerraformでAWSリソースを構築、Ansibleでmackerel-agentを含むVM内容を構成
    • 監視対象はEC2、ALB、RDS
      • EC2
      • その他
        • AWS Integrationにおまかせ
  • 監視設定の管理
    • Jenkinsから mkr monitor push
    • 設定のJSONはGit管理
    • チャンネル設定は手作業
  • 得られた価値
    • 楽 である
      • 想定通りに平易に監視を構成できた
      • つまづくところがほぼなし
    • 楽しく 監視構成
      • 何をすればどうなるかがわかりやすい
      • やってみて反映されるまでが早い
    • 通知時のグラフでぱっとヤバさがわかる
      • アプリケーションエンジニアでも異常がわかる
  • まとめ
    • 導入が楽で運用が楽しい
    • 監視結果を受けての改善サイクルができつつある

アプリケーション開発者の視点から見た監視や監視ツールについてのお話でした。会場アンケートではインフラエンジニアとアプリエンジニアの比率が6:4から7:3くらいだったかと思いますが、ずっとインフラをやってた身からすると「今はこんなにアプリケーション開発者がインフラ監視もしてるのか!」とちょっと驚きでした。

Mackerel インフラ基盤 AWS 移行の舞台裏

  • 8/7,21 にMackerelの基盤はAWSに移行した
    • Mackerelのサービス名を分けて移行した
    • DB、アプリケーション、DNS と切り替えて移行完了
  • なぜAWSに移行したか
    • 時系列データベース
      • ハードウェア的スケールの限界、調達が大変だった
      • データの堅牢性、冗長性の向上を図りたかった
    • データセンター運用コストの削減
      • ハードウェア、リソース管理の人的コストを下げたかった
  • 時系列データベースの移行

    • データセンターで動いているものとAWSで動いているものは別
    • AWSで動いているものは自分たちで作り直した
  • 時系列データベースの運用

    • ほとんどAWSのマネジメントサービス
    • Redis Cluster
      • ElastCacheで運用する想定だったが、動的にスケールできなかった
      • クラスタ作成後のノード追加・削除ができない
    • Redis ClusterをEC2上で動かしている
    • メトリックはredisプラグインで収集している
  • 権威DNSはデータセンターのものを使っている
    • 社内システムを利用する必要があるため
    • ホストのローカルキャッシュサーバに Unboundを使っている
    • MackerelホストのunboundはGoogle Public DNSを見ている
  • AWSのネットワークモニタリング
    • データセンタではスイッチのメトリックを取ればよかったが、AWSでは難しい
    • SNMPプラグイン
      • TCPパケットの再送、再送パケットの割合が見られる
    • AZ間の通信料モニタリング
      • iptablesのチェインで見る
      • VPC Flowlogでなくても見れる
  • Q & A
    • AWSのリージョンは東京か?マルチリージョン化する構想はあるか?
      • リージョンは東京。ディザスタリカバリで他リージョンにコピーを作っておけるというメリットからAWSを選定した
      • URL外形監視の砲台をマルチリージョン化したい みたいな議論はある
    • AWSに移行してコストは安くなったのか?
    • 当初はDCとトントンになる想定だった。今はトントンになるように頑張っている

単純な「オンプレミスからAWSへの移行」事例としてもすごい話だと思うんですが、その上AWSの各マネージドサービスの特性をフルに活かした構成に再構築されているのが凄まじいです。
コストについてはオンプレミスとクラウドで単純比較は難しいですね。AWSでいうMulti-AZはオンプレミスでいえば2か所以上のデータセンタをつないで運用していることになるので、それと比較すれば安いと思われるのですが。

大丈夫! Mackerel には CRE がいます

  • CREとは
    • Customer Reliability Engineer
    • 顧客信頼性エンジニア
  • CREがMackerelチームに在籍していることの意味
  • Mackerelによってユーザに提供されているものはなにか
    • 例えば
      • サーバ監視が効率化される
      • 動的なインフラ管理を実現することでDevOpsが加速される
    • こうした価値はMackerelが利用されることで初めて生まれるもの
    • ユーザが居るからこそMackerelの価値はうまれる
  • Mackerelの価値を支えるもの
    • プロダクトそのもの
      • はてなのエンジニアの高い技術力によって支えられている
    • Mackerelに対するエンジニアの皆様からの信頼
      • 投げかけた質問に的確かつ真摯な回答が得られること
      • わかりやすく正確なドキュメントがあること
      • Mackerelについてまだ知らない方がそれを使うことの便利さや重要性などを短期間で把握できること
  • これらの側面でMackerelに対する信頼性を支えるエンジニアロールがCRE
  • 開発エンジニアとのやりとりも積極的に円滑に行うことで、迅速なレスポンスの維持に努める
    • 同営業日中 90%
    • 翌営業日までに 99%
    • やりとりの往復 2往復以内
    • を達成 (前期実績)
  • 公式ヘルプページなどドキュメントもGitHubレポジトリで管理(Privateレポジトリ)
  • 「CREがいること」も含めてMackerelというサービス

サポートのレスポンスの速さと正確さは本当に驚異的で、これは当然CREのお二方のサポートが卓越しているからだと思うのですが、それだけでなくユーザ側もリテラシーや説明能力が高い人が多いというのもあるのでは、とイベントに参加して周りの方を見ていて感じました。
サービス提供側も利用側もハイレベルですごい世界だなと思います。

freeeでMackerelを使って一年間サービスを運用してみた事例紹介

  • freee 浅羽さん
  • Mackerel導入前はZabbixを使っていた
    • VPC毎にZabbixサーバを運用
  • いくつかのプロダクトを評価
    • 移行のしやすさ
    • プロダクトの進化のスピード
    • 使いやすさ(UI,API,CLI)
    • コスト
      • AutoScalingとの親和性
  • 監視の構成
    • Mackerel
      • リソースの監視、外形監視
      • アラート通知
    • NewRelic
      • アプリケーション内部
    • CloudWatch
      • AutoScalingのトリガとして利用
      • MackerelのAWSインテグレーションでMackerelに情報を集約
    • Bugsnag
      • アプリのエラーログ
    • DeepSecurity as a Service for AWS
      • セキュリティ監視
  • 通常時
    • ダッシュボードかサービス一覧のグラフを眺める
      • 定期的にパフォーマンス振り返り会を実施
      • 手でポチポチ作るのは面倒なのでmkrコマンドで作る
      • さらに深掘りしたいときはNewrelicで確認する
  • 何かあった時やグラフをシェアしたい時
    • チャンネルにグラフを投稿 が超絶便利
  • いつデプロイしたかわかるように記録しておく
  • EC2起動時の初期状態はStandby
    • 初期ビルドがおわったら mkr を叩いてworkingに戻す
    • 構築がコケた場合も mkr を叩いてworkingに戻す → コケたことを検知できる
  • Mackerelに欲しい機能
    • AWSインテグレーションも自動退役機能欲しい

EC2起動時の初期状態をStandbyにしておく、というのが目からウロコでした。AutoScalingでEC2が起動するたびチェック監視に引っかかってたので、早速うちの環境でも取り入れました。
グラフの共有機能でいうと自分はMarkdown形式で共有できるのが気に入っていて、Github/GitLab や Crowi などのMarkdownレンダリングしてくれるWebサービスに張り付けて自作ダッシュボードを作って眺めてます。これだとFreeプランでもダッシュボード作り放題だし複数オーガニゼーションのグラフを並べられて便利!

Mackerelを導入して変わったN個のこと

  • GMO ペパボ 高石 諒 さん
  • 初めて触った監視ツールがMackerel
    • 2015年4月に正式導入
    • 2017年10月5日時点でホスト数1000台
      • サービス 20
      • ユーザ 100
      • ロール 300
      • ホスト 1000
      • サービスメトリック 300
      • 外形監視 70
  • Mackerel導入前の課題
    • Nagiosの管理が大変
      • サーバ追加・削除時に設定ファイルの更新が必要
      • 複数のNagiosサーバがあり、情報が分散
    • クラウドらしい仕組みへの移行
    • 情報の一元管理
      • サーバ自体と、パッケージの情報も管理したい
      • 脆弱性のあるパッケージへのパッチ当て終わったんだっけ?的な。
  • Mackerel実践活用 @ペパボ
    • サービスディスカバリとして使う
      • デプロイ先のサーバを特定するために、あるロールのサーバ一覧を取得する など
    • 退役忘れ・ロール設定忘れをチェックする
    • ロール毎のサーバ数を数える
      • 任意の時点でのサーバ数を調べる
    • Consul未所属サーバの検知
    • リリースタイムの計測
    • ステータスコード毎のリクエスト数を取得
    • Sidekiqのジョブ数監視
    • TreasureDataのジョブ数監視
    • GHEのディスク使用量監視
    • お問合わせの数を監視
      • リリースの後の思わぬバグでお問合わせが急増していないか知りたい
  • いろんな言語で手軽に独自プラグインがかけるのは楽しい!
  • Q & A
    • 運用ツールとしてMackerelのグラフを活用しているということだが、面白い使い方しているものはあるか

リリースにかかった時間を計測している、というのが面白いなと思いました。デプロイプロセスを改善する際に定量的な評価ができるので素敵ですね。
懇親会でオーガニゼーションの構成についてお話を伺ったところ、あれだけジャンルの違う様々なサービスを展開されているのにMackerelのオーガニゼーションは1つだけで、全社員が全サービスの状況を自由に確認できるようになっているとのことでした。すごいなぁ!

Driving Mercari with 50+ custom Plugins

  • Mackerelの導入理由
    • 異なるインフラの監視項目・内容を共通化する
      • 以前はリージョン毎にZabbixを利用。バージョンがズレたり監視内容の差が発生
      • Service/Roleを利用することで管理
  • Mackrel以外の監視
    • Kurado
      • グラフを一気に見られる
      • 基本的なメトリクスはこちらで見る
    • New Relic
      • PHP内部のトレース
  • Service/Role設計&Deploy
    • サービスを行うリージョン毎にServiceを分ける
      • mercari, mercari-us, mercari-gb
    • 外形監視は別Service
      • mercari0jp-extenalなど
      • 通知チャンネルを分けるため
    • Role名のprefixに意味を持たせる
  • Deploy
    • mackerel-agent.conf には特に設定を書かない
    • conf.d/ 以下にロール毎の設定ファイルを置いてincludeする
      • role-mysql.conf
      • z-common-jp.conf
      • z-postfix.conf
      • など、サーバに寄って配布するconfが異なる
    • Roleの自動付与
      • /etc/sysconfig/mackerel-agent の処理を拡張
  • Mackerelによる監視とPlugin
    • 監視ルール数 265
    • Host毎の監視ルール数
      • MySQL 34
      • Application 39
      • Search 36
    • カスタムプラグイン 50+
  • 紹介されていたカスタムプラグインのうち特に気になったもの
    • diff-detector
      • コマンドの結果に変化があるとアラート
      • cat /etc/passwd, uname -aとか
    • mackerel-plugin-ntpq
      • check-ntp ではなくメトリックで見ているのは、時刻のズレ方を見たいから
    • periodic-checker
      • 特定の時間のみ監視を行う
  • 監視されてないサーバの自動検知
    • 1日2回Slackに通知

ものすごい情報量の発表で圧倒されました。
特定の時間だけ監視を行う、もしくは監視を止める 機能はmackerel-agent標準に欲しいと思いました。夜間休日停止させている開発・管理系のEC2の監視設定をもう少しスマートにやりたい。

AWS Ecosystem with Mackerel

  • AWS 酒徳 さん
  • DevOps系サービス
    • 色々あるけど、CodeStarで割りと統合されてる
      • が、東京リージョンにはまだ来てない
    • CloudFormation がマルチアカウント・マルチリージョンに対応した
  • This is my Architecture

AWSの繁栄はエコシステムあってのこと、というお話でした。AWSから見てもMackerelは単なる監視ツールではなくDevOpsを加速させるためのプラットフォームという認識なんですね。

参加しての感想

いろいろな環境での事例を聞けて、早速うちの環境でも適用できそうな知見も多く、さらに懇親会では直接はてなのエンジニアみなさんとお話しでき、要望をお伝えしたり今後の展望を伺えたりしてとても楽しかったです。 企画・運営してくださったはてなの皆様、ありがとうございました。

AWSアカウントを作ったらまずはこれをやる

業務・個人利用を問わず、新規にAWSアカウントを取得する機会が増えたので、普段自分がやっていることをまとめてみる。

セキュリティ系

  • rootアカウントを多要素認証(MFA)有効化した上で闇に葬る
  • IAMアカウント用パスワードポリシーを設定する
  • IAMアカウントを作る or Switch role 用のIAMロールを作る
    • いずれにせよ MFA必須

予算管理系

  • CloudWatchで請求金額のアラートを設定する
  • Cost Explolerを有効化する
  • Budgetを設定する
  • 現地通貨設定する

監査系

  • 全リージョンでCloudTrailを有効化する
  • 全リージョンでAWS Configを有効化する
    • 以前はAWS Config Rulesの"cloudtrail-enabled"ルールで各リージョンのCloudTrailが有効になっているかチェックしていたが、費用が高い(月額 $2/Rule)ため自前Lambdaファンクションを書いた
  • (ビジネスプラン以上のサポートに加入している場合は) AWS Trusted Advisor チェックを実施する

あと何かあったかな?