当前位置:   article > 正文

Amazon CloudFront 跨账号异常监控实践

Amazon CloudFront 跨账号异常监控实践

e1a730b3a7f31674d529e1099638ee59.gif

当用户受到 DDoS 攻击的时候,如果没有事先配置 Amanzon WAF 和 Amazon Shield Advanced 保护,往往在短时间内会产生大量的 Amazon CloudFront 请求或者流量,从而产生大量的 CDN 费用。站在 payer 账号的角度,payer 底下有很多 linked 账号在使用 Amazon CloudFront,我们希望可以集中和智能地监控所有 linked account 的 CDN 使用情况,在异常情况下发出告警。Amazon CloudFront 账单数据有一两天的延迟,所以我们决定结合 Amazon CloudWatch 的跨账号异常检测功能来实现这一目标。开始之前,我们先来了解什么是 Amazon CloudFront。

Amazon CloudFront 是一个全球内容分发网络 (CDN) 服务,它可以帮助您通过全球分布式的服务器网络更快地向用户提供内容。它的主要特性包括:

  1. 低延迟和高可用性:Amazon CloudFront 利用亚马逊云科技遍布全球的边缘节点,可以将内容快速传输到用户附近,减少延迟,提高可用性。

  2. 安全性:Amazon CloudFront 支持 HTTPS 协议,可以保护传输中的内容不被窃取或篡改。同时它还提供多种安全功能,如防 DDoS 攻击等。

  3. 静态请求加速:Amazon CloudFront 会自动缓存您的静态内容,如图片、视频、CSS 和 JavaScript 文件等,减少源站的负载压力,提高响应速度。

  4. 动态请求加速:Amazon CloudFront 可以轻松集成您的动态内容,如 API 、Web 应用程序等,为您提供全面的内容分发解决方案。

Amazon CloudWatch 

跨账号异常检测介绍

从 2024 年 4 月起,Amazon CloudWatch 支持对账户间共享的指标进行异常检测。Amazon CloudWatch 异常检测功能允许您在单个监控账户中通过 Amazon CloudWatch 跨账户可观测性跟踪多个账户之间的指标行为的异常变化(需要源账号授权)。

Amazon CloudWatch 的异常检测功能将机器学习算法应用于指标的历史数据,自动创建预期值模型。这个模型会评估指标的趋势,并捕捉每小时、每日和每周的模式变化。算法会训练最近两周的指标数据,但即使没有完整的两周数据,您仍然可以为指标启用异常检测。

与传统的静态阈值方式不同,Amazon CloudWatch 异常检测可以自动发现异常行为,避免了由于阈值设置不当而漏报或误报的情况。及时发现系统异常,有助于快速定位和解决潜在问题,提高系统稳定性。

在配置异常检测时,您需要设置一个异常检测阈值 ANOMALY_DETECTION_BAND,我们会在下文详细说明。Amazon CloudWatch 将使用这个阈值和模型来确定指标值的”正常”范围。阈值设置越高,判定为正常的值范围就越大。一旦模型创建完成,Amazon CloudWatch 会持续评估并调整模型,以保证尽可能精准。这包括重新训练模型,使其能随着指标值的变化而自我调整。还包括优化针对季节性、峰值或稀疏指标的预测器模型。

您还可以在启用异常检测后排除指标的某些时间段,这些数据将不会用于训练模型。通过排除部署或其他异常事件的影响,可以确保创建最准确的模型。同时,也可以设置异常发生时自动执行操作,如发送通知或触发自动化工作流,实现自动化运维。

总的来说,Amazon CloudWatch 异常检测通过机器学习自动发现异常,能够提高系统可观测性和可靠性,同时简化了异常检测的实施和管理。无需搭建和维护独立的异常检测系统,直接使用 Amazon CloudWatch 的托管服务,降低运维成本,中国区和海外区都已经上线。

ae9326846fffcfb265dee74256a5270c.png

修改异常检测模型

扫码了解更多

接下来我们使用一个集中账号连接另外一个源账号实现异常监控。

配置集中账号

要实现跨账号监控,先得在集中账号开通 Amazon CloudWatch 跨账号监控功能,由于我们监控的目标服务是 Amazon CloudFront,所以必须选择美东 1 区域进行配置。打开 Amazon CloudWatch 服务,点击 settings,并在 Monitoring account configuration 处点击 Configure。

