Amazon ECS 集群上自动发现的详细指南 - Amazon CloudWatch
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon ECS 集群上自动发现的详细指南

Prometheus 提供了数十种动态服务发现机制,如 <scrape_config> 中所述。但是,Amazon ECS 没有内置服务发现。CloudWatch 代理添加了此机制。

启用 Amazon ECS Prometheus 服务发现后,CloudWatch 代理会定期对 Amazon ECS 和 Amazon EC2 前端进行以下 API 调用,以检索目标 ECS 集群中正在运行的 ECS 任务的元数据。

EC2:DescribeInstances ECS:ListTasks ECS:ListServices ECS:DescribeContainerInstances ECS:DescribeServices ECS:DescribeTasks ECS:DescribeTaskDefinition

CloudWatch 代理使用元数据来扫描 ECS 集群内的 Prometheus 目标。CloudWatch 代理支持三种服务发现模式:

  • 基于容器 docker 标签的服务发现

  • 基于 ECS 任务定义 ARN 正则表达式的服务发现

  • 基于 ECS 服务名称正则表达式的服务发现

所有模式均可同时使用。CloudWatch 代理会根据 {private_ip}:{port}/{metrics_path} 对发现的目标进行重复去除。

所有发现的目标均写入由 CloudWatch 代理容器内的 sd_result_file 配置字段指定的结果文件。以下为示例结果文件:

- targets: - 10.6.1.95:32785 labels: __metrics_path__: /metrics ECS_PROMETHEUS_EXPORTER_PORT: "9406" ECS_PROMETHEUS_JOB_NAME: demo-jar-ec2-bridge-dynamic ECS_PROMETHEUS_METRICS_PATH: /metrics InstanceType: t3.medium LaunchType: EC2 SubnetId: subnet-123456789012 TaskDefinitionFamily: demo-jar-ec2-bridge-dynamic-port TaskGroup: family:demo-jar-ec2-bridge-dynamic-port TaskRevision: "7" VpcId: vpc-01234567890 container_name: demo-jar-ec2-bridge-dynamic-port job: demo-jar-ec2-bridge-dynamic - targets: - 10.6.3.193:9404 labels: __metrics_path__: /metrics ECS_PROMETHEUS_EXPORTER_PORT_SUBSET_B: "9404" ECS_PROMETHEUS_JOB_NAME: demo-tomcat-ec2-bridge-mapped-port ECS_PROMETHEUS_METRICS_PATH: /metrics InstanceType: t3.medium LaunchType: EC2 SubnetId: subnet-123456789012 TaskDefinitionFamily: demo-tomcat-ec2-bridge-mapped-port TaskGroup: family:demo-jar-tomcat-bridge-mapped-port TaskRevision: "12" VpcId: vpc-01234567890 container_name: demo-tomcat-ec2-bridge-mapped-port job: demo-tomcat-ec2-bridge-mapped-port

您可以直接将此结果文件与基于 Prometheus 文件的服务发现集成。有关基于 Prometheus 文件的服务发现的更多信息,请参阅 <file_sd_config>

假设将结果文件写入 /tmp/cwagent_ecs_auto_sd.yaml。以下 Prometheus 抓取配置将使用它。

global: scrape_interval: 1m scrape_timeout: 10s scrape_configs: - job_name: cwagent-ecs-file-sd-config sample_limit: 10000 file_sd_configs: - files: [ "/tmp/cwagent_ecs_auto_sd.yaml" ]

CloudWatch 代理还会为发现的目标添加以下附加标签。

  • container_name

  • TaskDefinitionFamily

  • TaskRevision

  • TaskGroup

  • StartedBy

  • LaunchType

  • job

  • __metrics_path__

  • Docker 标签

当集群具有 EC2 启动类型时,会添加以下三个标签。

  • InstanceType

  • VpcId

  • SubnetId

注意

与正则表达式 [a-zA-Z_][a-zA-Z0-9_]* 不匹配的 Docker 标签将被筛选掉。这与 Prometheus 文档中配置文件label_name 中列出的 Prometheus 惯例相匹配。

ECS 服务发现配置示例

本节包括演示 ECS 服务发现的示例。

示例 1

"ecs_service_discovery": { "sd_frequency": "1m", "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml", "docker_label": { } }

