第2回は、前回に引き続きAmazon Elastic Compute Cloud (EC2) を対象に、ほとんど利用されていないEC2リソースを把握し、インスタンスの削除や計画停止によるコスト削減につなげるアプローチについて紹介します。

どうぞよろしくお願いいたします。


必要な知識を得る

EC2の課金内容

停止中のEC2は課金対象にならない。

EC2にアタッチしているEBS(ストレージ)はEC2を停止していても課金対象となるので注意してください。

CloudWatchサービス

EC2の利用状況の把握にCloudWatchのAPIを利用します。

EC2を起動する際に「詳細モニタリングを有効にする」にチェックを入れた場合(有料オプション)は1分毎の各リソースデータが、チェックを入れない場合は5分毎の各リソースデータが自動的に収集されます。

概要の把握は5分毎のデータで十分です。

CloudWatchで取得可能なデータ

今回はEC2が利用しているNWデータ量を利用して、利用されていないと疑われるサーバの抽出を行います。

今回のようにシンプルにNWデータ量だけを確認するのであれば、CloudWatchの画面からも確認が可能です。

その他にもCloudWatchサービスではCPU使用率やストレージの使用量などのデータも取得可能です。また、個別にデータを送信するスクリプト(カスタムメトリクス)を手配することで、メモリリソースの使用率なども把握可能です。詳細は下記のURLを参照ください。

参考URL:Amazon Web Service社様HP

画像表示

サーバレスアーキテクチャ(Lambda)

今回は手順のご紹介は省略しますが、夜間のみ利用されていないサーバなどが抽出された場合、AWSの「Lambda」サービスを利用することで、安価に特定時間の間サーバを停止しておくなどの自動化が可能です。


作業に必要な準備をする

Card image cap

第1回で利用したものを流用します

手順を実施していない方は下記リンクから参照の上実施してください。

第1回 Amazon EC2 利用コストを可視化してリザーブドインスタンス(RI)を使い倒す

AWS管理者アカウントの手配

第1回で作成した「api_user」に、API実行に必要な権限を追加で割り当てます。上記AWSコンソール画面上の「IAMサービス」の画面で「CloudWatchLogsReadOnlyAccess」の権限を付与してください。

画像表示
Card image cap

日付型のデータライブラリのインストール

直近の日時のEC2利用状況を自動で取得するために日付型データのライブラリを利用します。第1回で作業したディレクトリと同じ場所で以下手順でインストールしてください。

$ npm install data-utils


APIを使ってデータを取得する

1.今回利用するAPI

それではAPIを使って実際にデータを取得していきましょう。

EC2のIDのリストを取得するのに前回と同様EC2サービスの

AWS.EC2.describeinstances」を利用します。

EC2が利用されているか、稼働しているかどうかを確認するために、CloudWatchサービスの

AWS.CloudWatch.getMetricData」を利用します。

2.スクリプトの作成

 

第1回で作成した「ec2_describeInstances.js」をそのまま利用しますので未作成の方は作成してください。

続いてCloudWatchのAPI実行スクリプトを作成します。以下の内容をコピーして「cloudwatch_getMetricData_ec2.js」として保存してください。今回は外部からの流入するNWパケット数でサーバの稼働状態を把握したいと思います。

バッチ処理などで利用されているサーバは外部へ接続するNWパケット数なども合わせて確認するとよいです。

require('date-utils');
const AWS = require('aws-sdk');
//credential情報の読込
AWS.config.loadFromPath('credential.json');
//対象のinstanceID情報
var instance_id='i-XXX'//後で修正します。
//時刻の設定(1週間分のデータを取得する)
var dt_today = Date.today();
var dt_1weekago = Date.today().remove({"weeks": 1});
var formatted_today = dt_today.toFormat("YYYY-MM-DDTHH24:MI:SSZ");
var formatted_1weekago = dt_1weekago.toFormat("YYYY-MM-DDTHH24:MI:SSZ");
//Metricsの設定
const metric = {
  StartTime: dt_1weekago,
  EndTime: dt_today,
  MetricDataQueries: [
  {
   Id: "data",
   MetricStat: {
    Metric: {
     Namespace: "AWS/EC2",
     MetricName: "NetworkPacketsIn",
     Dimensions: [
      {
       Name: "InstanceId",
       Value: instance_id
      }
     ]
    },
    Period: 60,
    Stat: "Average"
   }
  }
 ]
 };
