工作原理
Fargate 采集器(dag-fargate-agent)作为 应用容器内的 PID 1 运行,而不是作为独立的主机级进程运行。启动时,它会安装一个 seccomp-BPF 过滤器,仅拦截 Hilt 关心的约 20 个系统调用(execve、open、unlink、rename、chmod、connect 等),然后 fork+exec 你的原始应用程序。每个子进程都会继承该过滤器。其余部分——read、write、futex、epoll_wait 以及其余的高频路径——都以原生速度运行,不受任何插桩影响。
你不需要重建应用镜像。一个安装器 sidecar 容器会在你的应用启动前,把代理二进制文件复制到一个任务范围(task-scoped)的共享卷中;你的任务定义的入口点会被重写为先启动该代理,再由代理启动你的原始命令。这与 Datadog 或 Aqua 等 APM/安全类 sidecar 所使用的注入模式相同。
此机制专用于 ECS Fargate。在 Kubernetes 和普通 Linux VM 上,采集器使用 eBPF 并作为独立进程运行——参见在 Kubernetes 上部署和在 VM 上部署。Fargate 单纯是不允许 eBPF 所需的那些特权。
前提条件
- 一个 ECS Fargate 任务(Linux,
x86_64或arm64/Graviton) - 一个可访问的 Hilt 摄取端点(
DAG_SHIP_URL,在入驻过程中提供) - Hilt 在入驻时提供的安装器镜像 URI(通常是你账户 ECR 中的固定标签,例如
<account>.dkr.ecr.<region>.amazonaws.com/<name>/dag-fargate-installer:vX.Y.Z)。任务执行角色必须有权限拉取该镜像。
会对任务定义注入哪些内容
无论你使用下面哪种安装方式,最终对任务定义所做的改动都是一样的:
如果运行时出现任何附加失败,代理会故障开放(fail open):无论是否有遥测数据,你的应用始终会启动并正常运行。
安装
请根据你目前管理任务定义的方式选择对应的方式。以下四种方式最终产生的注入结果相同(见上文)。方式一:CLI(推荐用于 CI/CD)
1
安装注入 CLI
2
导出当前任务定义
3
注入代理
--image 使用入驻时提供的安装器镜像 URI。该工具是幂等的——对已经注入过的任务定义再次运行不会产生任何效果。4
注册并上线
方式二:Terraform
方式三:AWS Copilot
Copilot 会从manifest.yml 生成任务定义,因此这条路径只涉及清单编辑加一份文档化的覆盖配置 —— 无需编写代码:
1
添加 sidecar、共享卷、入口点和环境变量
将 Copilot manifest 片段 中的
sidecars、storage.volumes 和 entrypoint 块合并到你的服务的 copilot/<service>/manifest.yml 中,并将 <original-command> 替换为你应用真正的入口点,将安装器的 image: 替换为入驻时提供的 URI。2
添加 SYS_PTRACE 能力和 dependsOn
这两项设置并非 manifest 的一等字段,因此需要通过 Copilot 的任务定义覆盖机制来添加:然后将覆盖规则复制到
copilot/<service>/overrides/cfn.patches.yml 中。3
部署
方式四:CloudFormation
如果你的任务定义是以原生 CloudFormation 编写的,CLI 可以直接输出一段可粘贴的ContainerDefinitions 代码块,而不是完整的任务定义 JSON(CFN 使用 PascalCase 键名,且可能包含如 !Ref 之类的内建函数,这些会被原样传递,而不会被求值):
配置
所有配置都通过任务定义中应用容器上设置的环境变量进行:模式
完整模式(默认)
- exec 和文件事件(open、unlink、rename、chmod、exec):通过 seccomp+ptrace 引擎精确捕获——不会遗漏短生命周期进程。
- 网络流:连接生命周期(connect/close)通过 ptrace 捕获,字节计数通过周期性的
sock_diag轮询获得,而非直接拦截read/write。 - 开销:在系统调用密集的工作负载上,CPU 开销为个位数百分比,因为只有被拦截的系统调用会离开快速路径。
元数据模式(Kill Switch)
将DAG_FARGATE_MODE 设为 metadata,即可完全禁用 ptrace 引擎,且不需要重新部署镜像——只需在任务定义中翻转该环境变量并滚动更新服务即可。
- exec 事件:每 250ms 扫描一次
/proc(可能遗漏极短生命周期的进程) - 网络流:每 2s 轮询一次
sock_diag - 文件事件:无
- 开销:可忽略不计
与 eBPF 采集器的覆盖范围对比
Fargate 代理发送的事件线上格式与 Kubernetes/VM 采集器完全相同——下游流水线和仪表盘无需任何改动,两种类型的主机会一起出现在视图中。由于 Fargate 不允许内核访问,覆盖范围有所不同:身份映射
Fargate 任务比 Kubernetes 节点或 VM 更为短暂(ephemeral)。相比你在其他环境中的经验,主机群视图中会有更多的更替,这是预期行为——
task_definition_family 标签为你提供了一种随时间稳定地将属于同一服务的任务分组在一起的方式。验证
部署后,在采集器页面确认:- 任务显示
host_type为ecs_fargate - 已正确分组到相应的 ECS 集群名称下
task_definition_family标签存在- exec 和网络事件正常到达
升级
(通过你安装时使用的方式)更新安装器镜像标签,并重新注册任务定义。由于代理二进制文件在每次任务启动时都会从安装器容器重新复制,因此每次新的任务启动都会自动获取最新的代理版本——无需原地替换二进制文件。卸载
移除已注入的部分(安装器容器、共享卷、入口点重写、SYS_PTRACE 能力、dependsOn,以及 DAG_* 环境变量),并注册新的任务定义版本。如果你是通过 CLI 或 Terraform 模块安装的,针对你原始的、未注入的任务定义重新运行一次,即可得到一个干净的版本。