此示例启用基于 docker 标签的服务发现。CloudWatch 代理将每分钟查询一次 ECS 任务的元数据,并将发现的目标写入 CloudWatch 代理容器内的 /tmp/cwagent_ecs_auto_sd.yaml 文件中。

docker_label 部分中 sd_port_label 的默认值为 ECS_PROMETHEUS_EXPORTER_PORT。如果 ECS 任务中任何正在运行的容器具有 ECS_PROMETHEUS_EXPORTER_PORT docker 标签,CloudWatch 代理将其值作为 container port 来扫描容器的所有公开端口。如果匹配,则使用映射的主机端口和容器的私有 IP,以 private_ip:host_port 格式来构建 Prometheus 导出器目标。

docker_label 部分中 sd_metrics_path_label 的默认值为 ECS_PROMETHEUS_METRICS_PATH。如果容器具有此 docker 标签,则其值将用作 __metrics_path__。如果容器没有此标签,则使用默认值 /metrics

docker_label 部分中 sd_job_name_label 的默认值为 job。如果容器具有此 docker 标签,则其值将作为一个目标标签附加,以替换 Prometheus 配置中指定的默认任务名称。此 docker 标签的值用作 CloudWatch Logs 日志组中的日志流名称。

示例 2

"ecs_service_discovery": { "sd_frequency": "15s", "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml", "docker_label": { "sd_port_label": "ECS_PROMETHEUS_EXPORTER_PORT_SUBSET_A", "sd_job_name_label": "ECS_PROMETHEUS_JOB_NAME" } }

此示例启用基于 docker 标签的服务发现。CloudWatch 代理将每 15 秒查询一次 ECS 任务的元数据,并将发现的目标写入 CloudWatch 代理容器内的 /tmp/cwagent_ecs_auto_sd.yaml 文件中。带有 ECS_PROMETHEUS_EXPORTER_PORT_SUBSET_A 的 docker 标签的容器将被扫描。docker 标签 ECS_PROMETHEUS_JOB_NAME 的值用作任务名称。

示例 3

"ecs_service_discovery": { "sd_frequency": "5m", "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml", "task_definition_list": [ { "sd_job_name": "java-prometheus", "sd_metrics_path": "/metrics", "sd_metrics_ports": "9404; 9406", "sd_task_definition_arn_pattern": ".*:task-definition/.*javajmx.*:[0-9]+" }, { "sd_job_name": "envoy-prometheus", "sd_metrics_path": "/stats/prometheus", "sd_container_name_pattern": "^envoy$", "sd_metrics_ports": "9901", "sd_task_definition_arn_pattern": ".*:task-definition/.*appmesh.*:23" } ] }

此示例启用基于 ECS 任务定义 ARN 正则表达式的服务发现。CloudWatch 代理将每五分钟查询一次 ECS 任务的元数据,并将发现的目标写入 CloudWatch 代理容器内的 /tmp/cwagent_ecs_auto_sd.yaml 文件中。

定义了两个任务定义 ARN 正则表达式部分:

  • 对于第一部分,过滤 ECS 任务定义 ARN 中的 ECS 任务以及 javajmx,以进行容器端口扫描。如果这些 ECS 任务中的容器在 9404 或 9406 上公开容器端口,则映射的主机端口和容器的私有 IP 会用于创建 Prometheus 导出器目标。sd_metrics_path 的值将 __metrics_path__ 设置为 /metrics。因此 CloudWatch 代理将从 private_ip:host_port/metrics 中抓取 Prometheus 指标,抓取的指标发送到日志组 /aws/ecs/containerinsights/cluster_name/prometheus 中 CloudWatch Logs 中的 java-prometheus 日志流。

  • 对于第二部分,过滤 ECS 任务定义 ARN 中带有 appmesh 的 ECS 任务以及 :23version,以进行容器端口扫描。对于在 9901 上公开容器端口的、名称为 envoy 的容器,映射的主机端口以及容器的私有 IP 用于创建 Prometheus 导出器目标。这些 ECS 任务中的值会公开 9404 或 9406 上的容器端口,映射的主机端口以及容器的私有 IP 用于创建 Prometheus 导出器目标。sd_metrics_path 的值将 __metrics_path__ 设置为 /stats/prometheus。因此,CloudWatch 代理将从 private_ip:host_port/stats/prometheus 中抓取 Prometheus 指标,并将抓取的指标发送到日志组 /aws/ecs/containerinsights/cluster_name/prometheus 中的 CloudWatch Logs 中的 envoy-prometheus 日志流。