975b8124e9c4b9e44c91686859214cbf.png

对于 Amazon CloudFront 的监控,我们只需要启用 Metrics 就可以,Logs 和 Metrics 的共享在功能上是免费的,其他数据共享会产生额外的功能费。

240cfef778c1647830a2ea173310f7ec.png

在 source accounts 里面把需要收集数据的源账号 ID 填上。

d018be9e981e437c0e1564d800856165.png

保存配置并退出,然后点击 “Resources to link accounts” 来获取源账号链接信息。

c04bd286f16d72c87c8d0eccbf40a000.png

如果源账号和集中账号之间是已经使用 Amazon Organization 来管理,则可以使用下图左侧的连接方式。由于实验环境是独立的账号,所以我们选择右侧的 “Any Account”, 并点击 “Copy URL” 来保存源账号的连接配置 URL 地址。

161c6e796461a8d0a53413ad935a633d.jpeg

配置源账号

首先使用新的浏览器登录源账号,跳转到美东 1 区域,并打开 Link 配置的链接地址,确认配置信息无误后点解 “Link”。

370146ef2d81ff48cc5be3d2a8ffad71.png

验证集中账号能否看到

源账号的 CW 指标

配置完后大概等待 5 分钟,在集中账号的 Amazon CloudWatch 选择 Amazon CloudFront 就能看到同步过来的 CDN metrics 信息。

5cd12acd067212eed6725aed2a150ed2.png

配置 SNS 用于接受告警信息

f4aa84a7cde49d2884a95ce2c3a71fa1.png

创建一个 topic 叫 test-alert

e22cc1fbc60ef6ebec2e00ac4ba02fea.png

创建 email 订阅,登陆邮箱通过订阅服务,并记下 topic 的 ARN 地址串 arn:aws:sns:us-east-1:xxxxxxxx:test-alert,后面配置 Amazon CloudFront 监控告警需要使用到。

01ab4cd8d5080a182c8c45dddcdd0e88.png

部署代码

1、打开监控账号的 cloudshell ,然后从 git 上拉取代码

git clone https://github.com/Rayment915/aws-cdn-anamoly-detecor.git

左右滑动查看完整示意

跨账号监控只需要用到这两个文件:

  1. get_cross_account_distributionId.py
  2. create_alert_from_mon_account.py

左右滑动查看完整示意

  1. # get_cross_account_distributionId.py
  2. # use to list CloudFront distribution ID in source account and create alert in monitoring account
  3. import boto3
  4. from create_alert_from_mon_account import create_cloudwatch_alarm
  5. def get_distribution_list(OwningAccount,next_token = None):
  6.    cloudwatch = boto3.client('cloudwatch')
  7.    metrics = []
  8.    while True:
  9.        # Call the list_metrics API with the appropriate parameters
  10.        if next_token:
  11.            response = cloudwatch.list_metrics(
  12.                Namespace='AWS/CloudFront',
  13.                NextToken=next_token,
  14.                IncludeLinkedAccounts=True,
  15.                OwningAccount=OwningAccount
  16.            )
  17.        else:
  18.            response = cloudwatch.list_metrics(
  19.                Namespace='AWS/CloudFront',
  20.                IncludeLinkedAccounts=True,
  21.                OwningAccount=OwningAccount
  22.            )
  23.        # Append the retrieved metrics to the list
  24.        metrics.extend(response['Metrics'])
  25.        # Check if there are more results to retrieve
  26.        next_token = response.get('NextToken', None)
  27.        if not next_token:
  28.            break
  29.    distribution_ids= [metric['Dimensions'][1]['Value'] for metric in metrics]
  30.    ret=set(distribution_ids)
  31.    return ret
  32. if __name__ == "__main__":
  33.    OwningAccount='YOUR_SOURCE_ACOUNT_ID'
  34.    distributions_list=get_distribution_list(OwningAccount)
  35.    # Modify it according to your use case
  36.    ANOMALY_DETECTION_BAND=5
  37.    metric_list=['Requests','BytesDownloaded']
  38.    sns_arn='arn:aws:sns:us-east-1:YOUR_MONITORING_ACCOUNT_ID:test-alarm'
  39.    for distribution_id in distributions_list:
  40.        for metric in metric_list:
  41.            create_cloudwatch_alarm(distribution_id,metric,sns_arn,ANOMALY_DETECTION_BAND,OwningAccount)

