

# 部署 CloudWatch 代理以收集 Amazon ECS 上的 EC2 实例级别指标
<a name="deploy-container-insights-ECS-instancelevel"></a>

要部署 CloudWatch 代理以从 EC2 实例上托管的 Amazon ECS 集群中收集实例级别指标，请使用具有默认配置的快速启动设置，或手动安装该代理以便对其进行自定义。

这两种方法都要求您已经部署了至少一个带有 EC2 启动类型的 Amazon ECS 集群，并且 CloudWatch 代理容器可以访问 Amazon EC2 实例元数据服务（IMDS）。有关 IMDS 的更多信息，请参阅[实例元数据和用户数据](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。

这些方法还假设您已安装 AWS CLI。此外，要在以下过程中运行这些命令，您必须登录到具有 **IAMFullAccess** 和 **AmazonECS\$1FullAccess** 策略的账户或角色。

**重要**  
在任务定义中定义 CloudWatch 代理容器时，请设置 `essential: false`。这样可防止在 CloudWatch 代理容器故障时，整个 Amazon ECS 服务随之停止。即使代理暂时不可用，其他关键应用程序容器也将会继续运行。

**Topics**
+ [使用 CloudFormation 进行快速设置](#deploy-container-insights-ECS-instancelevel-quickstart)
+ [手动和自定义设置](#deploy-container-insights-ECS-instancelevel-manual)

## 使用 CloudFormation 进行快速设置
<a name="deploy-container-insights-ECS-instancelevel-quickstart"></a>

要使用快速设置，请输入以下命令来使用 CloudFormation 安装代理。将 *cluster-name* 和 *cluster-region* 分别替换为您的 Amazon ECS 集群的名称和区域。

此命令将创建 IAM 角色，即 **CWAgentECSTaskRole** 和 **CWAgentECSExecutionRole**。如果您的账户中已有这些角色，请在输入命令时使用 `ParameterKey=CreateIAMRoles,ParameterValue=False` 而非 `ParameterKey=CreateIAMRoles,ParameterValue=True`。否则，此命令将失败。

```
ClusterName=cluster-name
Region=cluster-region
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/daemon-service/cwagent-ecs-instance-metric/cloudformation-quickstart/cwagent-ecs-instance-metric-cfn.json
aws cloudformation create-stack --stack-name CWAgentECS-${ClusterName}-${Region} \
    --template-body file://cwagent-ecs-instance-metric-cfn.json \
    --parameters ParameterKey=ClusterName,ParameterValue=${ClusterName} \
                 ParameterKey=CreateIAMRoles,ParameterValue=True \
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${Region}
```

**（备选方案）使用您自己的 IAM 角色**

如果您要使用自己的自定义 ECS 任务角色和 ECS 任务执行角色，而不是使用 **CWAgentECSTaskRole** 和 **CWAgentECSExecutionRole** 角色，请先确保要用作 ECS 任务角色的角色已附加 **CloudWatchAgentServerPolicy**。此外，请确保要用作 ECS 任务执行角色的角色同时附加了 **CloudWatchAgentServerPolicy** 和 **AmazonECSTaskExecutionRolePolicy** 策略。然后，输入以下命令。在该命令中，将 *task-role-arn* 替换为您的自定义 ECS 任务角色的 ARN，并将 *execution-role-arn* 替换为您的自定义 ECS 任务执行角色的 ARN。

```
ClusterName=cluster-name
Region=cluster-region
TaskRoleArn=task-role-arn
ExecutionRoleArn=execution-role-arn
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/daemon-service/cwagent-ecs-instance-metric/cloudformation-quickstart/cwagent-ecs-instance-metric-cfn.json
aws cloudformation create-stack --stack-name CWAgentECS-${ClusterName}-${Region} \
    --template-body file://cwagent-ecs-instance-metric-cfn.json \
    --parameters ParameterKey=ClusterName,ParameterValue=${ClusterName} \
                 ParameterKey=TaskRoleArn,ParameterValue=${TaskRoleArn} \
                 ParameterKey=ExecutionRoleArn,ParameterValue=${ExecutionRoleArn} \
    --capabilities CAPABILITY_NAMED_IAM \
    --region ${Region}
```

**对快速设置进行故障排除**

要查看 CloudFormation 堆栈的状态，请输入以下命令。

```
ClusterName=cluster-name
Region=cluster-region
aws cloudformation describe-stacks --stack-name CWAgentECS-$ClusterName-$Region --region $Region
```

如果您看到的 `StackStatus` 不是 `CREATE_COMPLETE` 或 `CREATE_IN_PROGRESS`，请查看堆栈事件以查找错误。输入如下命令。

```
ClusterName=cluster-name
Region=cluster-region
aws cloudformation describe-stack-events --stack-name CWAgentECS-$ClusterName-$Region --region $Region
```

要查看 `cwagent` 守护进程服务的状态，请输入以下命令。在输出中，您应看到 `deployment` 部分中的 `runningCount` 等于 `desiredCount`。如果二者不相等，请查看输出中的 `failures` 部分。

```
ClusterName=cluster-name
Region=cluster-region
aws ecs describe-services --services cwagent-daemon-service --cluster $ClusterName --region $Region
```

您还可以使用 CloudWatch Logs 控制台来查看代理日志。查找 **/ecs/ecs-cwagent-daemon-service** 日志组。

**删除 CloudWatch 代理的 CloudFormation 堆栈**

如果您需要删除 CloudFormation 堆栈，请输入以下命令。

```
ClusterName=cluster-name
Region=cluster-region
aws cloudformation delete-stack --stack-name CWAgentECS-${ClusterName}-${Region} --region ${Region}
```

## 手动和自定义设置
<a name="deploy-container-insights-ECS-instancelevel-manual"></a>

执行此部分中的步骤，手动部署 CloudWatch 代理以从 EC2 实例上托管的 Amazon ECS 集群收集实例级别指标。

### 必要的 IAM 角色和策略
<a name="deploy-container-insights-ECS-instancelevel-IAMRoles"></a>

需要两个 IAM 角色。如果这两个角色不存在，则必须创建它们。有关这些角色的更多信息，请参阅[任务的 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)和 [Amazon ECS 任务执行角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html)。
+ 一个 *ECS 任务角色*，可供 CloudWatch 代理用来发布指标。如果此角色已存在，则必须确保它附加了 `CloudWatchAgentServerPolicy` 策略。
+ 一个 *ECS 任务执行角色*，可供 Amazon ECS 代理用来启动 CloudWatch 代理。如果此角色已存在，则必须确保它附加了 `AmazonECSTaskExecutionRolePolicy` 和 `CloudWatchAgentServerPolicy` 策略。

如果您还没有这些角色，则可使用以下命令来创建它们并附加必要的策略。第一条命令将创建 ECS 任务角色。

```
aws iam create-role --role-name CWAgentECSTaskRole \
    --assume-role-policy-document "{\"Version\": \"2012-10-17\",		 	 	 \"Statement\": [{\"Sid\": \"\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ecs-tasks.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}]}"
```

在输入上一条命令后，将命令输出中的 `Arn` 的值记为“TaskRoleArn”。稍后，您在创建任务定义时将需要使用它。然后，输入以下命令来附加必要的策略。

```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
    --role-name CWAgentECSTaskRole
```

下一条命令将创建 ECS 任务执行角色。

```
aws iam create-role --role-name CWAgentECSExecutionRole \
    --assume-role-policy-document "{\"Version\": \"2012-10-17\",		 	 	 \"Statement\": [{\"Sid\": \"\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ecs-tasks.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}]}"
```

在输入上一条命令后，将命令输出中的 `Arn` 的值记为“ExecutionRoleArn”。稍后，您在创建任务定义时将需要使用它。然后，输入以下命令来附加必要的策略。

```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
    --role-name CWAgentECSExecutionRole
          
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy \
    --role-name CWAgentECSExecutionRole
```

### 创建任务定义并启动守护进程服务
<a name="deploy-container-insights-ECS-instancelevel-taskdefinition"></a>

创建一个任务定义并使用它将 CloudWatch 代理作为守护进程服务启动。要创建任务定义，请输入以下命令。在前面的行中，将占位符替换为部署的实际值。*logs-region* 为 CloudWatch Logs 所在的区域，*cluster-region* 为集群所在的区域。*task-role-arn* 为您使用的 ECS 任务角色的 Arn，*execution-role-arn* 为 ECS 任务执行角色的 Arn。

```
TaskRoleArn=task-role-arn
ExecutionRoleArn=execution-role-arn
AWSLogsRegion=logs-region
Region=cluster-region
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/daemon-service/cwagent-ecs-instance-metric/cwagent-ecs-instance-metric.json \
    | sed "s|{{task-role-arn}}|${TaskRoleArn}|;s|{{execution-role-arn}}|${ExecutionRoleArn}|;s|{{awslogs-region}}|${AWSLogsRegion}|" \
    | xargs -0 aws ecs register-task-definition --region ${Region} --cli-input-json
```

然后，运行以下命令来启动守护程序服务。将 *cluster-name* 和 *cluster-region* 分别替换为您的 Amazon ECS 集群的名称和区域。

**重要**  
在运行此命令之前，请移除所有容量提供程序策略。否则，命令将无法正常运行。

```
ClusterName=cluster-name
Region=cluster-region
aws ecs create-service \
    --cluster ${ClusterName} \
    --service-name cwagent-daemon-service \
    --task-definition ecs-cwagent-daemon-service \
    --scheduling-strategy DAEMON \
    --region ${Region}
```

如果您看到的错误消息为 `An error occurred (InvalidParameterException) when calling the CreateService operation: Creation of service was not idempotent`，则您已创建名为 `cwagent-daemon-service` 的守护程序服务。您必须先删除该服务，并使用以下命令作为示例。

```
ClusterName=cluster-name
Region=cluster-region
aws ecs delete-service \
    --cluster ${ClusterName} \
    --service cwagent-daemon-service \
    --region ${Region} \
    --force
```

### （可选）高级配置
<a name="deploy-container-insights-ECS-instancelevel-advanced"></a>

（可选）您可以使用 SSM 来指定 EC2 实例上托管的 Amazon ECS 集群中 CloudWatch 代理的其他配置选项。这些选项如下所示：
+ `metrics_collection_interval` – CloudWatch 代理收集指标的频率（以秒为单位）。默认值为 60。范围为 1 – 172000。
+ `endpoint_override` –（可选）指定要将日志发送到的其他端点。如果您从 VPC 的集群中发布并希望将日志数据传输到 VPC 终端节点，则可能需要执行该操作。

  `endpoint_override` 的值必须是表示 URL 的字符串。
+ `force_flush_interval` – 以秒为单位指定日志在发送到服务器之前保留在内存缓冲区中的最大时间量。无论此字段的设置如何，如果缓冲区中的日志大小达到 1 MB，日志会立即发送到服务器。默认值为 5 秒。
+ `region` – 默认情况下，代理将指标发布到 Amazon ECS 容器实例所在的同一区域。要覆盖此设置，您可以在此处指定其他区域。例如，`"region" : "us-east-1"`

以下是自定义配置的示例：

```
{
    "agent": {
        "region": "us-east-1"
    },
    "logs": {
        "metrics_collected": {
            "ecs": {
                "metrics_collection_interval": 30
            }
        },
        "force_flush_interval": 5
    }
}
```

**在 Amazon ECS 容器中自定义 CloudWatch 代理配置**

1. 确保将 **AmazonSSMReadOnlyAccess** 策略附加到 Amazon ECS 任务执行角色。可输入以下命令来执行此操作。此示例假定您的 Amazon ECS 任务执行角色是 CWAgentECSExecutionRole。如果您使用其他角色，请在以下命令中替换该角色名称。

   ```
   aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess \
           --role-name CWAgentECSExecutionRole
   ```

1. 创建与上一示例类似的自定义配置文件。将此文件命名为 `/tmp/ecs-cwagent-daemon-config.json`。

1. 运行以下命令以将此配置放入 Parameter Store 中。将 *cluster-region* 替换为 Amazon ECS 集群的区域。要运行此命令，您必须登录到具有 **AmazonSSMFullAccess** 策略的用户或角色。

   ```
   Region=cluster-region
   aws ssm put-parameter \
       --name "ecs-cwagent-daemon-service" \
       --type "String" \
       --value "`cat /tmp/ecs-cwagent-daemon-config.json`" \
       --region $Region
   ```

1. 将任务定义文件下载到本地文件，例如 `/tmp/cwagent-ecs-instance-metric.json`

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/ecs-task-definition-templates/deployment-mode/daemon-service/cwagent-ecs-instance-metric/cwagent-ecs-instance-metric.json -o /tmp/cwagent-ecs-instance-metric.json
   ```

1. 修改任务定义文件。删除以下部分：

   ```
   "environment": [
                   {
                       "name": "USE_DEFAULT_CONFIG",
                       "value": "True"
                   }
               ],
   ```

   将此部分替换为以下内容：

   ```
   "secrets": [
                   {
                       "name": "CW_CONFIG_CONTENT",
                       "valueFrom": "ecs-cwagent-daemon-service"
                   }
               ],
   ```

1. 通过执行以下步骤，将代理作为守护程序服务重新启动：

   1. 运行如下命令。

      ```
      TaskRoleArn=task-role-arn
      ExecutionRoleArn=execution-role-arn
      AWSLogsRegion=logs-region
      Region=cluster-region
      cat /tmp/cwagent-ecs-instance-metric.json \
          | sed "s|{{task-role-arn}}|${TaskRoleArn}|;s|{{execution-role-arn}}|${ExecutionRoleArn}|;s|{{awslogs-region}}|${AWSLogsRegion}|" \
          | xargs -0 aws ecs register-task-definition --region ${Region} --cli-input-json
      ```

   1. 运行以下命令来启动守护程序服务。将 *cluster-name* 和 *cluster-region* 分别替换为您的 Amazon ECS 集群的名称和区域。

      ```
      ClusterName=cluster-name
      Region=cluster-region
      aws ecs create-service \
          --cluster ${ClusterName} \
          --service-name cwagent-daemon-service \
          --task-definition ecs-cwagent-daemon-service \
          --scheduling-strategy DAEMON \
          --region ${Region}
      ```

      如果您看到的错误消息为 `An error occurred (InvalidParameterException) when calling the CreateService operation: Creation of service was not idempotent`，则您已创建名为 `cwagent-daemon-service` 的守护程序服务。您必须先删除该服务，并使用以下命令作为示例。

      ```
      ClusterName=cluster-name
      Region=Region
      aws ecs delete-service \
          --cluster ${ClusterName} \
          --service cwagent-daemon-service \
          --region ${Region} \
          --force
      ```