【CloudWatch Logs Insights】VPCピアリングのトラフィック量を調査してみた

記事タイトルとURLをコピーする

こんにちは。AWS CLIが好きな福島です。

はじめに

今回は、VPCピアリングからTGWに移行する際の事前調査として、 VPCフローログからVPCピアリングのトラフィック量を調査したため、その方法をブログに記載いたします。

前提

ログ形式

今回、ブログに記載するクエリを使う場合の前提として、 VPCフローログのログ形式をカスタムし、flow-directionおよびtraffic-pathが末尾に出力されるように設定しておきます。

  • デフォルト

VPCフローログのログ形式のデフォルトは以下の通りです。

${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}
  • カスタム

VPCフローログのログ形式を以下の通り、カスタムします。 デフォルト形式に以下4つの列を追加します。

${pkt-src-aws-service} 
${pkt-dst-aws-service} 
${flow-direction} 
${traffic-path}
※${pkt-src-aws-service} ${pkt-dst-aws-service}は今回の分析に必須ではないです。

カスタムしたのログ形式は以下の通りです。

${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status} ${pkt-src-aws-service} ${pkt-dst-aws-service} ${flow-direction} ${traffic-path}

traffic-path

traffic-pathには、トラフィックの送信先に応じて数字が記載されます。詳細は以下の通りです。

出力トラフィックが送信先につながるパス。 トラフィックが出力トラフィックであるかどうかを判断するには、flow-direction フィールドを確認します。 指定できる値は次のとおりです。いずれの値も適用されない場合、フィールドは - に設定されます。

1 — 同じ VPC 内の別のリソース経由 2 — インターネットゲートウェイまたはゲートウェイ VPC エンドポイント経由 3 — 仮想プライベートゲートウェイ経由 4 — リージョン内 VPC ピア接続経由 5 — リージョン間 VPC ピア接続経由 6 — ローカルゲートウェイ経由 7 — ゲートウェイ VPC エンドポイント経由 (Nitro ベースのインスタンスのみ) 8 — インターネットゲートウェイ経由 (Nitro ベースのインスタンスのみ)

補足

ログ形式のカスタムをマネジメントコンソール上から実行する場合、 少し手間なので以下の変数を定義後、コマンドを実行すると楽です。

VPC_ID="VPCのIDを指定"
CW_LOGS_NAME="CloudWatch Logsのロググループ名を指定"
FLOWLOGS_IAM_ARN="VPCフローログを出力する際のIAMロールのARNを指定"
aws ec2 create-flow-logs \
--resource-ids ${VPC_ID} \
--resource-type VPC \
--traffic-type ALL \
--deliver-logs-permission-arn ${FLOWLOGS_IAM_ARN} \
--log-group-name ${CW_LOGS_NAME} \
--max-aggregation-interval 60 \
--log-format '${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status} ${pkt-src-aws-service} ${pkt-dst-aws-service} ${flow-direction} ${traffic-path}'

クエリ一覧

⓪クエリ実行前の準備

クエリを実行する前に対象となるロググループおよび調査するログの範囲(時間)を指定します。 ※今回は、fk-test-vpcとfk-test2-vpc間でのVPCピアリングしています。

①リージョン内のVPCピアリングのトラフィック量の出力

  • クエリ
filter @message =~ /egress 4$/
| stats sum(bytes) as TotalBytes
| display TotalBytes
  • 実行結果

  • 解説

以下のように出力されるログに対して、messageの末尾が「egress 4」(赤枠)のbytesの値(青枠)をsum関数で集計します。 egress だけに出力を絞っているのは、両方のVPCフローログをクエリの対象としているためです。 (そもそも、ingress 4という値は出力されなそうでしたが...)

②リージョン内のVPCピアリングのトラフィック量をENI単位で出力

  • クエリ
filter @message =~ /egress 4$/
| stats sum(bytes) as TotalBytes by interfaceId
| sort TotalBytes DESC
  • 実行結果

  • 解説

1個前のクエリとほぼ同様で、by interfaceIdという部分が異なります。 これは、interfaceid(ENI)ごと(緑枠)に集計結果を出力する意味となります。

③時間単位でリージョン内のVPCピアリングのトラフィック量を出力

これは、ログの範囲を変えつつ、①のクエリを実行するだけでいいのですが、 マネジメントコンソールからその作業は実行するのは、少し苦労します。

そのため、私は以下のスクリプトを使いました。

  • vpc_flowlogs_check.sh
#!/bin/bash

## 第1引数(ログの範囲)を代入
YYYY_MM_DD=${1}

## 第1引数をUNIXTIMEに変換
start_time=$(date -d "${YYYY_MM_DD}" +%s)
## クエリの終了時間を設定(1時間間隔でクエリを実行するため、3599(秒)加算)
end_time=$(expr ${start_time} + 3599)

## 第2引数(ロググループ)を代入
log_group_names=${2}

echo "start_time,end_time,traffic_bytes,statistics_bytes,query_id"

## 1日を1時間単位で集計するため、24回処理を実行
for i in {0..23}
do
   ## クエリを実行し、返り値をquery_idに代入
   query_id=$(aws logs start-query \
   --log-group-names ${log_group_names}\
   --start-time "${start_time}000" \
   --end-time "${end_time}000" \
   --query-string 'filter @message =~ /egress 4$/ | stats sum(bytes) as TotalBytes | display TotalBytes' \
   --query "queryId" --output text)

  ## クエリが完了するのを待つ(最大50秒)
   for i in {0..9}
   do
     ## クエリのステータスを確認
      query_status=$(aws logs get-query-results \
      --query-id ${query_id} \
      --query "status" --output text)

     ## クエリのステータスが「Complete」になった場合処理を抜ける
      if [[ "Complete" == ${query_status} ]] ; then
         query_result=$(aws logs get-query-results \
         --query-id ${query_id} \
         --query "[results[0][0].value,statistics.bytesScanned]" --output text \
         | tr "\t" ",")
         break
      fi

      sleep 5

   done

   ## クエリの結果を標準出力
   echo "$(date --date @${start_time} +'%Y/%m/%d %H:%M:%S'),$(date --date @${end_time} +'%Y/%m/%d %H:%M:%S'),${query_result},${query_id}"

   start_time=$(expr ${end_time} + 1)
   end_time=$(expr ${start_time} + 3599)

   i+=1
   unset total_bytes
