当 SageMaker Pipelines 分散在多个 AWS 账号和区域后,排查一次训练流水线失败,往往要经历切换账号、切换区域、搜索流水线、检查执行状态等步骤。来源方案通过 Amazon CloudWatch 自定义仪表盘集中展示这些流水线的运行信息,并提供可定制的 AWS CDK 基础设施示例,使监控入口可以随账号和区域扩展。
仪表盘解决的是“统一观察”,不是数据自动汇聚
CloudWatch Dashboard 可以把不同账号、不同区域的指标放到同一页面,但仪表盘本身不会自动发现 SageMaker Pipelines,也不会替你建立跨账号权限。落地时应把系统拆成三层:
- 数据层:SageMaker Pipelines 的原生指标,或者由 EventBridge、Lambda 等组件生成的自定义指标。
- 访问层:CloudWatch 跨账号可观测性、Observability Access Manager(OAM)或组织现有的跨账号共享机制。
- 展示层:部署在监控账号中的 CloudWatch 自定义仪表盘。
跨区域场景还需要单独处理区域边界。指标和 OAM 资源具有区域属性,因此每个被监控区域都要完成相应配置;Dashboard 小组件则通过 region 指向指标所在区域。
一个常见拓扑是使用专门的可观测性账号作为监控账号,各业务账号作为源账号。源账号开放所需指标,监控账号统一部署 Dashboard。这样可以避免团队成员为了查看状态而获得生产账号中的宽泛权限。
先定义真正有用的流水线信号
仪表盘不应只是把所有可用指标堆在一起。对 SageMaker Pipelines,通常更值得集中展示的是:
- 每条流水线的成功、失败和停止次数;
- 当前正在运行或排队的执行数量;
- 执行耗时及其趋势;
- 按账号、区域、流水线名称划分的失败分布;
- 最近一次失败发生的时间,以及对应告警状态。
来源摘要没有限定具体指标命名或采集方式。实际项目可以直接使用环境中已有的 CloudWatch 指标,也可以这样实践:通过 EventBridge 捕获流水线执行状态变化,由 Lambda 向统一命名空间发布计数和耗时指标。例如使用 Central/SageMakerPipelines 命名空间,并以 PipelineName 作为维度。
要控制维度基数。不要把流水线执行 ID、提交哈希或时间戳直接作为 CloudWatch 指标维度,否则每次执行都可能产生新的时间序列,增加成本并降低图表可读性。执行 ID 更适合保留在日志或事件记录中,再从仪表盘跳转查询。
用 AWS CDK 生成跨账号、跨区域仪表盘
下面是一个可以改造的 AWS CDK Python 示例。这里明确作出两个假设:源账号已经完成 CloudWatch 跨账号共享,并且采集器已经发布 Central/SageMakerPipelines/ExecutionFailures 自定义指标。运行前需要替换账号 ID、区域和流水线名称。
创建项目并安装依赖:
mkdir pipeline-monitoring && cd pipeline-monitoring
cdk init app --language python
source .venv/bin/activate
python -m pip install -r requirements.txt
将 app.py 调整为:
#!/usr/bin/env python3
from aws_cdk import App, Duration, Environment, Stack
from aws_cdk import aws_cloudwatch as cloudwatch
from constructs import Construct
TARGETS = [
{
"account": "111111111111",
"region": "us-east-1",
"pipeline": "customer-churn-training",
},
{
"account": "222222222222",
"region": "eu-west-1",
"pipeline": "fraud-detection-training",
},
]
class PipelineMonitoringStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
widgets = []
for target in TARGETS:
failures = cloudwatch.Metric(
namespace="Central/SageMakerPipelines",
metric_name="ExecutionFailures",
dimensions_map={"PipelineName": target["pipeline"]},
statistic="Sum",
period=Duration.minutes(5),
account=target["account"],
region=target["region"],
)
widgets.append(
cloudwatch.GraphWidget(
title=(
f'{target["pipeline"]} failures '
f'({target["account"]}/{target["region"]})'
),
left=[failures],
width=12,
height=6,
)
)
dashboard = cloudwatch.Dashboard(
self,
"SageMakerPipelinesDashboard",
dashboard_name="sagemaker-pipelines-central-monitoring",
)
dashboard.add_widgets(*widgets)
app = App()
PipelineMonitoringStack(
app,
"PipelineMonitoringStack",
env=Environment(
account="333333333333",
region="us-east-1",
),
)
app.synth()
其中 333333333333 是监控账号。先检查生成的 CloudFormation 模板,再部署:
cdk synth
cdk deploy --require-approval never
部署后可以用 AWS CLI 验证仪表盘是否存在:
aws cloudwatch get-dashboard \
--dashboard-name sagemaker-pipelines-central-monitoring \
--region us-east-1
如果图表存在但没有数据,按以下顺序排查:确认源账号和目标区域中确实存在对应指标;确认指标名称、命名空间和维度完全一致;确认跨账号共享关系已经在该区域建立;最后检查当前用户是否具有查看共享指标和仪表盘的权限。
让配置跟着账号规模增长
直接把 TARGETS 写在代码里适合验证方案,不适合管理大量账号。进入生产环境后,可以把账号、区域和流水线清单放入 YAML 或 JSON 文件,由 CDK 在合成阶段读取;也可以从 AWS Organizations、标签清单或内部服务目录生成目标列表。
仪表盘同样不应承担告警职责。CloudWatch Alarm 负责检测失败率、长时间运行或无数据等异常,SNS、PagerDuty 或工单系统负责通知;Dashboard 用于聚合上下文和辅助定位。两者使用同一组指标,但服务于不同的响应阶段。
上线前建议检查以下事项:
- 每个源账号和区域都已建立最小权限的指标共享关系;
- 自定义指标命名空间、维度和统计周期已有统一约定;
- 仪表盘变量或配置文件能够容纳新增账号和流水线;
- 失败、超时和无数据场景都配置了独立告警;
- 已评估自定义指标、跨账号观测、告警和日志查询成本;
- CDK 部署角色不能借助监控方案获得不必要的生产资源权限。
集中式仪表盘的价值不在于减少页面数量,而在于建立一致的运行视图。先统一指标语义和跨账号权限,再用 CDK 固化 Dashboard,才能让新增账号、区域和流水线成为一次配置变更,而不是一轮人工搭建。