

# 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** 中。