亚马逊AWS官方博客

利用VPC Flow Logs统计EC2网络流量信息

在针对一套应用系统进行运维的过程中,运维人员往往希望能够对网络流量进行精确监控,以此作为评价系统运行状况的依据。此外,由于 EC2 的数据传输会根据目标地址的不同而产生一定的费用[1],精确掌握流量信息还有助于针对资源使用成本进行详细分析。

AWS 提供的 CloudWatch 服务可以针对每一个弹性网络接口(以下简称 eni)的流量进行监控,但运维人员往往还希望获得源IP地址、源端口、目标 IP 地址、目标端口、传输层协议等信息。AWS提供的“VPC流日志”(以下简称Flow Logs)功能会针对每一个eni所产生的五元组信息进行监控记录 [2]。本文将介绍如何利用 Flow Logs 以及中国区域所提供的相关服务以实现针对 eni 的流量分析(例如:流入VPC、流出 VPC、在 VPC 内跨 AZ 的各种流量),并基于 Python3.x 给出相关操作代码。

要使用 Flow Logs 功能,需要在 VPC 中进行激活。目前,在中国的两个Region内仅支持将Flow Logs发布到CloudWatch Logs中[3]。Flow Logs 将会在 CloudWatch Logs 中为 VPC 中的每一个 eni 创建一条日志流。

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(1).png

为了使用中国区目前可用的服务完成对 Flow Logs 的分析,需要将 CloudWatch Logs 中的日志流导出到 S3 存储桶中[4]。实际操作中可以按月导出,以便汇总统计。每一条日志流都会导出成一个子目录,目录内包含一个名为 000000.gz 的文件。

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(2).png
https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(3).png

在对 Flow Logs 进行分析时,需要用到针对 IP 地址的操作。PostgreSQL 支持针对IP地址进行直接操作[5],因此本文利用 Amazon RDS 服务建立一个 PostgreSQL 数据库作为分析工具[6]

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(11).png

如使用其它数据库作为分析工具,在使用 SQL 语句时需要对IP地址进行处理[7]

通过以下代码可以完成对 S3 存储桶中日志文件的批量下载、解压:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(4).png

其中各参数含义如下:

BUCKET_NAME – 保存 Flow Logs 的 S3 存储桶名称;

PREFIX_NAME – 导出 CloudWatch Logs 时所指定的子目录名称;

SAVE_PATH – 指明日志文件下载后所保存的本地路径。

日志文件解压后,需要批量导入到已建立好的 PostgreSQL 数据库中。批量导入、建表过程可通过如下代码实现:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(5).png

DB_NAMEDB_USERDB_PASSDB_HOSTDB_PORT 为连接数据库所需参数,根据创建数据库时的设置进行填写。TABLE_NAME 为需要存放 Flow Logs 日志的表的名称。

在创建 TABLE_NAME 表时,需根据 Flow Logs 所记录的信息设置字段[2]。为便于标记流量状态,在所有日志文件导入完成后增加一个字段“transfer”,将在该字段内记录数值的含义如下:

0: 源 IP 与目标 IP 在相同可用区(同一 AZ 内的流量);

0: 源 IP 不属于VPC CIDR(从互联网流入 VPC 的流量);

1: 源 IP 与目标 IP 不在相同可用区,但都属于 VPC CIDR(跨 AZ 的流量);

2: 源 IP 属于 VPC CIDR、目标 IP 不属于 VPC CIDR(从 VPC 流出到互联网的流量)。

本文所利用的 VPC 相关地址分配如下:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(6).png

从上述截图中可以看出,本文所用实验环境包含5个子网、分布在3个可用区(AZ)。需要建立表明不同AZ所用IP地址段的数组、VPC所用IP地址段的常量,如下:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(7).png

为了准确标记出 data transfer 的状态,可以采用4条SQL语句实现。每条SQL语句实现的效果及最终结果如下表示意:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(8).png

实现代码如下:

https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(9).png

至此,已经在PostgreSQL数据库中建立起一张记录了VPC内所有eni流量记录的表。通过对该表执行SQL语句,可以获得相应的汇总信息。

例如,从表中汇总每个eni流出VPC的流量、并根据流出量的多少进行排序:

SELECT interface, sum(bytes)

FROM TABLE_NAME

WHERE transfer=2

GROUP BY interface

ORDER BY sum;
结果如下:
https://s3.cn-north-1.amazonaws.com.cn/awschinablog/vpc_flow_log+(10).png

[1] Amazon EC2 定价, https://www.amazonaws.cn/ec2/pricing/

[2] 流日志记录,https://docs.amazonaws.cn/vpc/latest/userguide/flow-logs.html#flow-log-records

[3] 将日志发布到CloudWatch Logs,https://docs.amazonaws.cn/vpc/latest/userguide/flow-logs-cwl.html#process-records-cwl

[4] 将日志数据导出至Amazon S3,https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/S3Export.html

[5] Network Address Functions and Operators,https://www.postgresql.org/docs/9.6/functions-net.html

[6] 创建运行PostgreSQL数据库引擎的数据库实例,https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/USER_CreatePostgreSQLInstance.html

[7] Comparing IP Addresses in SQL,https://www.periscopedata.com/blog/comparing-ip-addresses-in-sql

本篇作者

刘伟平

AWS APN 合作伙伴解决方案架构师,主要负责 AWS (中国)合作伙伴的技术支持工作,同时致力于 AWS 云服务在国内的应用及推广。加入 AWS 前,在 HP(HPE)服务超过7年,历任存储售前工程师、电信行业售前工程师、NFV 解决方案架构师,熟悉传统企业 IT 架构、私有云及混合云部署。