//cloudwatchの生成+リージョン指定
const cloudwatch = new AWS.CloudWatch({region: 'ap-northeast-1'});
//データを投げる
cloudwatch.getMetricData(metric, (err, data) => {
  if (err) console.log(err, err.stack); // an error occurred
  else console.log(JSON.stringify(data.MetricDataResults,null,null));           // successful response
});

3.実行

作成したスクリプトを以下のコマンドで実行します。

稼働中のサーバの確認

$ node ec2_describeInstances.js | jq -r '.[].Instances[] | select(.State.Name == "running") | [.InstanceId, .LaunchTime]'

稼働中のサーバのID(i-から始まるデータ)が表示されますのでこのデータを先ほど作成した「cloudwatch_getMetricData_ec2.js」の8行目にコピーします。より長時間起動しているサーバの方が費用削減効果が期待できるでしょう。

[
  "i-XXXXXXXXXXXXXXXXX",//インスタンスIDが出力されます。
  "2019-02-15T01:47:27.000Z"//最終起動時刻が出力されます。
]
[
  "i-YYYYYYYYYYYYYYYYY",
  "2019-02-08T01:29:23.000Z"
]
サーバの稼働状況データの取得(csv形式)

$ node cloudwatch_getMetricData_ec2.js | jq -r '.[].Timestamps, .[].Values | @csv'

4.結果の確認

スクリプト実行時の結果のサンプルを以下に示します。このデータを整形して、NWの流入がほぼないサーバのリソースを調べます。

"2019-04-22T14:59:00.000Z","2019-04-22T14:54:00.000Z","2019-04-22T14:49:00.000Z",......//データが収集された時刻が出力されます
1.2,2.6,1.4,1.8,1.4,1,3.2,1.8,1,1.4,1.8,3,1,2.2,1.4,1.......//実際のデータ数。今回はサーバに流入するNWパケットの数が出力されます

5.結果の分析

上記のデータを加工して、NWの利用のないEC2を特定します。

データの見方

[i-aaa]のEC2インスタンスについては、ほぼNWパケットが処理されていないことから、未使用のサーバであることが疑われます。Webサーバではないバッチ用サーバの可能性もありますので利用用途については確認する必要があります。

[i-bbb]のEC2インスタンスについては、早朝のみNWパケットが処理されていないことから、早朝はサーバを停止できる候補となります。

[i-ccc]のEC2インスタンスについては、不規則ではありますが定常的にNWパケットが処理されていることから常時稼働が必要なサーバであることが想定されます。

NetworkPacketsInデータサンプル
InstanceIdMonTueWedThuFriSatSun
~08:00~16:00~24:00~08:00~16:00~24:00~08:00~16:00~24:00~08:00~16:00~24:00~08:00~16:00~24:00~08:00~16:00~24:00~08:00~16:00~24:00
i-aaa 1.8 2.2 1.4 7.1 6.7 5.4 0.6 8.5 3.7 6.3 7.2 7.8 7.6 2 2 3 3 9.4 7.6 2.6 8
i-bbb 8 307.5 476.2 1.2 204.1 86.4 3.4 142 38.4 9.3 764.4 260.5 4.3 793.9 40 1.5 548.4 251.7 4.7 308.3 11.6
i-ccc 271.6 121.9 224.9 588.1 413.6 396.9 705.4 29.9 49.5 423.4 997.8 757.1 43.1 24.6 640.8 360.2 573 816.6 618.4 486.9 311.4

サーバの停止、特定期間停止を実施する

EC2を停止する

上記のデータから、[i-aaa]を停止することとしました。

AWSのコンソール画面、EC2サービスの画面から、対象のサーバを選択し「停止」ボタンを押下することで停止できます。


EC2を期間停止する

上記のデータから、[i-bbb]を早朝のみ停止することとしました。

手順は今回は省略しますが、8時間毎日停止することで、対象のサーバの33%分の費用が浮くことになります。