示例 4

"ecs_service_discovery": { "sd_frequency": "5m", "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml", "service_name_list_for_tasks": [ { "sd_job_name": "nginx-prometheus", "sd_metrics_path": "/metrics", "sd_metrics_ports": "9113", "sd_service_name_pattern": "^nginx-.*" }, { "sd_job_name": "haproxy-prometheus", "sd_metrics_path": "/stats/metrics", "sd_container_name_pattern": "^haproxy$", "sd_metrics_ports": "8404", "sd_service_name_pattern": ".*haproxy-service.*" } ] }

本示例启用基于 ECS 服务名称正则表达式的服务发现。CloudWatch 代理将每五分钟查询一次 ECS 服务的元数据,并将发现的目标写入 CloudWatch 代理容器内的 /tmp/cwagent_ecs_auto_sd.yaml 文件中。

定义了两个服务名称正则表达式部分:

  • 对于第一部分,过滤与 ECS 服务关联的 ECS 任务(名称与正则表达式 ^nginx-.* 相匹配),以进行容器端口扫描。如果这些 ECS 任务中的容器在 9113 上公开容器端口,则映射的主机端口和容器的私有 IP 将用于创建 Prometheus 导出器目标。sd_metrics_path 的值将 __metrics_path__ 设置为 /metrics。因此,CloudWatch 代理将从 private_ip:host_port/metrics 中抓取 Prometheus 指标,并将抓取的指标发送到日志组 /aws/ecs/containerinsights/cluster_name/prometheus 中 CloudWatch Logs 中的 nginx-prometheus 日志流。

  • 或第二部分,过滤与 ECS 服务关联的 ECS 任务(名称与正则表达式 .*haproxy-service.* 匹配),以进行容器端口扫描。对于在 8404 上公开容器端口、名称为 haproxy 的容器,映射的主机端口以及容器的私有 IP 用于创建 Prometheus 导出器目标。sd_metrics_path 的值将 __metrics_path__ 设置为 /stats/metrics。因此,CloudWatch 代理将从 private_ip:host_port/stats/metrics 中抓取 Prometheus 指标,并将抓取的指标发送到日志组 /aws/ecs/containerinsights/cluster_name/prometheus 中 CloudWatch Logs 中的 haproxy-prometheus 日志流。

示例 5

"ecs_service_discovery": { "sd_frequency": "1m30s", "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml", "docker_label": { "sd_port_label": "MY_PROMETHEUS_EXPORTER_PORT_LABEL", "sd_metrics_path_label": "MY_PROMETHEUS_METRICS_PATH_LABEL", "sd_job_name_label": "MY_PROMETHEUS_METRICS_NAME_LABEL" } "task_definition_list": [ { "sd_metrics_ports": "9150", "sd_task_definition_arn_pattern": "*memcached.*" } ] }

本示例启用了两种 ECS 服务发现模式。CloudWatch 代理将每 90 秒查询一次 ECS 任务的元数据,并将发现的目标写入 CloudWatch 代理容器内的 /tmp/cwagent_ecs_auto_sd.yaml 文件中。

对于基于 docker 的服务发现配置:

  • 过滤带有 docker 标签 MY_PROMETHEUS_EXPORTER_PORT_LABEL 的 ECS 任务,以进行 Prometheus 端口扫描。目标 Prometheus 容器端口由 label MY_PROMETHEUS_EXPORTER_PORT_LABEL 的值指定。

  • docker 标签 MY_PROMETHEUS_EXPORTER_PORT_LABEL 的值用于 __metrics_path__。如果容器没有此 docker 标签,则使用默认值 /metrics

  • docker 标签 MY_PROMETHEUS_EXPORTER_PORT_LABEL 的值用作任务标签。如果容器没有此 docker 标签,则使用 Prometheus 配置中定义的任务名称。

对于基于 ECS 任务定义 ARN 正则表达式的服务发现配置:

  • 过滤 ECS 任务定义 ARN 中带 memcached 的 ECS 任务,以进行容器端口扫描。根据 sd_metrics_ports 定义,目标 Prometheus 容器端口是 9150。使用默认指标路径 /metrics。使用 Prometheus 配置中定义的任务名称。