

# 在亚马逊云服务器集群上设置和配置 Prometheus 指标收集 在 Amazon ECS 集群上设置和配置 Prometheus 指标收集
<a name="ContainerInsights-Prometheus-Setup-ECS"></a>

要从 Amazon ECS 集群收集 Prometheus 指标，您可以使用 CloudWatch 代理作为收集器或使用 AWS Distro for OpenTelemetry 收集器。有关使用 AWS Distro for OpenTelemetry 收集器的信息，请参阅 [https://aws-otel.github.io/docs/getting-started/container-insights/ecs-prometheus](https://aws-otel.github.io/docs/getting-started/container-insights/ecs-prometheus)。

下面几节介绍如何使用 CloudWatch 代理作为收集器来检索 Prometheus 指标。您可以在运行 Amazon ECS 的集群上安装带有 Prometheus 监控功能的 CloudWatch 代理，还可以选择配置该代理以抓取其他目标。这些部分还提供用于设置示例工作负载的可选教程，以使用 Prometheus 监控进行测试。

Amazon ECS 上的 Container Insights 支持 Prometheus 指标的以下启动类型和网络模式组合：


| Amazon ECS 启动类型 | 支持的网络模式 | 
| --- | --- | 
|  EC2 (Linux)  |  网桥、主机和 awsvpc  | 
|  Fargate  |  awsvpc  | 

**VPC 安全组要求**

Prometheus 工作负载的安全组的入口规则必须向 CloudWatch 代理打开 Prometheus 端口，以便通过私有 IP 抓取 Prometheus 指标。

CloudWatch 代理的安全组的出口规则必须允许 CloudWatch 代理通过私有 IP 连接到 Prometheus 工作负载的端口。

**Topics**
+ [

# 在 Amazon ECS 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理
](ContainerInsights-Prometheus-install-ECS.md)
+ [

# 抓取其他 Prometheus 源并导入这些指标
](ContainerInsights-Prometheus-Setup-configure-ECS.md)
+ [

# （可选）为 Prometheus 指标测试设置示例容器化 Amazon ECS 工作负载
](ContainerInsights-Prometheus-Sample-Workloads-ECS.md)

# 在 Amazon ECS 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理
<a name="ContainerInsights-Prometheus-install-ECS"></a>

本节介绍如何在运行 Amazon ECS 的集群中设置带有 Prometheus 监控功能的 CloudWatch 代理。执行此操作后，代理会自动抓取并导入该集群中运行的以下工作负载的指标。
+ AWS App Mesh
+ Java/JMX

您还可以将代理配置为从其他 Prometheus 工作负载和源抓取及导入指标。

## 设置 IAM 角色
<a name="ContainerInsights-Prometheus-Setup-ECS-IAM"></a>

您需要两个 IAM 角色来执行 CloudWatch 代理任务定义。如果您指定 CloudFormation 堆栈中的 **CreateIAMRoles=True** 让 Container Insights 为您创建这些角色，则将使用正确的权限创建这些角色。如果要自己创建或使用现有角色，则需要以下角色和权限。
+ **CloudWatch 代理 ECS 任务角色** – CloudWatch 代理容器使用此角色。它必须包括 **CloudWatchAgentServerPolicy** 策略以及包含以下只读权限的客户管理策略：
  + `ec2:DescribeInstances`
  + `ecs:ListTasks`
  + `ecs:ListServices`
  + `ecs:DescribeContainerInstances`
  + `ecs:DescribeServices`
  + `ecs:DescribeTasks`
  + `ecs:DescribeTaskDefinition`
+ **CloudWatch 代理 ECS 任务执行角色** – 这是 Amazon ECS 启动和执行容器所需的角色。确保您的任务执行角色附加了 **AmazonSSMReadOnlyAccess**、**AmazonECSTaskExecutionRolePolicy** 和 **CloudWatchAgentServerPolicy** 策略。如果您需要存储更敏感的数据以供 Amazon ECS 使用，请参阅[指定敏感数据](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html)以了解更多信息。

## 使用 CloudFormation 安装带有 Prometheus 监控功能的 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup-ECS-CFN"></a>

您使用 AWS CloudFormation 为 Amazon ECS 集群安装带有 Prometheus 监控功能的 CloudWatch 代理。以下列表显示了您将在 CloudFormation 模板中使用的参数。
+ **ECSClusterName** – 指定目标 Amazon ECS 集群。
+ **CreateIAMRoles** – 指定 **True** 为 Amazon ECS 任务角色和 Amazon ECS 任务执行角色创建新角色。指定 **False** 重新使用现有角色。
+ **TaskRoleName** – 如果您为 **CreateIAMRoles** 指定 **True**，这会指定用于新 Amazon ECS 任务角色的名称。如果您为 **CreateIAMRoles** 指定 **False**，这会指定要用作 Amazon ECS 任务角色的现有角色。
+ **ExecutionRoleName** – 如果您为 **CreateIAMRoles** 指定 **True**，这会指定用于新 Amazon ECS 任务执行角色的名称。如果您为 **CreateIAMRoles** 指定 **False**，这会指定要用作 Amazon ECS 任务执行角色的现有角色。
+ **ECSNetworkMode** – 如果您使用 EC2 启动类型，请在此处指定网络模式。必须是 **bridge** 或 **host**。
+ **ECSLaunchType** – 指定 **fargate** 或 **EC2**。
+ **SecurityGroupID** – 如果 **ECSNetworkMode** 是 **awsvpc**，请在此处指定安全组 ID。
+ **SubnetID** – 如果 **ECSNetworkMode** 是 **awsvpc**，请在此处指定子网 ID。

### 命令示例
<a name="ContainerInsights-Prometheus-Setup-ECS-CFNcommands"></a>

本节包含在各种情况下安装带有 Prometheus 监控功能的 Container Insights 的 CloudFormation 示例命令。

**在桥式网络模式下为 Amazon ECS 集群创建 CloudFormation 堆栈**

```
export AWS_PROFILE=your_aws_config_profile_eg_default
export AWS_DEFAULT_REGION=your_aws_region_eg_ap-southeast-1
export ECS_CLUSTER_NAME=your_ec2_ecs_cluster_name
export ECS_NETWORK_MODE=bridge
export CREATE_IAM_ROLES=True
export ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
export ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name

curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml

aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
    --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
    --parameters ParameterKey=ECSClusterName,ParameterValue=${ECS_CLUSTER_NAME} \
                 ParameterKey=CreateIAMRoles,ParameterValue=${CREATE_IAM_ROLES} \
                 ParameterKey=ECSNetworkMode,ParameterValue=${ECS_NETWORK_MODE} \
                 ParameterKey=TaskRoleName,ParameterValue=${ECS_TASK_ROLE_NAME} \
                 ParameterKey=ExecutionRoleName,ParameterValue=${ECS_EXECUTION_ROLE_NAME} \
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${AWS_DEFAULT_REGION} \
    --profile ${AWS_PROFILE}
```

**在主机网络模式下为 Amazon ECS 集群创建 CloudFormation 堆栈**

```
export AWS_PROFILE=your_aws_config_profile_eg_default
export AWS_DEFAULT_REGION=your_aws_region_eg_ap-southeast-1
export ECS_CLUSTER_NAME=your_ec2_ecs_cluster_name
export ECS_NETWORK_MODE=host
export CREATE_IAM_ROLES=True
export ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
export ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name


curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml

aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
    --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
    --parameters ParameterKey=ECSClusterName,ParameterValue=${ECS_CLUSTER_NAME} \
                 ParameterKey=CreateIAMRoles,ParameterValue=${CREATE_IAM_ROLES} \
                 ParameterKey=ECSNetworkMode,ParameterValue=${ECS_NETWORK_MODE} \
                 ParameterKey=TaskRoleName,ParameterValue=${ECS_TASK_ROLE_NAME} \
                 ParameterKey=ExecutionRoleName,ParameterValue=${ECS_EXECUTION_ROLE_NAME} \ 
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${AWS_DEFAULT_REGION} \
    --profile ${AWS_PROFILE}
```

**在 awsvpc 网络模式下为 Amazon ECS 集群创建 CloudFormation 堆栈**

```
export AWS_PROFILE=your_aws_config_profile_eg_default
export AWS_DEFAULT_REGION=your_aws_region_eg_ap-southeast-1
export ECS_CLUSTER_NAME=your_ec2_ecs_cluster_name
export ECS_LAUNCH_TYPE=EC2
export CREATE_IAM_ROLES=True
export ECS_CLUSTER_SECURITY_GROUP=your_security_group_eg_sg-xxxxxxxxxx
export ECS_CLUSTER_SUBNET=your_subnet_eg_subnet-xxxxxxxxxx
export ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
export ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name

curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-awsvpc.yaml

aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-${ECS_LAUNCH_TYPE}-awsvpc \
    --template-body file://cwagent-ecs-prometheus-metric-for-awsvpc.yaml \
    --parameters ParameterKey=ECSClusterName,ParameterValue=${ECS_CLUSTER_NAME} \
                 ParameterKey=CreateIAMRoles,ParameterValue=${CREATE_IAM_ROLES} \
                 ParameterKey=ECSLaunchType,ParameterValue=${ECS_LAUNCH_TYPE} \
                 ParameterKey=SecurityGroupID,ParameterValue=${ECS_CLUSTER_SECURITY_GROUP} \
                 ParameterKey=SubnetID,ParameterValue=${ECS_CLUSTER_SUBNET} \
                 ParameterKey=TaskRoleName,ParameterValue=${ECS_TASK_ROLE_NAME} \
                 ParameterKey=ExecutionRoleName,ParameterValue=${ECS_EXECUTION_ROLE_NAME} \
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${AWS_DEFAULT_REGION} \
    --profile ${AWS_PROFILE}
```

**在 awsvpc 网络模式下为 Fargate 集群创建 CloudFormation 堆栈**

```
export AWS_PROFILE=your_aws_config_profile_eg_default
export AWS_DEFAULT_REGION=your_aws_region_eg_ap-southeast-1
export ECS_CLUSTER_NAME=your_ec2_ecs_cluster_name
export ECS_LAUNCH_TYPE=FARGATE
export CREATE_IAM_ROLES=True
export ECS_CLUSTER_SECURITY_GROUP=your_security_group_eg_sg-xxxxxxxxxx
export ECS_CLUSTER_SUBNET=your_subnet_eg_subnet-xxxxxxxxxx
export ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
export ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name            

curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-awsvpc.yaml

aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-${ECS_LAUNCH_TYPE}-awsvpc \
    --template-body file://cwagent-ecs-prometheus-metric-for-awsvpc.yaml \
    --parameters ParameterKey=ECSClusterName,ParameterValue=${ECS_CLUSTER_NAME} \
                 ParameterKey=CreateIAMRoles,ParameterValue=${CREATE_IAM_ROLES} \
                 ParameterKey=ECSLaunchType,ParameterValue=${ECS_LAUNCH_TYPE} \
                 ParameterKey=SecurityGroupID,ParameterValue=${ECS_CLUSTER_SECURITY_GROUP} \
                 ParameterKey=SubnetID,ParameterValue=${ECS_CLUSTER_SUBNET} \
                 ParameterKey=TaskRoleName,ParameterValue=${ECS_TASK_ROLE_NAME} \
                 ParameterKey=ExecutionRoleName,ParameterValue=${ECS_EXECUTION_ROLE_NAME} \
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${AWS_DEFAULT_REGION} \
    --profile ${AWS_PROFILE}
```

### CloudFormation 堆栈创建的 AWS 资源
<a name="ContainerInsights-Prometheus-Setup-ECS-resources"></a>

下表列出了 AWS 资源，该资源在 Amazon ECS 集群上使用 CloudFormation 设置 带有 Prometheus 监控功能的 Container Insights 时创建。


| 资源类型 | 资源名称 | 评论 | 
| --- | --- | --- | 
|  AWS::SSM::Parameter  |  AmazonCloudWatch-CWAgentConfig-\$1*ECS\$1CLUSTER\$1NAME*-\$1*ECS\$1LAUNCH\$1TYPE*-\$1*ECS\$1NETWORK\$1MODE*  |  这是具有默认 App Mesh 和 Java/JMX 嵌入式指标格式定义的 CloudWatch 代理。  | 
|  AWS::SSM::Parameter  |  AmazonCloudWatch-PrometheusConfigName-\$1*ECS\$1CLUSTER\$1NAME*-\$1*ECS\$1LAUNCH\$1TYPE*-\$1*ECS\$1NETWORK\$1MODE*  |  这是 Prometheus 抓取配置。  | 
|  AWS::IAM::Role  |  **\$1ECS\$1TASK\$1ROLE\$1NAME**。  |  Amazon ECS 任务角色。这仅在您为 `CREATE_IAM_ROLES` 指定 **True** 时创建。  | 
|  AWS::IAM::Role  |  **\$1\$1ECS\$1EXECUTION\$1ROLE\$1NAME\$1**   |  Amazon ECS 任务执行角色。这仅在您为 `CREATE_IAM_ROLES` 指定 **True** 时创建。  | 
|  AWS::ECS::TaskDefinition  |  cwagent-prometheus-\$1*ECS\$1CLUSTER\$1NAME*-\$1*ECS\$1LAUNCH\$1TYPE*-\$1*ECS\$1NETWORK\$1MODE*   |   | 
|  AWS::ECS::Service  |  cwagent-prometheus-replica-service-\$1*ECS\$1LAUNCH\$1TYPE*-\$1*ECS\$1NETWORK\$1MODE*  |   | 

### 使用 Prometheus 监控功能删除 CloudWatch 代理的 CloudFormation 堆栈
<a name="ContainerInsights-Prometheus-ECS-delete"></a>

要从 Amazon ECS 集群中删除 CloudWatch 代理，请输入以下命令。

```
export AWS_PROFILE=your_aws_config_profile_eg_default
export AWS_DEFAULT_REGION=your_aws_region_eg_ap-southeast-1
export CLOUDFORMATION_STACK_NAME=your_cloudformation_stack_name

aws cloudformation delete-stack \
--stack-name ${CLOUDFORMATION_STACK_NAME} \
--region ${AWS_DEFAULT_REGION} \
--profile ${AWS_PROFILE}
```

# 抓取其他 Prometheus 源并导入这些指标
<a name="ContainerInsights-Prometheus-Setup-configure-ECS"></a>

具有 Prometheus 监控功能的 CloudWatch 代理需要两种配置来抓取 Prometheus 指标。一个用于 Prometheus 文档中 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 记录的标准 Prometheus 配置。另一种配置是 CloudWatch 代理配置文件。

对于 Amazon ECS 集群，配置通过 Amazon ECS 任务定义中的密钥与 AWS Systems Manager 的 Parameter Store 集成：
+ 密钥 `PROMETHEUS_CONFIG_CONTENT` 用于 Prometheus 抓取配置。
+ 密钥 `CW_CONFIG_CONTENT` 用于 CloudWatch 代理配置。

要抓取其他 Prometheus 指标源并将这些指标导入 CloudWatch，您需要修改 Prometheus 抓取配置和 CloudWatch 代理配置，然后使用更新的配置重新部署代理。

**VPC 安全组要求**

Prometheus 工作负载的安全组的入口规则必须向 CloudWatch 代理打开 Prometheus 端口，以便通过私有 IP 抓取 Prometheus 指标。

CloudWatch 代理的安全组的出口规则必须允许 CloudWatch 代理通过私有 IP 连接到 Prometheus 工作负载的端口。

## Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Setup-config-global"></a>

CloudWatch 代理支持标准的 Prometheus 抓取配置，如 Prometheus 文档中的 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 所述。您可以编辑此部分以更新此文件中已有的配置，并添加其他 Prometheus 抓取目标。默认情况下，示例配置文件包含以下全局配置行：

```
global:
  scrape_interval: 1m
  scrape_timeout: 10s
```
+ **scrape\$1interval** – 定义抓取目标的频率。
+ **scrape\$1timeout** – 定义抓取请求超时之前的等待时间。

您还可以在作业级别为这些设置定义不同的值，以覆盖全局配置。

### Prometheus 抓取任务
<a name="ContainerInsights-Prometheus-Setup-config-scrape"></a>

CloudWatch 代理 YAML 文件已配置了一些默认的抓取任务。例如，在 Amazon ECS 的 YAML 文件（例如 `cwagent-ecs-prometheus-metric-for-bridge-host.yaml`）中，默认抓取任务在 `ecs_service_discovery` 部分中配置。

```
"ecs_service_discovery": {
                  "sd_frequency": "1m",
                  "sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml",
                  "docker_label": {
                  },
                  "task_definition_list": [
                    {
                      "sd_job_name": "ecs-appmesh-colors",
                      "sd_metrics_ports": "9901",
                      "sd_task_definition_arn_pattern": ".*:task-definition\/.*-ColorTeller-(white):[0-9]+",
                      "sd_metrics_path": "/stats/prometheus"
                    },
                    {
                      "sd_job_name": "ecs-appmesh-gateway",
                      "sd_metrics_ports": "9901",
                      "sd_task_definition_arn_pattern": ".*:task-definition/.*-ColorGateway:[0-9]+",
                      "sd_metrics_path": "/stats/prometheus"
                    }
                  ]
                }
```

这些默认目标中的每个目标都会被抓取，并使用嵌入式指标格式在日志事件中将指标发送到 CloudWatch。有关更多信息，请参阅 [在日志中嵌入指标](CloudWatch_Embedded_Metric_Format.md)。

来自 Amazon ECS 集群的日志事件存储在 **/aws/ecs/containerinsights/*cluster\$1name*/prometheus** 日志组中。

每个抓取作业都包含在此日志组中的不同日志流中。

要添加新的抓取目标，请在 YAML 文件 `ecs_service_discovery` 部分下的 `task_definition_list` 部分中添加一个新条目，然后重新启动代理。有关此过程的示例，请参阅 [添加新 Prometheus 抓取目标的教程：Prometheus API 服务器指标](ContainerInsights-Prometheus-Setup-configure.md#ContainerInsights-Prometheus-Setup-new-exporters)。

## Prometheus 的 CloudWatch 代理配置
<a name="ContainerInsights-Prometheus-Setup-cw-agent-config"></a>

CloudWatch 代理配置文件在 `metrics_collected` 下面有一个 `prometheus` 部分用于 Prometheus 抓取配置。它包含以下配置选项：
+ **cluster\$1name** – 指定要在日志事件中添加为标签的集群名称。该字段是可选的。如果省略此项，代理可以检测 Amazon ECS 集群名称。
+ **log\$1group\$1name** – 指定已抓取 Prometheus 指标的日志组名称。该字段是可选的。如果省略此项，CloudWatch 会将 **/aws/ecs/containerinsights/*cluster\$1name*/prometheus** 用于来自 Amazon ECS 集群的日志。
+ **prometheus\$1config\$1path** – 指定 Prometheus 抓取配置文件路径。如果此字段的值以 `env:` 开头，Prometheus 抓取配置文件内容将从容器的环境变量中检索。请勿更改此字段。
+ **ecs\$1service\$1discovery** – 是指定 Amazon ECS Prometheus 目标自动发现功能配置的部分。支持两种模式来发现 Prometheus 目标：根据容器的 docker 标签的发现或根据 Amazon ECS 任务定义 ARN 正则表达式的发现。您可以同时使用这两种模式，CloudWatch 代理将根据 *\$1private\$1ip\$1:\$1port\$1/\$1metrics\$1path\$1* 对发现的目标进行重复去除。

  `ecs_service_discovery` 部分包含以下字段：
  + `sd_frequency` 是发现 Prometheus 导出器的频率。指定数字和单位后缀。例如，`1m` 表示每分钟一次或 `30s` 表示每 30 秒一次。有效的单位后缀为 `ns`、`us`、`ms`、`s`、`m` 和 `h`。

    该字段是可选的。默认值为 60 秒（1 分钟）。
  + `sd_target_cluster` 是用于自动发现的目标 Amazon ECS 集群名称。该字段是可选的。默认名称为安装 CloudWatch 代理的 Amazon ECS 集群的名称。
  + `sd_cluster_region` 是目标 Amazon ECS 集群的区域。该字段是可选的。默认区域为安装 CloudWatch 代理的 Amazon ECS 集群的区域。
  + `sd_result_file` 是 Prometheus 目标结果的 YAML 文件的路径。Prometheus 抓取配置将引用此文件。
  + `docker_label` 是可选部分，您可以使用它来指定基于 docker 标签的服务发现的配置。如果省略此部分，则不会使用基于 docker 标签的发现。此部分包含以下字段：
    + `sd_port_label` 是容器的 docker 标签名称，用于指定 Prometheus 指标的容器端口。默认值为 `ECS_PROMETHEUS_EXPORTER_PORT`。如果容器没有此 docker 标签，CloudWatch 代理将跳过它。
    + `sd_metrics_path_label` 是容器的 docker 标签名称，用于指定 Prometheus 指标路径。默认值为 `ECS_PROMETHEUS_METRICS_PATH`。如果容器没有此 docker 标签，则代理会采用默认路径 `/metrics`。
    + `sd_job_name_label` 是容器的 docker 标签名称，用于指定 Prometheus 抓取任务名称。默认值为 `job`。如果容器没有此 docker 标签，CloudWatch 代理会使用 Prometheus 抓取配置中的任务名称。
  + `task_definition_list` 是可选部分，可用于指定基于任务定义的服务发现的配置。如果省略此部分，则不会使用基于任务定义的发现。此部分包含以下字段：
    + `sd_task_definition_arn_pattern` 是用于指定要发现的 Amazon ECS 任务定义的模式。这是正则表达式。
    + `sd_metrics_ports` 列出 Prometheus 指标的 containerPort。用分号分隔 containerPorts。
    + `sd_container_name_pattern` 指定 Amazon ECS 任务容器名称。这是正则表达式。
    + `sd_metrics_path` 指定 Prometheus 指标路径。如果省略此项，代理会采用默认路径 `/metrics`
    + `sd_job_name` 指定 Prometheus 抓取任务名称。如果省略此字段，CloudWatch 代理会使用 Prometheus 抓取配置中的任务名称。
  + `service_name_list_for_tasks` 是可选部分，可用于指定基于服务名称的发现的配置。如果省略此部分，则不会使用基于服务名称的发现。此部分包含以下字段：
    + `sd_service_name_pattern` 是用于指定要在其中发现任务的 Amazon ECS 服务的模式。这是正则表达式。
    + `sd_metrics_ports` 列出 Prometheus 指标的 `containerPort`。用分号分隔多个 `containerPorts`。
    + `sd_container_name_pattern` 指定 Amazon ECS 任务容器名称。这是正则表达式。
    + `sd_metrics_path` 指定 Prometheus 指标路径。如果省略此项，代理会采用默认路径 `/metrics`。
    + `sd_job_name` 指定 Prometheus 抓取任务名称。如果省略此字段，CloudWatch 代理会使用 Prometheus 抓取配置中的任务名称。
+ **metric\$1declaration** – 是指定要生成的采用嵌入式指标格式的日志数组的部分。默认情况下，CloudWatch 代理从中进行导入的每个 Prometheus 源都有 `metric_declaration` 部分。这些部分各包括以下字段：
  + `label_matcher` 是一个正则表达式，用于检查 `source_labels` 中列出的标签的值。匹配的指标将启用，以包含在发送到 CloudWatch 的嵌入式指标格式中。

    如果您在 `source_labels` 中指定了多个标签，我们建议您不要在 `label_matcher` 的正则表达式中使用 `^` 或 `$` 字符。
  + `source_labels` 指定由 `label_matcher` 行检查的标签的值。
  + `label_separator` 指定要在 ` label_matcher` 行中使用的分隔符（如果指定了多个 `source_labels`）。默认值为 `;`。您可以在以下示例中看到 `label_matcher` 行中使用的此默认值。
  + `metric_selectors` 是一个正则表达式，用于指定要收集并发送到 CloudWatch 的指标。
  + `dimensions` 是要用作每个选定指标的 CloudWatch 维度的标签列表。

请参阅以下 `metric_declaration` 示例。

```
"metric_declaration": [
  {
     "source_labels":[ "Service", "Namespace"],
     "label_matcher":"(.*node-exporter.*|.*kube-dns.*);kube-system$",
     "dimensions":[
        ["Service", "Namespace"]
     ],
     "metric_selectors":[
        "^coredns_dns_request_type_count_total$"
     ]
  }
]
```

此示例配置嵌入式指标格式部分，以便在满足以下条件时作为日志事件发送：
+ `Service` 的值包含 `node-exporter` 或 `kube-dns`。
+ `Namespace` 的值为 `kube-system`。
+ Prometheus 指标 `coredns_dns_request_type_count_total` 同时包含 `Service` 和 `Namespace` 标签。

发送的日志事件包括以下突出显示的部分：

```
{
   "CloudWatchMetrics":[
      {
         "Metrics":[
            {
               "Name":"coredns_dns_request_type_count_total"
            }
         ],
         "Dimensions":[
            [
               "Namespace",
               "Service"
            ]
         ],
         "Namespace":"ContainerInsights/Prometheus"
      }
   ],
   "Namespace":"kube-system",
   "Service":"kube-dns",
   "coredns_dns_request_type_count_total":2562,
   "eks_amazonaws_com_component":"kube-dns",
   "instance":"192.168.61.254:9153",
   "job":"kubernetes-service-endpoints",
   ...
}
```

# Amazon ECS 集群上自动发现的详细指南
<a name="ContainerInsights-Prometheus-Setup-autodiscovery-ecs"></a>

Prometheus 提供了数十种动态服务发现机制，如 [<scrape\$1config>](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\$1sd\$1config>](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`

**注意**  
与正则表达式 `[a-zA-Z_][a-zA-Z0-9_]*` 不匹配的 Docker 标签将被筛选掉。这与 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，以 `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 任务以及 `:23` 的 `version`，以进行容器端口扫描。对于在 `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 配置中定义的任务名称。

# （可选）为 Prometheus 指标测试设置示例容器化 Amazon ECS 工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-ECS"></a>

要测试 CloudWatch Container Insights 中的 Prometheus 指标支持，您可设置以下一个或多个容器化工作负载。具有 Prometheus 支持的 CloudWatch 代理会自动从这些工作负载中的每一个收集指标。要查看默认情况下收集的指标，请参阅 [CloudWatch 代理收集的 Prometheus 指标](ContainerInsights-Prometheus-metrics.md)。

**Topics**
+ [

# Amazon ECS 集群的示例 App Mesh 工作负载
](ContainerInsights-Prometheus-Sample-Workloads-ECS-appmesh.md)
+ [

# Amazon ECS 集群的示例 Java/JMX 工作负载
](ContainerInsights-Prometheus-Sample-Workloads-ECS-javajmx.md)
+ [

# Amazon ECS 集群的示例 NGINX 工作负载
](ContainerInsights-Prometheus-Setup-nginx-ecs.md)
+ [

# Amazon ECS 集群的示例 NGINX Plus 工作负载
](ContainerInsights-Prometheus-Setup-nginx-plus-ecs.md)
+ [

# 添加新 Prometheus 抓取目标的教程：Amazon ECS 上的 Memcached
](ContainerInsights-Prometheus-Setup-memcached-ecs.md)
+ [

# 在 Amazon ECS Fargate 上抓取 Redis OSS Prometheus 指标的教程
](ContainerInsights-Prometheus-Setup-redis-ecs.md)

# Amazon ECS 集群的示例 App Mesh 工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-ECS-appmesh"></a>

要从 Amazon ECS 的示例 Prometheus 工作负载收集指标，您必须在集群中运行 Container Insights。有关安装 Container Insights 的信息，请参阅 [在 Amazon ECS 上设置 Container Insights](deploy-container-insights-ECS.md)。

首先，按照本[演练](https://github.com/aws/aws-app-mesh-examples/tree/main/examples/apps/colorapp#app-mesh-walkthrough-deploy-the-color-app-on-ecs)在 Amazon ECS 集群上部署示例颜色应用程序。完成后，您将在端口 9901 上公开 App Mesh Prometheus 指标。

接下来，按照以下步骤在安装颜色应用程序的同一 Amazon ECS 集群上，安装带有 Prometheus 监控功能的 CloudWatch 代理。本节中的步骤以桥式网络模式安装 CloudWatch 代理。

您在演练中设置的环境变量 `ENVIRONMENT_NAME`、`AWS_PROFILE` 和 `AWS_DEFAULT_REGION`也将在以下步骤中使用。

**安装带有 Prometheus 监控功能的 CloudWatch 代理以进行测试**

1. 通过输入以下命令，下载 CloudFormation 模板。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml
   ```

1. 通过输入以下命令，设置网络模式。

   ```
   export ECS_CLUSTER_NAME=${ENVIRONMENT_NAME}
   export ECS_NETWORK_MODE=bridge
   ```

1. 输入以下命令以创建 CloudFormation 堆栈。

   ```
   aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=${ECS_CLUSTER_NAME} \
                    ParameterKey=CreateIAMRoles,ParameterValue=True \
                    ParameterKey=ECSNetworkMode,ParameterValue=${ECS_NETWORK_MODE} \
                    ParameterKey=TaskRoleName,ParameterValue=CWAgent-Prometheus-TaskRole-${ECS_CLUSTER_NAME} \
                    ParameterKey=ExecutionRoleName,ParameterValue=CWAgent-Prometheus-ExecutionRole-${ECS_CLUSTER_NAME} \
       --capabilities CAPABILITY_NAMED_IAM \
       --region ${AWS_DEFAULT_REGION} \
       --profile ${AWS_PROFILE}
   ```

1. （可选）创建 CloudFormation 堆栈后，您会看到 `CREATE_COMPLETE` 消息。如果要在看到该消息之前检查状态，请输入以下命令。

   ```
   aws cloudformation describe-stacks \
   --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
   --query 'Stacks[0].StackStatus' \
   --region ${AWS_DEFAULT_REGION} \
   --profile ${AWS_PROFILE}
   ```

**故障排查**

演练中的步骤使用 jq 来分析 AWS CLI 的输出结果。有关安装 jq 代理的更多信息，请参阅 [ jq](https://stedolan.github.io/jq/)。使用以下命令将 AWS CLI 的默认输出格式设置为 JSON，以便 jq 可以对其进行正确分析。

```
$ aws configure
```

当响应变为 `Default output format` 时，输入 **json**。

## 使用 Prometheus 监控功能卸载 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Sample-Workloads-ECS-appmesh-uninstall"></a>

完成测试后，输入以下命令以通过 CloudFormation 删除堆栈来卸载 CloudWatch 代理。

```
aws cloudformation delete-stack \
--stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
--region ${AWS_DEFAULT_REGION} \
--profile ${AWS_PROFILE}
```

# Amazon ECS 集群的示例 Java/JMX 工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-ECS-javajmx"></a>

JMX Exporter 是 Prometheus 的官方导出程序，可以将 JMX MBeans 作为 Prometheus 指标进行抓取和公开。有关详细信息，请参阅 [prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter)。

支持 Prometheus 的 CloudWatch 代理根据 Amazon ECS 集群中的服务发现配置抓取 Java/JMX Prometheus 指标。您可以将 JMX Exporter 配置为在不同端口或 metrics\$1path 上公开指标。如果您更改了端口或路径，请更新 CloudWatch 代理配置中的默认 `ecs_service_discovery` 部分。

要从 Amazon ECS 的示例 Prometheus 工作负载收集指标，您必须在集群中运行 Container Insights。有关安装 Container Insights 的信息，请参阅 [在 Amazon ECS 上设置 Container Insights](deploy-container-insights-ECS.md)。

**为 Amazon ECS 集群安装 Java/JMX 示例工作负载**

1. 按照这些部分中的步骤创建 Docker 镜像。
   + [示例：具有 Prometheus 指标的 Java Jar 应用程序 Docker 镜像](ContainerInsights-Prometheus-Sample-Workloads-javajmx.md#ContainerInsights-Prometheus-Sample-Workloads-javajmx-jar)
   + [示例：具有 Prometheus 指标的 Apache Tomcat Docker 镜像](ContainerInsights-Prometheus-Sample-Workloads-javajmx.md#ContainerInsights-Prometheus-Sample-Workloads-javajmx-tomcat)

1. 在 Amazon ECS 任务定义文件中指定以下两个 docker 标签。然后，您可以将任务定义作为集群中的 Amazon ECS 服务或 Amazon ECS 任务运行。
   + 将 `ECS_PROMETHEUS_EXPORTER_PORT` 设置为指向公开 Prometheus 指标的 containerPort。
   + 将 `Java_EMF_Metrics` 设置为 `true`。CloudWatch 代理使用此标志在日志事件中生成嵌入的指标格式。

   以下是示例：

   ```
   {
     "family": "workload-java-ec2-bridge",
     "taskRoleArn": "{{task-role-arn}}",
     "executionRoleArn": "{{execution-role-arn}}",
     "networkMode": "bridge",
     "containerDefinitions": [
       {
         "name": "tomcat-prometheus-workload-java-ec2-bridge-dynamic-port",
         "image": "your_docker_image_tag_for_tomcat_with_prometheus_metrics",
         "portMappings": [
           {
             "hostPort": 0,
             "protocol": "tcp",
             "containerPort": 9404
           }
         ],
         "dockerLabels": {
           "ECS_PROMETHEUS_EXPORTER_PORT": "9404",
           "Java_EMF_Metrics": "true"
         }
       }
     ],
     "requiresCompatibilities": [
       "EC2"  ],
     "cpu": "256",
     "memory": "512"
     }
   ```

CloudFormation 模板中 CloudWatch 代理的默认设置同时启用基于 docker 标签的服务发现和基于任务定义 ARN 的服务发现。要查看这些默认设置，请参阅 [CloudWatch 代理 YAML 配置文件](https://github.com/aws-samples/amazon-cloudwatch-container-insights/blob/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml#L65)的第 65 行。带有 `ECS_PROMETHEUS_EXPORTER_PORT` 标签的容器将根据 Prometheus 抓取的指定容器端口自动发现。

CloudWatch 代理的默认设置在同一文件的第 112 行也有 Java/JMX `metric_declaration` 设置。目标容器的所有 docker 标签将作为附加标签添加到 Prometheus 指标中并发送到 CloudWatch Logs。对于带有 docker 标签 `Java_EMF_Metrics=“true”` 的 Java/JMX 容器，将生成嵌入式指标格式。

# Amazon ECS 集群的示例 NGINX 工作负载
<a name="ContainerInsights-Prometheus-Setup-nginx-ecs"></a>

NGINX Prometheus 导出器可以抓取和公开 NGINX 数据作为 Prometheus 指标。此示例将导出器与适用于 Amazon ECS 的 NGINX 反向代理服务结合使用。

有关 NGINX Prometheus 导出器的更多信息，请参阅 Github 上的 [nginx-prometheus-exporter](https://github.com/nginxinc/nginx-prometheus-exporter)。有关 NGINX 反向代理的更多信息，请参阅 Github 上的 [ecs-nginx-reverse-proxy](https://github.com/awslabs/ecs-nginx-reverse-proxy)。

支持 Prometheus 的 CloudWatch 代理根据 Amazon ECS 集群中的服务发现配置抓取 NGINX Prometheus 指标。您可以将 NGINX Prometheus Exporter 配置为在不同端口或路径上公开指标。如果您更改端口或路径，请更新 CloudWatch 代理配置文件中的 `ecs_service_discovery` 部分。

## 为 Amazon ECS 集群安装 NGINX 反向代理示例工作负载
<a name="ContainerInsights-Prometheus-nginx-ecs-setup"></a>

按照以下步骤安装 NGINX 反向代理示例工作负载。

### 创建 Docker 镜像
<a name="ContainerInsights-Prometheus-nginx-ecs-setup-docker"></a>

**为 NGINX 反向代理示例工作负载创建 Docker 镜像**

1. 从 NGINX 反向代理存储库下载以下文件夹：[https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/](https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/)。

1. 查找 `app` 目录并从该目录构建镜像：

   ```
   docker build -t web-server-app ./path-to-app-directory
   ```

1. 为 NGINX 构建自定义镜像。首先，创建一个包含以下两个文件的目录：
   + 示例 Dockerfile：

     ```
     FROM nginx
     COPY nginx.conf /etc/nginx/nginx.conf
     ```
   + 一个 `nginx.conf` 文件，修改自 [https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/](https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/)：

     ```
     events {
       worker_connections 768;
     }
     
     http {
       # Nginx will handle gzip compression of responses from the app server
       gzip on;
       gzip_proxied any;
       gzip_types text/plain application/json;
       gzip_min_length 1000;
     
       server{
         listen 8080;
         location /stub_status {
             stub_status   on;
         }
       }
     
       server {
         listen 80;
     
         # Nginx will reject anything not matching /api
         location /api {
           # Reject requests with unsupported HTTP method
           if ($request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|DELETE)$) {
             return 405;
           }
     
           # Only requests matching the whitelist expectations will
           # get sent to the application server
           proxy_pass http://app:3000;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection 'upgrade';
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_cache_bypass $http_upgrade;
         }
       }
     }
     ```
**注意**  
`stub_status` 必须在将 `nginx-prometheus-exporter` 配置为从中抓取指标的同一端口上启用。在我们的示例任务定义中，将 `nginx-prometheus-exporter` 配置为从端口 8080 抓取指标。

1. 从新目录中的文件构建镜像：

   ```
   docker build -t nginx-reverse-proxy ./path-to-your-directory
   ```

1. 将新镜像上传到镜像存储库以供日后使用。

### 创建任务定义以在 Amazon ECS 中运行 NGINX 和 web 服务器应用程序
<a name="ContainerInsights-Prometheus-nginx-ecs-setup-task"></a>

接下来，设置任务定义。

此任务定义启用 NGINX Prometheus 指标的收集和导出。NGINX 容器跟踪来自应用程序的输入，并将该数据公开到端口 8080，如 `nginx.conf` 中所设置。NGINX prometheus 导出器容器抓取这些指标，并将其发布到端口 9113，以在 CloudWatch 中使用。

**为 NGINX 示例 Amazon ECS 工作负载设置任务定义**

1. 使用以下内容创建任务定义 JSON 文件。将 *your-customized-nginx-iamge* 替换为您自定义的 NGINX 镜像的镜像 URI，并将 *your-web-server-app-image* 替换为您 web 服务器应用程序镜像的镜像 URI。

   ```
   {
     "containerDefinitions": [
       {
         "name": "nginx",
         "image": "your-customized-nginx-image",
         "memory": 256,
         "cpu": 256,
         "essential": true,
         "portMappings": [
           {
             "containerPort": 80,
             "protocol": "tcp"
           }
         ],
         "links": [
           "app"
         ]
       },
       {
         "name": "app",
         "image": "your-web-server-app-image",
         "memory": 256,
         "cpu": 256,
         "essential": true
       },
       {
         "name": "nginx-prometheus-exporter",
         "image": "docker.io/nginx/nginx-prometheus-exporter:0.8.0",
         "memory": 256,
         "cpu": 256,
         "essential": true,
         "command": [
           "-nginx.scrape-uri",
           "http://nginx:8080/stub_status"
       ],
       "links":[
         "nginx"
       ],
         "portMappings":[
           {
             "containerPort": 9113,
             "protocol": "tcp"
           }
         ]
       }
     ],
     "networkMode": "bridge",
     "placementConstraints": [],
     "family": "nginx-sample-stack"
   }
   ```

1. 使用以下命令注册任务定义。

   ```
   aws ecs register-task-definition --cli-input-json file://path-to-your-task-definition-json
   ```

1. 通过输入以下命令创建服务以运行任务：

   确保不要更改服务名称。我们将使用配置来运行 CloudWatch 代理服务，该配置使用启动它们的服务的名称模式来搜索任务。例如，要让 CloudWatch 代理查找此命令启动的任务，您可以将 `sd_service_name_pattern` 的值指定为 `^nginx-service$`。下一部分将提供更多详细信息。

   ```
   aws ecs create-service \
    --cluster your-cluster-name \
    --service-name nginx-service \
    --task-definition nginx-sample-stack:1 \
    --desired-count 1
   ```

### 配置 CloudWatch 代理以抓取 NGINX Prometheus 指标
<a name="ContainerInsights-Prometheus-nginx-ecs-setup-agent"></a>

最后一步是配置 CloudWatch 代理以抓取 NGINX 指标。在此示例中，CloudWatch 代理通过服务名称模式和端口 9113 发现任务，导出器在该端口公开 NGINX 的 prometheus 指标。发现任务且指标可用后，CloudWatch 代理开始将收集的指标发布到日志流 **nginx-prometheus-exporter**。

**配置 CloudWatch 代理以抓取 NGINX 指标**

1. 通过输入以下命令，下载必要 YAML 文件的最新版本。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml
   ```

1. 使用文本编辑器打开文件，然后在 `resource:CWAgentConfigSSMParameter` 部分的 `value` 密钥中查找完整的 CloudWatch 代理配置。然后，在 `ecs_service_discovery` 部分中，添加以下 `service_name_list_for_tasks` 部分。

   ```
   "service_name_list_for_tasks": [
     {
       "sd_job_name": "nginx-prometheus-exporter",
       "sd_metrics_path": "/metrics",
       "sd_metrics_ports": "9113",
       "sd_service_name_pattern": "^nginx-service$"
      }
   ],
   ```

1. 在同一文件中，在 `metric_declaration` 部分中添加以下部分以允许 NGINX 指标。请务必遵循现有的缩进模式。

   ```
   {
     "source_labels": ["job"],
     "label_matcher": ".*nginx.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily", "ServiceName"]],
     "metric_selectors": [
       "^nginx_.*$"
     ]
   },
   ```

1. 如果您尚未在此集群中部署 CloudWatch 代理，请跳至步骤 8。

   如果您已经使用 AWS CloudFormation 将 CloudWatch 代理部署在 Amazon ECS 集群中，您可以通过输入以下命令来创建更改集：

   ```
   ECS_CLUSTER_NAME=your_cluster_name
   AWS_REGION=your_aws_region
   ECS_NETWORK_MODE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-change-set --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION \
       --change-set-name nginx-scraping-support
   ```

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 查看新创建的变更集 **nginx-scraping-support**。您会看到一项应用于 **CWAgentConfigSSMParameter** 资源的更改。通过输入以下命令，运行变更集并重新启动 CloudWatch 代理任务：

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 0 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 等待大约 10 秒，然后输入以下命令。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 1 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 如果您是首次在集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理，请输入以下命令。

   ```
   ECS_CLUSTER_NAME=your_cluster_name
   AWS_REGION=your_aws_region
   ECS_NETWORK_MODE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION
   ```

## 查看您的 NGINX 指标和日志
<a name="ContainerInsights-Prometheus-Setup-nginx-view"></a>

您现在可以查看正在收集的 NGINX 指标。

**查看示例 NGINX 工作负载的指标**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在运行集群的区域中，选择左侧导航窗格中的 **Metrics（指标）**。查找 **ContainerInsights/Prometheus** 命名空间以查看指标。

1. 要查看 CloudWatch Logs 事件，请在导航窗格中选择 **Log groups（日志组）**。这些事件位于日志流 *nginx-prometheus-exporter* 中的日志组 **/aws/containerinsights/*your\$1cluster\$1name*/prometheus** 中。

# Amazon ECS 集群的示例 NGINX Plus 工作负载
<a name="ContainerInsights-Prometheus-Setup-nginx-plus-ecs"></a>

NGINX Plus 是 NGINX 的商业版本。您必须拥有许可证方可使用它。有关更多信息，请参阅 [NGINX Plus](https://www.nginx.com/products/nginx/)

NGINX Prometheus 导出器可以抓取和公开 NGINX 数据作为 Prometheus 指标。此示例将导出器与适用于 Amazon ECS 的 NGINX Plus 反向代理服务结合使用。

有关 NGINX Prometheus 导出器的更多信息，请参阅 Github 上的 [nginx-prometheus-exporter](https://github.com/nginxinc/nginx-prometheus-exporter)。有关 NGINX 反向代理的更多信息，请参阅 Github 上的 [ecs-nginx-reverse-proxy](https://github.com/awslabs/ecs-nginx-reverse-proxy)。

支持 Prometheus 的 CloudWatch 代理根据 Amazon ECS 集群中的服务发现配置抓取 NGINX Plus Prometheus 指标。您可以将 NGINX Prometheus Exporter 配置为在不同端口或路径上公开指标。如果您更改端口或路径，请更新 CloudWatch 代理配置文件中的 `ecs_service_discovery` 部分。

## 为 Amazon ECS 集群安装 NGINX Plus 反向代理示例工作负载
<a name="ContainerInsights-Prometheus-nginx-plus-ecs-setup"></a>

按照以下步骤安装 NGINX 反向代理示例工作负载。

### 创建 Docker 镜像
<a name="ContainerInsights-Prometheus-nginx-plus-ecs-setup-docker"></a>

**为 NGINX Plus 反向代理示例工作负载创建 Docker 镜像**

1. 从 NGINX 反向代理存储库下载以下文件夹：[https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/](https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/)。

1. 查找 `app` 目录并从该目录构建镜像：

   ```
   docker build -t web-server-app ./path-to-app-directory
   ```

1. 为 NGINX Plus 构建自定义镜像。在为 NGINX Plus 构建镜像之前，您需要为您的 NGINX Plus 许可获取名为 `nginx-repo.key` 的密钥和 SSL 证书 `nginx-repo.crt`。创建目录并将您的 `nginx-repo.key` 和 `nginx-repo.crt` 文件存储在其中。

   在刚刚创建的目录中，创建以下两个文件：
   + 使用以下内容创建示例 Dockerfile。此 docker 文件取自 [https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/\$1docker\$1plus\$1image](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/#docker_plus_image) 上提供的示例文件。我们所做的重要更改是我们加载了一个名为 `nginx.conf` 的单独文件，该文件将在下一步中创建。

     ```
     FROM debian:buster-slim
     
     LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>“
     
     # Define NGINX versions for NGINX Plus and NGINX Plus modules
     # Uncomment this block and the versioned nginxPackages block in the main RUN
     # instruction to install a specific release
     # ENV NGINX_VERSION 21
     # ENV NJS_VERSION 0.3.9
     # ENV PKG_RELEASE 1~buster
     
     # Download certificate and key from the customer portal (https://cs.nginx.com (https://cs.nginx.com/))
     # and copy to the build context
     COPY nginx-repo.crt /etc/ssl/nginx/
     COPY nginx-repo.key /etc/ssl/nginx/
     # COPY nginx.conf /etc/ssl/nginx/nginx.conf
     
     RUN set -x \
     # Create nginx user/group first, to be consistent throughout Docker variants
     && addgroup --system --gid 101 nginx \
     && adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx \
     && apt-get update \
     && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg1 \
     && \
     NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
     found=''; \
     for server in \
     ha.pool.sks-keyservers.net (http://ha.pool.sks-keyservers.net/) \
     hkp://keyserver.ubuntu.com:80 \
     hkp://p80.pool.sks-keyservers.net:80 \
     pgp.mit.edu (http://pgp.mit.edu/) \
     ; do \
     echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
     apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
     done; \
     test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
     apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
     # Install the latest release of NGINX Plus and/or NGINX Plus modules
     # Uncomment individual modules if necessary
     # Use versioned packages over defaults to specify a release
     && nginxPackages=" \
     nginx-plus \
     # nginx-plus=${NGINX_VERSION}-${PKG_RELEASE} \
     # nginx-plus-module-xslt \
     # nginx-plus-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \
     # nginx-plus-module-geoip \
     # nginx-plus-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \
     # nginx-plus-module-image-filter \
     # nginx-plus-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \
     # nginx-plus-module-perl \
     # nginx-plus-module-perl=${NGINX_VERSION}-${PKG_RELEASE} \
     # nginx-plus-module-njs \
     # nginx-plus-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \
     " \
     && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx \
     && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \
     && echo "Acquire::https::plus-pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \
     && echo "Acquire::https::plus-pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \
     && printf "deb https://plus-pkgs.nginx.com/debian buster nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \
     && apt-get update \
     && apt-get install --no-install-recommends --no-install-suggests -y \
     $nginxPackages \
     gettext-base \
     curl \
     && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list \
     && rm -rf /etc/apt/apt.conf.d/90nginx /etc/ssl/nginx
     
     # Forward request logs to Docker log collector
     RUN ln -sf /dev/stdout /var/log/nginx/access.log \
     && ln -sf /dev/stderr /var/log/nginx/error.log
     
     COPY nginx.conf /etc/nginx/nginx.conf
     
     EXPOSE 80
     
     STOPSIGNAL SIGTERM
     
     CMD ["nginx", "-g", "daemon off;"]
     ```
   + 一个修改自 [ https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/nginx](https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/nginx) 的 `nginx.conf` 文件。

     ```
     events {
       worker_connections 768;
     }
     
     http {
       # Nginx will handle gzip compression of responses from the app server
       gzip on;
       gzip_proxied any;
       gzip_types text/plain application/json;
       gzip_min_length 1000;
     
       upstream backend {
         zone name 10m;
         server app:3000    weight=2;
         server app2:3000    weight=1;
       }
     
       server{
         listen 8080;
         location /api {
           api write=on;
         }
       }
     
       match server_ok {
         status 100-599;
       }
     
       server {
         listen 80;
         status_zone zone;
         # Nginx will reject anything not matching /api
         location /api {
           # Reject requests with unsupported HTTP method
           if ($request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|DELETE)$) {
             return 405;
           }
     
           # Only requests matching the whitelist expectations will
           # get sent to the application server
           proxy_pass http://backend;
           health_check uri=/lorem-ipsum match=server_ok;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection 'upgrade';
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_cache_bypass $http_upgrade;
         }
       }
     }
     ```

1. 从新目录中的文件构建镜像：

   ```
   docker build -t nginx-plus-reverse-proxy ./path-to-your-directory
   ```

1. 将新镜像上传到镜像存储库以供日后使用。

### 创建任务定义以在 Amazon ECS 中运行 NGINX Plus 和 web 服务器应用程序
<a name="ContainerInsights-Prometheus-nginx-plus-ecs-setup-task"></a>

接下来，设置任务定义。

此任务定义启用 NGINX Plus Prometheus 指标的收集和导出。NGINX 容器跟踪来自应用程序的输入，并将该数据公开到端口 8080，如 `nginx.conf` 中所设置。NGINX prometheus 导出器容器抓取这些指标，并将其发布到端口 9113，以在 CloudWatch 中使用。

**为 NGINX 示例 Amazon ECS 工作负载设置任务定义**

1. 使用以下内容创建任务定义 JSON 文件。将 *your-customized-nginx-plus-image* 替换为自定义 NGINX Plus 镜像的镜像 URI，并将 *your-web-server-app-image* 替换为 Web 服务器应用程序镜像的镜像 URI。

   ```
   {
     "containerDefinitions": [
       {
         "name": "nginx",
         "image": "your-customized-nginx-plus-image",
         "memory": 256,
         "cpu": 256,
         "essential": true,
         "portMappings": [
           {
             "containerPort": 80,
             "protocol": "tcp"
           }
         ],
         "links": [
           "app",
           "app2"
         ]
       },
       {
         "name": "app",
         "image": "your-web-server-app-image",
         "memory": 256,
         "cpu": 128,
         "essential": true
       },
       {
         "name": "app2",
         "image": "your-web-server-app-image",
         "memory": 256,
         "cpu": 128,
         "essential": true
       },
       {
         "name": "nginx-prometheus-exporter",
         "image": "docker.io/nginx/nginx-prometheus-exporter:0.8.0",
         "memory": 256,
         "cpu": 256,
         "essential": true,
         "command": [
           "-nginx.plus",
           "-nginx.scrape-uri",
            "http://nginx:8080/api"
       ],
       "links":[
         "nginx"
       ],
         "portMappings":[
           {
             "containerPort": 9113,
             "protocol": "tcp"
           }
         ]
       }
     ],
     "networkMode": "bridge",
     "placementConstraints": [],
     "family": "nginx-plus-sample-stack"
   }
   ```

1. 注册任务定义：

   ```
   aws ecs register-task-definition --cli-input-json file://path-to-your-task-definition-json
   ```

1. 通过输入以下命令创建服务以运行任务：

   ```
   aws ecs create-service \
    --cluster your-cluster-name \
    --service-name nginx-plus-service \
    --task-definition nginx-plus-sample-stack:1 \
    --desired-count 1
   ```

   确保不要更改服务名称。我们将使用配置来运行 CloudWatch 代理服务，该配置使用启动它们的服务的名称模式来搜索任务。例如，要让 CloudWatch 代理查找此命令启动的任务，您可以将 `sd_service_name_pattern` 的值指定为 `^nginx-plus-service$`。下一部分将提供更多详细信息。

### 配置 CloudWatch 代理以抓取 NGINX Plus Prometheus 指标
<a name="ContainerInsights-Prometheus-nginx-plus-ecs-setup-agent"></a>

最后一步是配置 CloudWatch 代理以抓取 NGINX 指标。在此示例中，CloudWatch 代理通过服务名称模式和端口 9113 发现任务，导出器在该端口公开 NGINX 的 prometheus 指标。发现任务且指标可用后，CloudWatch 代理开始将收集的指标发布到日志流 **nginx-prometheus-exporter**。

**配置 CloudWatch 代理以抓取 NGINX 指标**

1. 通过输入以下命令，下载必要 YAML 文件的最新版本。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-bridge-host.yaml
   ```

1. 使用文本编辑器打开文件，然后在 `resource:CWAgentConfigSSMParameter` 部分的 `value` 密钥中查找完整的 CloudWatch 代理配置。然后，在 `ecs_service_discovery` 部分中，添加以下 `service_name_list_for_tasks` 部分。

   ```
   "service_name_list_for_tasks": [
     {
       "sd_job_name": "nginx-plus-prometheus-exporter",
       "sd_metrics_path": "/metrics",
       "sd_metrics_ports": "9113",
       "sd_service_name_pattern": "^nginx-plus.*"
      }
   ],
   ```

1. 在同一个文件中，在 `metric_declaration` 的部分中添加以下部分，以允许 NGINX Plus 指标。请务必遵循现有的缩进模式。

   ```
   {
     "source_labels": ["job"],
     "label_matcher": "^nginx-plus.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily", "ServiceName"]],
     "metric_selectors": [
       "^nginxplus_connections_accepted$",
       "^nginxplus_connections_active$",
       "^nginxplus_connections_dropped$",
       "^nginxplus_connections_idle$",
       "^nginxplus_http_requests_total$",
       "^nginxplus_ssl_handshakes$",
       "^nginxplus_ssl_handshakes_failed$",
       "^nginxplus_up$",
       "^nginxplus_upstream_server_health_checks_fails$"
     ]
   },
   {
     "source_labels": ["job"],
     "label_matcher": "^nginx-plus.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily", "ServiceName", "upstream"]],
     "metric_selectors": [
       "^nginxplus_upstream_server_response_time$"
     ]
   },
   {
     "source_labels": ["job"],
     "label_matcher": "^nginx-plus.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily", "ServiceName", "code"]],
     "metric_selectors": [
       "^nginxplus_upstream_server_responses$",
       "^nginxplus_server_zone_responses$"
     ]
   },
   ```

1. 如果您尚未在此集群中部署 CloudWatch 代理，请跳至步骤 8。

   如果您已经使用 AWS CloudFormation 将 CloudWatch 代理部署在 Amazon ECS 集群中，您可以通过输入以下命令来创建更改集：

   ```
   ECS_CLUSTER_NAME=your_cluster_name
   AWS_REGION=your_aws_region
   ECS_NETWORK_MODE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-change-set --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION \
       --change-set-name nginx-plus-scraping-support
   ```

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 查看新创建的变更集 **nginx-plus-scraping-support**。您会看到一项应用于 **CWAgentConfigSSMParameter** 资源的更改。通过输入以下命令，运行变更集并重新启动 CloudWatch 代理任务：

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 0 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 等待大约 10 秒，然后输入以下命令。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 1 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 如果您是首次在集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理，请输入以下命令。

   ```
   ECS_CLUSTER_NAME=your_cluster_name
   AWS_REGION=your_aws_region
   ECS_NETWORK_MODE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION
   ```

## 查看您的 NGINX Plus 指标和日志
<a name="ContainerInsights-Prometheus-Setup-nginx-plus-view"></a>

您现在可以查看正在收集的 NGINX Plus 指标。

**查看示例 NGINX 工作负载的指标**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在运行集群的区域中，选择左侧导航窗格中的 **Metrics（指标）**。查找 **ContainerInsights/Prometheus** 命名空间以查看指标。

1. 要查看 CloudWatch Logs 事件，请在导航窗格中选择 **Log groups（日志组）**。事件位于日志流 *nginx-plus-prometheus-exporter* 中的日志组 **/aws/containerinsights/*your\$1cluster\$1name*/prometheus** 中。

# 添加新 Prometheus 抓取目标的教程：Amazon ECS 上的 Memcached
<a name="ContainerInsights-Prometheus-Setup-memcached-ecs"></a>

本教程提供实践介绍，关于如何在 Amazon ECS 集群上使用 EC2 启动类型抓取示例 Memcached 应用程序的 Prometheus 指标。Memcached Prometheus 导出器目标将由 CloudWatch 代理通过基于 ECS 任务定义的服务发现自动发现。

Memcached 是一个通用型分布式内存缓存系统。它通常用于通过在 RAM 中缓存数据和对象来加速动态数据库驱动的网站，以减少必须读取的外部数据源（例如数据库或 API）的次数。有关更多信息，请参阅[什么是 Memcached？](https://www.memcached.org/)

[memchached\$1exporter](https://github.com/prometheus/memcached_exporter)（Apache 许可证 2.0）是 Prometheus 一款官方导出器。默认情况下，memcache\$1exporter 在 `/metrics.` 的端口 0.0.0.0:9150 上提供服务

本教程使用了以下两个 Docker Hub 存储库中的 Docker 镜像：
+ [ Memcached](https://hub.docker.com/_/memcached?tab=description)
+ [prom/memcached-exporter](https://hub.docker.com/r/prom/memcached-exporter/)

**先决条件**

要从 Amazon ECS 的示例 Prometheus 工作负载收集指标，您必须在集群中运行 Container Insights。有关安装 Container Insights 的信息，请参阅 [在 Amazon ECS 上设置 Container Insights](deploy-container-insights-ECS.md)。

**Topics**
+ [

## 设置 Amazon ECS EC2 集群环境变量
](#ContainerInsights-Prometheus-Setup-memcached-ecs-environment)
+ [

## 安装 Memcached 示例工作负载
](#ContainerInsights-Prometheus-Setup-memcached-ecs-install-workload)
+ [

## 配置 CloudWatch 代理以抓取 Memcached Prometheus 指标
](#ContainerInsights-Prometheus-Setup-memcached-ecs-agent)
+ [

## 查看您的 Memcached 指标
](#ContainerInsights-Prometheus-ECS-memcached-view)

## 设置 Amazon ECS EC2 集群环境变量
<a name="ContainerInsights-Prometheus-Setup-memcached-ecs-environment"></a>

**设置 Amazon ECS EC2 集群环境变量**

1. 请安装 Amazon ECS CLI（如果尚未安装）。有关更多信息，请参阅[安装 Amazon ECS CLI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html)。

1. 设置新的 Amazon ECS 集群名称和区域。例如：

   ```
   ECS_CLUSTER_NAME=ecs-ec2-memcached-tutorial
   AWS_DEFAULT_REGION=ca-central-1
   ```

1. （可选）如果您还没有要在其中安装示例 Memcached 工作负载和 CloudWatch 代理的、带有 EC2 启动类型的 Amazon ECS 集群，您可以通过输入以下命令来创建一个。

   ```
   ecs-cli up --capability-iam --size 1 \
   --instance-type t3.medium \
   --cluster $ECS_CLUSTER_NAME \
   --region $AWS_REGION
   ```

   此命令的预期结果如下所示：

   ```
   WARN[0000] You will not be able to SSH into your EC2 instances without a key pair. 
   INFO[0000] Using recommended Amazon Linux 2 AMI with ECS Agent 1.44.4 and Docker version 19.03.6-ce 
   INFO[0001] Created cluster                               cluster=ecs-ec2-memcached-tutorial region=ca-central-1
   INFO[0002] Waiting for your cluster resources to be created... 
   INFO[0002] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
   INFO[0063] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
   INFO[0124] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
   VPC created: vpc-xxxxxxxxxxxxxxxxx
   Security Group created: sg-xxxxxxxxxxxxxxxxx
   Subnet created: subnet-xxxxxxxxxxxxxxxxx
   Subnet created: subnet-xxxxxxxxxxxxxxxxx
   Cluster creation succeeded.
   ```

## 安装 Memcached 示例工作负载
<a name="ContainerInsights-Prometheus-Setup-memcached-ecs-install-workload"></a>

**安装公开 Prometheus 指标的示例 Memcached 工作负载**

1. 通过输入以下命令，下载 Memcached CloudFormation 模板。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/sample_traffic/memcached/memcached-traffic-sample.yaml
   ```

1. 通过输入以下命令，设置要为 Memcached 创建的 IAM 角色名称。

   ```
   MEMCACHED_ECS_TASK_ROLE_NAME=memcached-prometheus-demo-ecs-task-role-name
   MEMCACHED_ECS_EXECUTION_ROLE_NAME=memcached-prometheus-demo-ecs-execution-role-name
   ```

1. 通过输入以下命令，安装示例 Memcached 工作负载。此示例在 `host` 网络模式下安装工作负载。

   ```
   MEMCACHED_ECS_NETWORK_MODE=host
   
   aws cloudformation create-stack --stack-name Memcached-Prometheus-Demo-ECS-$ECS_CLUSTER_NAME-EC2-$MEMCACHED_ECS_NETWORK_MODE \
       --template-body file://memcached-traffic-sample.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=ECSNetworkMode,ParameterValue=$MEMCACHED_ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$MEMCACHED_ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$MEMCACHED_ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION
   ```

CloudFormation 堆栈创建四种资源：
+ 一个 ECS 任务角色
+ 一个 ECS 任务执行角色
+ 一个 Memcached 任务定义
+ 一项 Memcached 服务

在 Memcached 任务定义中，定义了两个容器：
+ 主容器运行一个简单的 Memcached 应用程序并打开端口 11211 以供访问。
+ 另一个容器运行 Redis OSS 导出器进程，以在端口 9150 上公开 Prometheus 指标。该容器将由 CloudWatch 代理发现和抓取。

## 配置 CloudWatch 代理以抓取 Memcached Prometheus 指标
<a name="ContainerInsights-Prometheus-Setup-memcached-ecs-agent"></a>

**配置 CloudWatch 代理以抓取 Memcached Prometheus 指标**

1. 通过输入以下命令，下载 `cwagent-ecs-prometheus-metric-for-awsvpc.yaml` 的最新版本。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-awsvpc.yaml
   ```

1. 使用文本编辑器打开该文件，并在 `resource:CWAgentConfigSSMParameter` 部分中的 `value` 密钥后面查找完整的 CloudWatch 代理配置。

   然后，在 `ecs_service_discovery` 部分中，将以下配置添加到 `task_definition_list` 部分中。

   ```
   {
       "sd_job_name": "ecs-memcached",
       "sd_metrics_ports": "9150",
       "sd_task_definition_arn_pattern": ".*:task-definition/memcached-prometheus-demo.*:[0-9]+"
   },
   ```

   对于 `metric_declaration` 部分，默认设置不允许任何 Memcached 指标。添加以下部分以允许 Memcached 指标。请务必遵循现有的缩进模式。

   ```
   {
     "source_labels": ["container_name"],
     "label_matcher": "memcached-exporter-.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily"]],
     "metric_selectors": [
       "^memcached_current_(bytes|items|connections)$",
       "^memcached_items_(reclaimed|evicted)_total$",
       "^memcached_(written|read)_bytes_total$",
       "^memcached_limit_bytes$",
       "^memcached_commands_total$"
     ]
   },
   {
     "source_labels": ["container_name"],
     "label_matcher": "memcached-exporter-.*",
     "dimensions": [["ClusterName", "TaskDefinitionFamily","status","command"], ["ClusterName", "TaskDefinitionFamily","command"]],
     "metric_selectors": [
       "^memcached_commands_total$"
     ]
   },
   ```

1. 如果 CloudFormation 已在 Amazon ECS 集群中部署 CloudWatch 代理，您可以通过输入以下命令来创建更改集。

   ```
   ECS_NETWORK_MODE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-change-set --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION \
       --change-set-name memcached-scraping-support
   ```

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 查看新创建的变更集 `memcached-scraping-support`。您会看到一项应用于 `CWAgentConfigSSMParameter` 资源的更改。通过输入以下命令执行变更集并重新启动 CloudWatch 代理任务。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 0 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 等待大约 10 秒，然后输入以下命令。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 1 \
   --service cwagent-prometheus-replica-service-EC2-$ECS_NETWORK_MODE \
   --region $AWS_REGION
   ```

1. 如果您是首次为集群安装带有 Prometheus 指标收集功能的 CloudWatch 代理，请输入以下命令：

   ```
   ECS_NETWORK_MODEE=bridge
   CREATE_IAM_ROLES=True
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
       --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_REGION
   ```

## 查看您的 Memcached 指标
<a name="ContainerInsights-Prometheus-ECS-memcached-view"></a>

本教程会将以下指标发送到 CloudWatch 中的 **ECS/ContainerInsights/Prometheus** 命名空间。您可以使用 CloudWatch 控制台查看该命名空间中的指标。


| 指标名称 | Dimensions | 
| --- | --- | 
|  `memcached_current_items` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_current_connections` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_limit_bytes` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_current_bytes` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_written_bytes_total` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_read_bytes_total` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_items_evicted_total` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_items_reclaimed_total` |  `ClusterName`, `TaskDefinitionFamily`  | 
|  `memcached_commands_total` |  `ClusterName`, `TaskDefinitionFamily` `ClusterName`、TaskDefinitionFinitionFamy、command `ClusterName`、TaskDefinitionFamily、status、command  | 

**注意**  
**命令**维度的值可以是 `delete`、`get`、`cas`、`set`、`decr`、`touch`、`incr` 或 `flush`。  
**状态**维度的值可以是 `hit`、`miss` 或 `badval`。

您还可以为 Memcached Prometheus 指标创建 CloudWatch 控制面板。

**为 Memcached Prometheus 指标创建控制面板**

1. 创建环境变量，替换以下值以匹配部署。

   ```
   DASHBOARD_NAME=your_memcached_cw_dashboard_name
   ECS_TASK_DEF_FAMILY=memcached-prometheus-demo-$ECS_CLUSTER_NAME-EC2-$MEMCACHED_ECS_NETWORK_MOD
   ```

1. 输入以下命令以创建控制面板。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/sample_cloudwatch_dashboards/memcached/cw_dashboard_memcached.json \
   | sed "s/{{YOUR_AWS_REGION}}/$AWS_REGION/g" \
   | sed "s/{{YOUR_CLUSTER_NAME}}/$ECS_CLUSTER_NAME/g" \
   | sed "s/{{YOUR_TASK_DEF_FAMILY}}/$ECS_TASK_DEF_FAMILY/g" \
   | xargs -0 aws cloudwatch put-dashboard --dashboard-name ${DASHBOARD_NAME} --region $AWS_REGION --dashboard-body
   ```

# 在 Amazon ECS Fargate 上抓取 Redis OSS Prometheus 指标的教程
<a name="ContainerInsights-Prometheus-Setup-redis-ecs"></a>

本教程提供实践介绍，关于如何在 Amazon ECS Fargate 集群中抓取示例 Redis OSS 应用程序的 Prometheus 指标。Redis OSS Prometheus 导出器目标将由 CloudWatch 代理自动发现，并根据容器的 docker 标签提供 Prometheus 指标支持。

Redis OSS（https://redis.io/）是一个开源（获得 BSD 许可）的内存数据结构存储，用作数据库、缓存和消息代理。有关更多信息，请参阅 [ redis](https://redis.io/)。

redis\$1exporter（获得 MIT 许可证）用于在指定端口（默认值：0.0.0.0:9121）上公开 Redis OSS prometheus 指标。有关更多信息，请参阅 [redis\$1exporter](https://github.com/oliver006/redis_exporter)。

本教程使用了以下两个 Docker Hub 存储库中的 Docker 镜像：
+ [redis](https://hub.docker.com/_/redis?tab=description)
+ [redis\$1exporter](https://hub.docker.com/r/oliver006/redis_exporter)

**先决条件**

要从 Amazon ECS 的示例 Prometheus 工作负载收集指标，您必须在集群中运行 Container Insights。有关安装 Container Insights 的信息，请参阅 [在 Amazon ECS 上设置 Container Insights](deploy-container-insights-ECS.md)。

**Topics**
+ [

## 设置 Amazon ECS Fargate 集群环境变量
](#ContainerInsights-Prometheus-Setup-redis-ecs-variable)
+ [

## 为 Amazon ECS Fargate 集群设置网络环境变量
](#ContainerInsights-Prometheus-Setup-redis-ecs-variable2)
+ [

## 安装 Redis OSS 示例工作负载
](#ContainerInsights-Prometheus-Setup-redis-ecs-install-workload)
+ [

## 配置 CloudWatch 代理以抓取 Redis OSS Prometheus 指标
](#ContainerInsights-Prometheus-Setup-redis-ecs-agent)
+ [

## 查看您的 Redis OSS 指标
](#ContainerInsights-Prometheus-Setup-redis-view)

## 设置 Amazon ECS Fargate 集群环境变量
<a name="ContainerInsights-Prometheus-Setup-redis-ecs-variable"></a>

**设置 Amazon ECS Fargate 集群环境变量**

1. 请安装 Amazon ECS CLI（如果尚未安装）。有关更多信息，请参阅[安装 Amazon ECS CLI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html)。

1. 设置新的 Amazon ECS 集群名称和区域。例如：

   ```
   ECS_CLUSTER_NAME=ecs-fargate-redis-tutorial
   AWS_DEFAULT_REGION=ca-central-1
   ```

1. （可选）如果您还没有要在其中安装示例 Redis OSS 工作负载和 CloudWatch 代理的 Amazon ECS Fargate 集群，可以通过输入以下命令来创建一个。

   ```
   ecs-cli up --capability-iam \
   --cluster $ECS_CLUSTER_NAME \
   --launch-type FARGATE \
   --region $AWS_DEFAULT_REGION
   ```

   此命令的预期结果如下所示：

   ```
   INFO[0000] Created cluster   cluster=ecs-fargate-redis-tutorial region=ca-central-1
   INFO[0001] Waiting for your cluster resources to be created...
   INFO[0001] Cloudformation stack status   stackStatus=CREATE_IN_PROGRESS
   VPC created: vpc-xxxxxxxxxxxxxxxxx
   Subnet created: subnet-xxxxxxxxxxxxxxxxx
   Subnet created: subnet-xxxxxxxxxxxxxxxxx
   Cluster creation succeeded.
   ```

## 为 Amazon ECS Fargate 集群设置网络环境变量
<a name="ContainerInsights-Prometheus-Setup-redis-ecs-variable2"></a>

**为 Amazon ECS Fargate 集群设置网络环境变量**

1. 设置 Amazon ECS 集群的 VPC 和子网 ID。如果您在上一步骤中创建了新集群，您将在最终命令的结果中看到这些值。否则，请使用要与 Redis 一起使用的现有集群的 ID。

   ```
   ECS_CLUSTER_VPC=vpc-xxxxxxxxxxxxxxxxx
   ECS_CLUSTER_SUBNET_1=subnet-xxxxxxxxxxxxxxxxx
   ECS_CLUSTER_SUBNET_2=subnet-xxxxxxxxxxxxxxxxx
   ```

1. 在本教程中，我们将在 Amazon ECS 集群的 VPC 的默认安全组中安装 Redis OSS 应用程序和 CloudWatch 代理。默认安全组允许同一安全组内的所有网络连接，因此 CloudWatch 代理可以抓取 Redis OSS 容器上公开的 Prometheus 指标。在实际生产环境中，您可能希望为 Redis OSS 应用程序和 CloudWatch 代理创建专用安全组并为其设置自定义权限。

   要获取默认安全组 ID，请输入以下命令。

   ```
   aws ec2 describe-security-groups \
   --filters Name=vpc-id,Values=$ECS_CLUSTER_VPC  \
   --region $AWS_DEFAULT_REGION
   ```

   然后通过输入以下命令设置 Fargate 集群默认安全组变量，将 *my-default-security-group* 替换为您在上一个命令中找到的值。

   ```
   ECS_CLUSTER_SECURITY_GROUP=my-default-security-group
   ```

## 安装 Redis OSS 示例工作负载
<a name="ContainerInsights-Prometheus-Setup-redis-ecs-install-workload"></a>

**安装公开 Prometheus 指标的示例 Redis OSS 工作负载**

1. 通过输入以下命令，下载 Redis OSS CloudFormation 模板。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/sample_traffic/redis/redis-traffic-sample.yaml
   ```

1. 通过输入以下命令，设置要为 Redis OSS 创建的 IAM 角色名称。

   ```
   REDIS_ECS_TASK_ROLE_NAME=redis-prometheus-demo-ecs-task-role-name
   REDIS_ECS_EXECUTION_ROLE_NAME=redis-prometheus-demo-ecs-execution-role-name
   ```

1. 通过输入以下命令安装 Redis OSS 示例工作负载。

   ```
   aws cloudformation create-stack --stack-name Redis-Prometheus-Demo-ECS-$ECS_CLUSTER_NAME-fargate-awsvpc \
       --template-body file://redis-traffic-sample.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=SecurityGroupID,ParameterValue=$ECS_CLUSTER_SECURITY_GROUP \
                    ParameterKey=SubnetID,ParameterValue=$ECS_CLUSTER_SUBNET_1 \
                    ParameterKey=TaskRoleName,ParameterValue=$REDIS_ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$REDIS_ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region $AWS_DEFAULT_REGION
   ```

CloudFormation 堆栈创建四种资源：
+ 一个 ECS 任务角色
+ 一个 ECS 任务执行角色
+ 一个 Redis OSS 任务定义
+ 一项 Redis OSS 服务

在 Redis OSS 任务定义中，定义了两个容器：
+ 主容器运行一个简单的 Redis OSS 应用程序并打开端口 6379 以供访问。
+ 另一个容器运行 Redis OSS 导出器进程，以在端口 9121 上公开 Prometheus 指标。该容器将由 CloudWatch 代理发现和抓取。定义了以下 docker 标签，以便 CloudWatch 代理可以根据它发现该容器。

  ```
  ECS_PROMETHEUS_EXPORTER_PORT: 9121
  ```

## 配置 CloudWatch 代理以抓取 Redis OSS Prometheus 指标
<a name="ContainerInsights-Prometheus-Setup-redis-ecs-agent"></a>

**配置 CloudWatch 代理以抓取 Redis OSS Prometheus 指标**

1. 通过输入以下命令，下载 `cwagent-ecs-prometheus-metric-for-awsvpc.yaml` 的最新版本。

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-awsvpc.yaml
   ```

1. 使用文本编辑器打开该文件，并在 `resource:CWAgentConfigSSMParameter` 部分中的 `value` 密钥后面查找完整的 CloudWatch 代理配置。

   然后，在此处显示的 `ecs_service_discovery` 部分中，使用基于 `ECS_PROMETHEUS_EXPORTER_PORT` 的默认设置启用基于 `docker_label` 的服务发现，这与我们在 Redis OSS ECS 任务定义中定义的 Docker 标签相匹配。因此，我们无需在此部分进行任何更改：

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

   对于 `metric_declaration` 部分，默认设置不允许任何 Redis OSS 指标。添加以下部分以允许 Redis OSS 指标。请务必遵循现有的缩进模式。

   ```
   {
     "source_labels": ["container_name"],
     "label_matcher": "^redis-exporter-.*$",
     "dimensions": [["ClusterName","TaskDefinitionFamily"]],
     "metric_selectors": [
       "^redis_net_(in|out)put_bytes_total$",
       "^redis_(expired|evicted)_keys_total$",
       "^redis_keyspace_(hits|misses)_total$",
       "^redis_memory_used_bytes$",
       "^redis_connected_clients$"
     ]
   },
   {
     "source_labels": ["container_name"],
     "label_matcher": "^redis-exporter-.*$",
     "dimensions": [["ClusterName","TaskDefinitionFamily","cmd"]],
     "metric_selectors": [
       "^redis_commands_total$"
     ]
   },
   {
     "source_labels": ["container_name"],
     "label_matcher": "^redis-exporter-.*$",
     "dimensions": [["ClusterName","TaskDefinitionFamily","db"]],
     "metric_selectors": [
       "^redis_db_keys$"
     ]
   },
   ```

1. 如果 CloudFormation 已在 Amazon ECS 集群中部署 CloudWatch 代理，您可以通过输入以下命令来创建更改集。

   ```
   ECS_LAUNCH_TYPE=FARGATE
   CREATE_IAM_ROLES=True
   ECS_CLUSTER_SUBNET=$ECS_CLUSTER_SUBNET_1
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-change-set --stack-name CWAgent-Prometheus-ECS-$ECS_CLUSTER_NAME-$ECS_LAUNCH_TYPE-awsvpc \
       --template-body file://cwagent-ecs-prometheus-metric-for-awsvpc.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSLaunchType,ParameterValue=$ECS_LAUNCH_TYPE \
                    ParameterKey=SecurityGroupID,ParameterValue=$ECS_CLUSTER_SECURITY_GROUP \
                    ParameterKey=SubnetID,ParameterValue=$ECS_CLUSTER_SUBNET \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region ${AWS_DEFAULT_REGION} \
       --change-set-name redis-scraping-support
   ```

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 查看新创建的变更集 `redis-scraping-support`。您会看到一项应用于 `CWAgentConfigSSMParameter` 资源的更改。通过输入以下命令执行变更集并重新启动 CloudWatch 代理任务。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 0 \
   --service cwagent-prometheus-replica-service-$ECS_LAUNCH_TYPE-awsvpc \
   --region ${AWS_DEFAULT_REGION}
   ```

1. 等待大约 10 秒，然后输入以下命令。

   ```
   aws ecs update-service --cluster $ECS_CLUSTER_NAME \
   --desired-count 1 \
   --service cwagent-prometheus-replica-service-$ECS_LAUNCH_TYPE-awsvpc \
   --region ${AWS_DEFAULT_REGION}
   ```

1. 如果您是首次为集群安装带有 Prometheus 指标收集功能的 CloudWatch 代理，请输入以下命令：

   ```
   ECS_LAUNCH_TYPE=FARGATE
   CREATE_IAM_ROLES=True
   ECS_CLUSTER_SUBNET=$ECS_CLUSTER_SUBNET_1
   ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
   ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
   
   aws cloudformation create-stack --stack-name CWAgent-Prometheus-ECS-$ECS_CLUSTER_NAME-$ECS_LAUNCH_TYPE-awsvpc \
       --template-body file://cwagent-ecs-prometheus-metric-for-awsvpc.yaml \
       --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                    ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                    ParameterKey=ECSLaunchType,ParameterValue=$ECS_LAUNCH_TYPE \
                    ParameterKey=SecurityGroupID,ParameterValue=$ECS_CLUSTER_SECURITY_GROUP \
                    ParameterKey=SubnetID,ParameterValue=$ECS_CLUSTER_SUBNET \
                    ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                    ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
       --capabilities CAPABILITY_NAMED_IAM \
       --region ${AWS_DEFAULT_REGION}
   ```

## 查看您的 Redis OSS 指标
<a name="ContainerInsights-Prometheus-Setup-redis-view"></a>

本教程会将以下指标发送到 CloudWatch 中的 **ECS/ContainerInsights/Prometheus** 命名空间。您可以使用 CloudWatch 控制台查看该命名空间中的指标。


| 指标名称 | Dimensions | 
| --- | --- | 
|  `redis_net_input_bytes_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_net_output_bytes_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_expired_keys_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_evicted_keys_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_keyspace_hits_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_keyspace_misses_total` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_memory_used_bytes` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_connected_clients` |  ClusterName、`TaskDefinitionFamily`  | 
|  `redis_commands_total` |  ` ClusterName`, `TaskDefinitionFamily`, `cmd`  | 
|  `redis_db_keys` |  `ClusterName`, `TaskDefinitionFamily`, `db`  | 

**注意**  
**cmd** 维度的值可以是 `append`、`client`、`command`、`config`、`dbsize`、`flushall`、`get`、`incr`、`info`、`latency` 或 `slowlog`。  
**db** 维度的值可以从 `db0` 到 `db15`。

您还可以为 Redis OSS Prometheus 指标创建 CloudWatch 控制面板。

**为 Redis OSS Prometheus 指标创建控制面板**

1. 创建环境变量，替换以下值以匹配部署。

   ```
   DASHBOARD_NAME=your_cw_dashboard_name
   ECS_TASK_DEF_FAMILY=redis-prometheus-demo-$ECS_CLUSTER_NAME-fargate-awsvpc
   ```

1. 输入以下命令以创建控制面板。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_cloudwatch_dashboards/redis/cw_dashboard_redis.json \
   | sed "s/{{YOUR_AWS_REGION}}/${REGION_NAME}/g" \
   | sed "s/{{YOUR_CLUSTER_NAME}}/${CLUSTER_NAME}/g" \
   | sed "s/{{YOUR_NAMESPACE}}/${NAMESPACE}/g" \
   ```