

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Amazon ECS 叢集上自動探索的詳細指南
<a name="ContainerInsights-Prometheus-Setup-autodiscovery-ecs"></a>

Prometheus 提供數十種動態服務探索機制，如 [<scrape\_config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#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>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#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`

**注意**  
不符合規則表達式的 Docker 標籤 `[a-zA-Z_][a-zA-Z0-9_]*` 會被篩選掉。這與 Prometheus 文件中的[組態檔案](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#labelname)的 `label_name` 列出的 Prometheus 慣例相符。

## ECS 服務探索組態範例
<a name="ContainerInsights-Prometheus-Setup-autodiscovery-ecs-examples"></a>

本節包含示範 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，以下列格式建構 Prometheus 匯出工具目標：`private_ip:host_port`。

`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` 檔案中。將掃描帶有 Docker 標籤的容器 `ECS_PROMETHEUS_EXPORTER_PORT_SUBSET_A`。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 代理程式將會每 5 分鐘查詢一次 ECS 任務的中繼資料，然後將已搜索到的目標寫入 CloudWatch 代理程式容器內的 `/tmp/cwagent_ecs_auto_sd.yaml` 檔案中。

定義了兩個任務定義 ARN 規則表達式部分：
+  對於第一個區段，會篩選出其 ECS 任務定義 ARN 中具有 `javajmx` 的 ECS 任務，以進行容器連接埠掃描。如果這些 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` 且 `:23` 的 `version` 的 ECS 任務，以進行容器連接埠掃描。對於名稱為 `envoy` 且在 `9901` 上公開容器連接埠的容器，則會使用映射的主機連接埠以及容器的私有 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 代理程式將會每 5 分鐘查詢一次 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.*`，以進行容器連接埠掃描。對於名稱為 `haproxy` 且在 8404 上公開容器連接埠的容器，則會使用映射的主機連接埠以及容器的私有 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 標籤的 ECS 任務 `MY_PROMETHEUS_EXPORTER_PORT_LABEL` 將被篩選為 Prometheus 連接埠掃描。目標 Prometheus 容器連接埠由標籤 `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 任務，以進行容器連接埠掃描。目標 Prometheus 容器連接埠由 `sd_metrics_ports` 定義為 9150。使用預設指標路徑 `/metrics`。使用 Prometheus 組態中定義的任務名稱。