左右滑动查看完整示意

  1. # create_alert_from_mon_account.py
  2. import boto3
  3. from botocore.exceptions import ClientError
  4. def create_cloudwatch_alarm(distribution_id,metric,sns_arn,ANOMALY_DETECTION_BAND,account_id):
  5.    """
  6.    创建基于 Anomaly Detection 的 CloudWatch 告警
  7.    """
  8.    # 创建 CloudWatch 客户端
  9.    ALARM_NAME = f"CloudFront-{account_id}-{distribution_id}-{metric}-Anomaly"
  10.    cloudwatch = boto3.client('cloudwatch', region_name='us-east-1')
  11.    try:
  12.        # 创建异常检测模型
  13.        response = cloudwatch.put_anomaly_detector(
  14.            MetricName=metric,
  15.            Namespace='AWS/CloudFront',
  16.            Dimensions=[
  17.                {
  18.                    'Name': 'DistributionId',
  19.                    'Value': distribution_id
  20.                },
  21.            ],
  22.            Stat='Sum',
  23.        )
  24.        print(f"==== created detactor model for {ALARM_NAME}==== ")
  25.        # 创建基于异常检测的告警
  26.        response = cloudwatch.put_metric_alarm(
  27.            AlarmName=ALARM_NAME,
  28.            ComparisonOperator='GreaterThanUpperThreshold',
  29.            TreatMissingData = "notBreaching",
  30.            ActionsEnabled = True,
  31.            EvaluationPeriods = 5,
  32.            DatapointsToAlarm = 3,
  33.            Metrics = [
  34.                {
  35.                    "Id": f"m_cdn_{metric}_{account_id}_{distribution_id}",
  36.                    "MetricStat": {
  37.                        "Metric": {
  38.                            "Namespace": "AWS/CloudFront",
  39.                            "MetricName": metric,
  40.                            "Dimensions": [
  41.                                {
  42.                                    "Name": "Region",
  43.                                    "Value": 'Global'
  44.                                },
  45.                                {
  46.                                    "Name": "DistributionId",
  47.                                    "Value": distribution_id
  48.                                }
  49.                            ]
  50.                        },
  51.                        "Period": 60,
  52.                        "Stat": "Sum"
  53.                    },
  54.                    "AccountId": account_id,
  55.                    "ReturnData": True
  56.                },
  57.                {
  58.                    "Id": f"ad_cdn_{metric}_{account_id}_{distribution_id}",
  59.                    "Expression": f"ANOMALY_DETECTION_BAND(m_cdn_{metric}_{account_id}_{distribution_id}, {ANOMALY_DETECTION_BAND})",
  60.                    "Label": f"{metric} (expected)",
  61.                    "ReturnData": True
  62.                }
  63.            ],
  64.            
  65.            ThresholdMetricId=f"ad_cdn_{metric}_{account_id}_{distribution_id}",
  66.            AlarmActions=[sns_arn]
  67.        )
  68.        print(f"已创建告警: {ALARM_NAME}")
  69.    except ClientError as e:
  70.        print(f"创建告警失败: {e}")

左右滑动查看完整示意

2、 执行代码部署上去

两个文件需要放同一个目录,并修改 get_cross_account_distributionId.py 文件的部分信息:

  • OwningAccount ,源账号的 Amazon account ID

  • sns_arn ,修改为实际的 SNS ARN 地址

python3 get_cross_account_distributionId.py

472ec9a3f7f72996dd72f306a59a9ff6.png

3、 ANOMALY_DETECTION_BAND 说明

