はじめに
最近、サーバ監視やるとしてAWSだったらZabbix用意しなくても何とかなるのではと思い、
今AWSだけでサーバ監視するならどこまでできるのか調べてみた。
監視でやりたいこと
基本的な監視をAWSでどこまでできるかって結論、現状以下のようなマルバツ表だと思っています。
今回は黄色の部分を手を動かしてみてどこまでできるか記事にしました。
メモリ監視、ディスク監視(Monitering Scripts)
※ Cloud9上で実行する場合。
AWS公式の手順を抜粋しているだけなので、必要があれば原文を見てください。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/mon-scripts.html
1.IAMロール作成 まずはIAMロールに付けるポリシーから作成。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudwatch:GetMetricStatistics",
"cloudwatch:PutMetricData",
"cloudwatch:ListMetrics",
"ec2:DescribeTags"
],
"Effect": "Allow",
"Resource": [
"*"
]
}
]
}
IAMポリシーを作成後、IAMロールに紐づけ、監視対象のEC2にアタッチ
2.必要なパッケージのインストール
$ sudo yum install -y perl-Switch perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https perl-Dig
$ sudo cpan
↓CPAN内で実行
> install YAML
> install LWP::Protocol::https
> install Sys::Syslog
> install Switch
↓任意の場所に配置
$ curl https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip -O
$ unzip CloudWatchMonitoringScripts-1.2.2.zip
3.テスト
Cloud9上に作成した「moniter」ディレクトリに上記の「aws-scripts-mon」を配置している場合。
/home/ec2-user/environment/moniter/aws-scripts-mon/mon-put-instance-data.pl --mem-util --mem-avail --disk-space-avail --disk-space-util --disk-path=/
CloudWatchのメトリクスに「System/Linux」が追加されており、そこからグラフ表示などできることが確認できた。
定期実行する場合は、Cronなどを使用すればよい。
(この後出てくるAWS Run Commandでも可能)
ここまでの参考:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/mon-scripts.html
http監視(CloudWatch Synthetics)
今までhttp監視のために何かしらサーバを用意する必要があったように思うが(lambdaしかり)、AWSの新サービスでhttp監視がCloudWatchからできるようになっていた。
CloudWatchのSyntheticsコンソールから一気に設定できるので容易に始められるのもgood。
1.Canary作成
Cloudwatch > Synthetics > Canaryを作成ボタンを押下してCanary作成開始。
- 設計図はハートビートのモニタリングを選択。
- Canaryビルダーには監視したいURLを入力する。
- スクリプトエディタは特に変更なし。(上記の内容が自動で入力される仕様)
スクリプトエディタの中身を見るとhttpステータスが200かどうかで判別していることが分かる。
- Canary作成中にスケジュールも設定できる。
- データ保持期間の設定もここからできる。データは最大12か月まで保持できる模様。
- アラームも同じ画面で設定でき、手間が少ない。
2.上記の設定だけでhttp監視は設定完了
これだけの設定で、任意のURLに対してhttp監視できることが分かった。
アラームにAWS SNSのメール設定をしておけば、httpステータスが200以外になったときに
アラートメールを飛ばすことができた。
ただし、CloudWatchのアラートの仕様上、メール文面からはどのURLがエラーとなっているかは
アラート名から推測する形になるのでアラート名は分かりやすいものにする必要があると感じた。
また、文面のカスタマイズ性が必要なら、まだZabbixが必要ということになるかと思う。
UIはすごく見やすかった。
コマンド監視(AWS Systems Manager Run Command + CloudWatch Events)
CloudWatch EventsでRun Commandを定期実行できるので、
これをやればコマンド監視できるかと思い、試してみた。
やった感想としては、かなり手順がめんどくさいし使いにくかったが、
なんとかできはした。
AWS Run Commandでは、CloudWatch Logsに実行結果を飛ばせたので、
CloudWatch Logsでフィルターかけてアラートを発報すれば何とかなると思ったが、
CloudWatch EventsからRun Commandを設定する際には実行結果の出力先を設定する項目がなく、
素直にCloudWatch Logsと連携できなかった。
そのため、
・Run Commandでシェルをたたき
・シェル内に、コマンドとCloudWatch Logsへの送信を書く
ことでCloudWatch Logsと連携させた。
1.監視対象のEC2にSSM Agentをインストール
ここはAWS公式で詳しく載っているので割愛。
(参考:https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html)
今回はSSMコンソール上から「高速セットアップ」を使用してEC2にAgentをインストールした。
2.CloudWatch Logsのロググループ、ログストリームの作成
$ aws logs create-log-group --log-group-name moniter-group
$ aws logs create-log-stream --log-group-name moniter-group --log-stream-name moniter-group-001
3.スクリプト作成
#!/bin/sh
DATE=`date +"%Y/%m/%d %H:%M:%S" -d "9 hours"`
DATE_LINUX=`date +%s%3N`
COM1=`sudo service httpd status`
SPACE=" : "
MESSAGE1=$DATE$SPACE$COM1
SEQUENCE_TOKEN=`cat /home/ec2-user/environment/moniter/cloudwatch_sequenceToken | jq .nextSequenceToken`
aws logs put-log-events \
--log-group-name moniter-group \
--log-stream-name moniter-group-005 \
--log-events timestamp=$DATE_LINUX,message="$MESSAGE1" \
--sequence-token ${SEQUENCE_TOKEN:1:-1} \
> /home/ec2-user/environment/moniter/cloudwatch_sequenceToken
ひとまずコマンドでサービスの状態を監視する想定として、
「sudo service httpd status」コマンドを実行することにした。
今回は考えるのが面倒だったので、とりあえず「/home/ec2-user/environment/moniter/cloudwatch_sequenceToken」というファイルに
sequence-tokenの値を上書き&参照していく仕様にした。
スクリプト中ではjsonを使うために「jq」コマンドを使用している。
デフォルトではインストールされていないので、別途インストールが必要。
$ sudo yum install jq
ハマりどころとしては、「aws logs put-log-events」コマンドにおいて
timestampは13桁のUNIXTimeでないといけないこと、
CloudWatch Logsに送信した際に返ってくるsequence-tokenを次の送信時に使用しないといけないこと。
ただし、初回はsequence-tokenを送ってはいけないので、あらかじめ
下記で一回送信しておくとよい。
$ aws logs put-log-events --log-group-name moniter-group --log-stream-name moniter-group-001 --log-events timestamp=1590995877,message="test"
4.CloudWatch EventsからRun commandの設定
CloudWatch Eventsを新規に作成する。
- スケジュール :任意に設定。Cron式も書ける
- ターゲット :SSM Run Command
- ドキュメント :AWS-RunShellScript(Linux)
- ターゲットキー:今回はインスタンスIDでコマンド実行対象のEC2を識別したかったのでInstanceIdsを入力
- ターゲット値 :対象とするインスタンスのIDを入力
- Commands :sh [絶対パス]/[スクリプト名] (例:sh /home/ec2-user/environment/moniter/xxx.sh)
ここまでで、特定のコマンドを対象のEC2に実行し、実行結果をCloudWatch Logsに飛ばすところまでいけた。
あとは、CloudWatch Logsで特定の文言で拾ってアラート飛ばすだけ。
5.メトリクスフィルターの作成
WloudWatch > ロググループから作成したロググループを選択し、
メトリクスフィルターを作成する。
下記例
- フィルターパターン:stop
- フィルター名:service-moniter-filter
- メトリクス名:service-moniter-metrics-name
- メトリクス名前空間:service-moniter-metrics-namespace
- メトリクス値:1
- デフォルト値:0
デフォルト値を0にしておかないと、エラー出ないときにデータ不足といわれてしまうので注意。
6.AWS SNSの設定
AWS SNSでメール送信設定ができる。この手順はすぐに完了するような内容。
トピック
- 名前:moniter-email
サブスクリプション
- プロトコル:Eメール
- メールアドレス:(受け取るメールアドレスを記載)
設定後、確認メールが来るので確認のURLにアクセスする。
7.上記の設定でやっとのことコマンド監視設定が完了
ここまでやってやっとコマンド監視ができた。
実際に動かしてみたが問題なく検知&アラート発報できていた。
コマンドをまとめてシェルに書いておけば、まとめてコマンド実行して監視できるかと思ったが、
CloudWatchのアラートの仕様では発報されたメールにはアラート名しかないので、
メールから失敗したコマンドを判別したいなら、実行するコマンドの数だけ上記設定が必要となる。
- メール例
Alarm Details: - Name: service-moniter-alarm - Description: - State Change: OK -> ALARM
コマンド監視が必要な場合は、現状AWSの機能だけでコマンド監視しようとすると少しキツいという印象だった。
やはりこの場合も現時点ではZabbixが必要な場合もあると思う。
プロセス監視(外部参照)
こちらはDeveloperIOで詳しく書かれていたのでそちらを参照します。
ログ監視(外部参照)
ログ監視については特定のログをCloudWatch Logsに送ることができれば、
上記コマンド監視で行っていたフィルター&アラートで監視できると思います。
CloudWatch Logsに送るまでの手順は別の方が詳しく書いてくださっていたのでそちらを参照します。
終わりに
AWSマネージドの監視について一通り検証した結果、
Zabbixなどの監視システム不要な時代は近いのかもしれないと思った。
(私の考えが古いだけで、AWSの監視で本番運用しているトコも多くあるかもしれない。)
しかし、現状監視のレポートを見る場所が分散していたり、
メールも可読性が悪いためにアラートの詳細が文面から把握できない場合もあるため現状はまだまだZabbixは使うと考える。
今後の動向を追いながら少しづつAWSマネージドに寄せて運用負荷を減らしていきたいと思う。
また、Cloud Watch Agentをまだ使い倒せていないのでいろいろいじってみて
考えをアップデートしていきたい。