

# Amazon ECS 클러스터의 NGINX 워크로드 샘플
<a name="ContainerInsights-Prometheus-Setup-nginx-ecs"></a>

NGINX Prometheus Exporter는 NGINX 데이터를 Prometheus 지표로 스크레이프하고 노출할 수 있습니다. 이 예에서는 Amazon ECS의 NGINX 역방향 프록시 서비스와 함께 Exporter를 사용합니다.

NGINX Prometheus Exporter에 대한 자세한 내용은 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
     ```
   + [https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/](https://github.com/awslabs/ecs-nginx-reverse-proxy/tree/master/reverse-proxy/)에서 수정한 `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;
     
       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;
         }
       }
     }
     ```
**참고**  
`nginx-prometheus-exporter`가 지표를 스크레이프하도록 구성된 동일한 포트에서 `stub_status`를 사용하도록 설정해야 합니다. 태스크 정의 예에서 `nginx-prometheus-exporter`는 포트 8080에서 지표를 스크레이프하도록 구성됩니다.

1. 새 디렉터리의 파일에서 이미지를 구축합니다.

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

1. 나중에 사용할 수 있도록 새 이미지를 이미지 리포지토리에 업로드합니다.

### Amazon ECS에서 NGINX 및 웹 서버 앱을 실행하는 태스크 정의 생성
<a name="ContainerInsights-Prometheus-nginx-ecs-setup-task"></a>

다음으로, 태스크 정의를 설정합니다.

이 태스크 정의를 사용하면 NGINX Prometheus 지표를 수집하고 내보낼 수 있습니다. NGINX 컨테이너는 앱의 입력을 추적하고, `nginx.conf`에 설정된 대로 해당 데이터를 포트 8080에 노출합니다. NGINX Prometheus Exporter 컨테이너는 이러한 지표를 스크레이프하며 CloudWatch에서 사용할 수 있도록 포트 9113에 게시합니다.

**NGINX 샘플 Amazon ECS 워크로드의 태스크 정의를 설정하려면**

1. 다음 내용이 포함된 태스크 정의 JSON 파일을 생성합니다. *your-customized-nginx-iamge*를 사용자 지정 NGINX 이미지의 이미지 URI로 바꾸고 *your-web-server-app-image*를 웹 서버 앱 이미지의 이미지 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
   ```

### NGINX Prometheus 지표를 스크레이프하도록 CloudWatch 에이전트 구성
<a name="ContainerInsights-Prometheus-nginx-ecs-setup-agent"></a>

마지막 단계는 NGINX 지표를 스크레이프하도록 CloudWatch 에이전트를 구성하는 것입니다. 이 예에서 CloudWatch 에이전트는 서비스 이름 패턴과 Exporter가 NGINX에 대한 Prometheus 지표를 노출하는 포트 9113을 통해 태스크를 검색합니다. 태스크를 검색하고 지표를 사용할 수 있게 되면 CloudWatch 에이전트는 수집된 지표를 로그 스트림 **nginx-prometheus-exporter**에 게시하기 시작합니다.

**NGINX 지표를 스크레이프하도록 CloudWatch 에이전트를 구성하려면**

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을 사용하여 Amazon ECS 클러스터에 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-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)**]을 선택합니다. 이벤트는 로그 그룹 **/aws/containerinsights/*your\$1cluster\$1name*/prometheus**의 로그 스트림 *nginx-prometheus-exporter*에 있습니다.