done
  • 使い方
# ./vpc_flowlogs_check.sh [調査したい日付] [ロググループ名("で囲み、スペース区切りで複数指定)]
  • 実行例
# ./vpc_flowlogs_check.sh 2022-03-28 "fk-test-vpc fk-test2-vpc"
start_time,end_time,traffic_bytes,statistics_bytes,query_id
2022/03/28 00:00:00,2022/03/28 00:59:59,None,16407.0,79b6b8d1-d05d-4505-bd56-cb062a2e4a13
2022/03/28 01:00:00,2022/03/28 01:59:59,None,16407.0,03ab240c-a47f-42c3-bfd1-c3faaf7e482e
2022/03/28 02:00:00,2022/03/28 02:59:59,None,16407.0,aaceea5f-30e5-4c84-b745-b9a132b91cf2
2022/03/28 03:00:00,2022/03/28 03:59:59,None,16407.0,6d7cb1ef-d3c7-4329-8001-f4bd3ed01f27
2022/03/28 04:00:00,2022/03/28 04:59:59,None,16407.0,4df1c986-c985-45d7-950a-5f7e802b1a58
2022/03/28 05:00:00,2022/03/28 05:59:59,None,16407.0,0fe2f628-09bd-45b6-b329-1f88c69006a0
2022/03/28 06:00:00,2022/03/28 06:59:59,None,16407.0,ffaef180-a9ee-4ed7-a231-338e75d40e61
2022/03/28 07:00:00,2022/03/28 07:59:59,None,16407.0,69b9068d-582d-47e0-9b1a-9a7d3a95a399
2022/03/28 08:00:00,2022/03/28 08:59:59,None,16407.0,c500035e-dfa1-46c2-a2f5-1f1cb1ee560e
2022/03/28 09:00:00,2022/03/28 09:59:59,None,16407.0,61395b09-019d-4d23-b576-4357167dbd3b
2022/03/28 10:00:00,2022/03/28 10:59:59,None,16407.0,6ad4c3c5-356a-4a6d-9c0e-8f2c115adbc8
2022/03/28 11:00:00,2022/03/28 11:59:59,None,16407.0,b8c2ab36-240a-412e-bd5c-0268d2fc403f
2022/03/28 12:00:00,2022/03/28 12:59:59,None,16407.0,ae67c89a-3d12-4ae9-ba57-2c2a9760c899
2022/03/28 13:00:00,2022/03/28 13:59:59,None,16407.0,76a61753-6f2f-43b9-a170-1e6bd7e67d86
2022/03/28 14:00:00,2022/03/28 14:59:59,None,16407.0,755ae266-c60e-4161-8df7-124fb8cabc00
2022/03/28 15:00:00,2022/03/28 15:59:59,None,16407.0,64301660-c842-4f6a-9579-bfbb3b4f988d
2022/03/28 16:00:00,2022/03/28 16:59:59,1092,309332.0,3da35432-d6dc-4c63-b3cb-d224cbd0f5ca
2022/03/28 17:00:00,2022/03/28 17:59:59,336,932346.0,2bfdcdbb-db89-452d-80cb-1044a1dbba5d
2022/03/28 18:00:00,2022/03/28 18:59:59,None,889753.0,4140acdb-3665-4349-ae67-3d10e3c8e17b
2022/03/28 19:00:00,2022/03/28 19:59:59,None,929301.0,4581454b-7cc1-4c69-a998-bfb7734d4fc8
2022/03/28 20:00:00,2022/03/28 20:59:59,None,905492.0,6a9fb063-9fe3-4fda-9f18-09d36322841b
2022/03/28 21:00:00,2022/03/28 21:59:59,None,916564.0,a2e7b3fc-bc53-4879-9890-6d438260fe95
2022/03/28 22:00:00,2022/03/28 22:59:59,None,917511.0,7a9a40f2-8deb-480c-9447-ff53a66c0527
2022/03/28 23:00:00,2022/03/28 23:59:59,None,934279.0,ae91dd6f-2a22-422f-82fe-45a5e2785561

各項目の意味は以下の通りです。statistics_bytesを出力しているのは、この値に応じてCloudWatch Logs Insightsの料金が代わるため、一応出力しています。

start_time: 開始時刻 
end_time: 終了時刻
traffic_bytes: トラフィック量
statistics_bytes: 分析したログの総量
query_id: クエリID
  • 補足 クエリIDを指定することで実際の分析結果を確認することができます。
#  aws logs get-query-results --query-id 2bfdcdbb-db89-452d-80cb-1044a1dbba5d
{
    "results": [
        [
            {
                "field": "TotalBytes",
                "value": "336"
            }
        ]
    ],
    "statistics": {
        "recordsMatched": 2.0,
        "recordsScanned": 6470.0,
        "bytesScanned": 932346.0
    },
    "status": "Complete"
}
 #

終わりに

今回は、VPCピアリングのトラフィックをVPCフローログから調査してみました。 どなたかのお役に立てれば幸いです。

福島 和弥 (記事一覧)

SRE3課

2019/10 入社

AWS CLIが好きです。