如何获取CloudWatch中所有ECS实例的日志?
ECS ASG多实例场景下CloudWatch日志丢失排查方案
- 第一优先级核对任务定义的awslogs驱动配置:必须显式指定
awslogs-stream-prefix参数,这个参数在单实例单任务运行时不是强制项,很多人配置的时候会跳过,但多实例、多任务副本场景下如果缺省该配置,不同实例上运行的同名容器会生成重名的日志流,后启动的实例(也就是你说的第二个实例)没有权限写入已存在的同名日志流,直接导致日志上报失败。配置后日志流会自动按照前缀/容器名/任务ID的格式生成唯一命名,不会出现冲突,前缀填固定值比如ecs-service即可。 - 核对ASG新启动实例的IAM权限:ASG扩容出来的实例如果绑定的IAM实例Profile没有配齐CloudWatch Logs相关权限,就会写日志失败。需要确认实例角色包含以下权限:
logs:CreateLogStream、logs:PutLogEvents、logs:DescribeLogStreams,不要给权限配置资源级限制限定到特定日志流,否则新实例创建新流的时候会被拦截。可以直接SSH到出问题的第二个实例上,执行cat /var/log/ecs/ecs-agent.log | grep -i awslogs,如果看到PermissionDenied相关的报错就能直接定位是权限问题。 - 检查实例网络连通性:如果ECS实例跑在私有子网,要确认扩容出来的实例所在可用区的路由表配置正确——要么有通公网的NAT网关,要么已经绑定了对应可用区的CloudWatch Logs VPC端点,很多人跨AZ扩容的时候漏配新AZ的路由和端点,导致新实例根本连不上CloudWatch服务,自然传不上日志。可以在实例上执行
curl -v https://logs.<你的集群所在区域>.amazonaws.com测试连通性,连不通的话先修网络。 - 不要在业务Docker镜像里内置CloudWatch Agent来收集任务标准输出日志:ECS的awslogs日志驱动是靠宿主机上的ECS Agent直接捕获容器stdout/stderr上报的,和容器内部署的CloudWatch Agent完全是两套链路,容器内的agent默认没有访问宿主机docker socket的权限,根本读不到其他容器的日志,配了也解决不了问题,反而可能因为权限配置问题干扰宿主机的正常日志上报。
- 核对CloudWatch控制台的查询筛选条件:很多人第一次查完单实例日志后,会在日志组里手动选中单个日志流做筛选,后续新实例创建的新日志流不会被自动纳入查询范围,查的时候记得选择“所有日志流”,不要手动指定特定流,避免漏查新实例的日志。
实操中90%以上的同类问题都是漏配
awslogs-stream-prefix导致的,这个参数的强制要求只在多副本场景下触发,单实例测试时不会暴露问题,很容易被忽略。
内容的提问来源于stack exchange,提问作者Gerald
相关产品推荐
相关产品推荐