在创建异常检测告警时,我们需要指定一个参数 ANOMALY_DETECTION_BAND。这个值用于定义异常检测带的厚度。您设置的数值会乘以指标的标准差。如果使用较高的值,异常检测带就会变得更宽更厚,这样一些异常值可能被忽略。但如果使用较小的数值,就可能产生大量的误报。基本上,这个值取决于您的指标数据的特征,以及您希望异常检测带有多精确。考虑到 CDN 的流量通常会产生较大的请求数和带宽的波动,您可以先将 ANOMALY_DETECTION_BAND 设置的高一些,例如 5 。然后选择几个 Amazon CloudFront 分配,观察异常检测带是否能覆盖正常的 Request 和 BytesDownloaded 波形,再根据实际情况将 BAND 调大或者调小。我们的目的是监控 CDN 流量的异常增长,所以只需要观察波峰。另外,您也不需要观察所有的 Amazon CloudFront 分配,选择几个典型的分配来评估 BAND 数值即可。由于 Amazon CloudWatch 异常检测会对模型进行持续的评估和调整,所以 ANOMALY_DETECTION_BAND 主要起到种子的作用,您不需要过于担心它的精准性。

3ebab2733b3907c8c412cf879a42df4f.png

成本预估

异常检测警报会产生以下成本(集中账号):

  1. 您在 alarm 中用到的每个指标的成本。

  2. 额外的两个警报指标成本,用于计算异常检测模型生成的上下限指标。

d0387fbaaa649db02e943e789888f0ad.png

官方计价

扫码了解更多

举例:

假设现在有一个集中账号和一个源账号,其中源账号有 100 个分配需要跨账号监控。这时候源账号在只共享 Logs 和 Metrics 的情况下不会产生额外的费用,集中账号会产生 100*3*2 = 600 个 metric alarms 的费用,因为每个 metric 会产生 3 个 alarm-metric 的费用,然后我们的代码监控 ‘Requests’ 和 ‘BytesDownloaded’ 这两个源账号的指标。

总结

通过 Amazon CloudWatch 的跨账号异常检测功能,我们可以实现使用集中账号来监控多个源账号的 Amazon CloudFront 维度,通过机器学习自动和迅速地发现异常,提高系统可观测性和可靠性,同时简化了异常检测的实施和管理。但是对于新创建的或者预知到有突发流量(如线上推广活动)的 Amazon CloudFront 分配,异常监控可能会产生误报,在这期间可以适当暂停异常监控告警功能,转而使用 Amazon Budgets 对 Link 账号进行成本控制。

参考链接

cb1ba425524f49efbb3eb2ee94bad65f.png

Amazon CloudWatch 

现在支持跨账户异常检测

扫码了解更多

8dcb31bf68a9466f637f8fd2e52bcfa8.png

建立监控账号

扫码了解更多

a5e22ccc5a9bfe7ccc4857db865694a0.png

使用

Amazon CloudWatch 

异常检测

扫码了解更多

左右滑动查看更多

本篇作者

4f6b241da9170588ff8f37afc5c535a6.jpeg

林进风

2017 年加入亚马逊云科技,现从事方案架构( SA )工作,在计算、联网、数据库方面以及 Serverless 领域学习和研究。在硬件和应用容灾以及高可用方面有相关经验。

1f83a1c2eb5e4800ea17a4a25ba42a7d.jpeg

张振威

亚马逊云科技 APN 解决方案架构师,主要负责合作伙伴架构咨询和方案设计,同时致力于亚马逊云科技云服务在国内的应用及推广,擅长数据迁移、数据库调优和数据分析。

1ba2399abe77592596b4c5f24090c52e.jpeg

陈程

亚马逊云科技高级边缘产品架构师,专注于

Amazon CloudFront 、 Amazon WAF 、 Amazon Shield 、 Amazon Global Accelerator 、 Amazon Route 53 等产品和服务。

45b7da960e3baceb325f79037e4919dd.jpeg

庄颖勤

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案架构设计、咨询、实施等工作。在 DevOps 、 CI/CD 和容器等领域拥有丰富的技术和支持经验,致力于帮助客户实现技术创新和业务发展。

ae55e2dd34f831b62b9fcf7a65a1cf37.jpeg

柯俊雄

亚马逊云科技解决方案架构师,专注于数据分析/容器化领域。

9c8142defdf00dcd87c3c3eaff246b88.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

点击阅读原文查看博客,获得更详细内容

听说,点完下面4个按钮

就不会碰到bug了!

209abbc6a071cc9dc93902464495c2b2.gif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/816436
推荐阅读
相关标签
  

闽ICP备14008679号