

# Amazon ECS 작업 정의 사용 사례
<a name="use-cases"></a>

다양한 AWS 서비스 및 기능에 대한 작업 정의를 작성하는 방법에 대해 자세히 알아봅니다.

워크로드에 따라 설정해야 하는 특정 작업 정의 파라미터가 있습니다. 또한 EC2의 경우 워크로드에 맞게 엔지니어링된 특정 인스턴스를 선택해야 합니다.

**Topics**
+ [GPU 워크로드에 대한 Amazon ECS 작업 정의](ecs-gpu.md)
+ [비디오 트랜스코딩 워크로드에 대한 Amazon ECS 태스크 정의](ecs-vt1.md)
+ [AWS Neuron 기계 학습 워크로드에 대한 Amazon ECS 작업 정의](ecs-inference.md)
+ [딥 러닝 인스턴스에 대한 Amazon ECS 작업 정의](ecs-dl1.md)
+ [64비트 ARM 워크로드에 대한 Amazon ECS 작업 정의](ecs-arm64.md)
+ [Amazon ECS 로그를 CloudWatch로 전송](using_awslogs.md)
+ [Amazon ECS 로그를 AWS 서비스 또는 AWS Partner로 전송](using_firelens.md)
+ [Amazon ECS에서 AWS 컨테이너가 아닌 이미지 사용](private-auth.md)
+ [컨테이너 재시작 정책이 있는 Amazon ECS 작업의 개별 컨테이너 재시작](container-restart-policy.md)
+ [Amazon ECS 컨테이너로 민감한 데이터 전달](specifying-sensitive-data.md)

# GPU 워크로드에 대한 Amazon ECS 작업 정의
<a name="ecs-gpu"></a>

GPU를 지원하는 컨테이너 인스턴스로 클러스터를 생성하는 경우 Amazon ECS는 GPU를 사용하는 워크로드를 지원합니다. p2, p3, p5, g3, g4 및 g5 인스턴스 유형을 사용하는 Amazon EC2 GPU 기반 컨테이너 인스턴스는 NVIDIA GPU에 대한 액세스를 제공합니다. 자세한 내용은 *Amazon EC2 인스턴스 유형 가이드*의 [Linux 가속 컴퓨팅 인스턴스](https://docs.aws.amazon.com/ec2/latest/instancetypes/ac.html)를 참조하세요.

Amazon ECS는 NVIDIA 커널 드라이버와 Docker GPU 실행 시간이 구성되어 있어 바로 사용할 수 있는 GPU 최적화 AMI를 제공합니다. 자세한 정보는 [Amazon ECS 최적화 Linux AMI](ecs-optimized_AMI.md)을 참조하세요.

컨테이너 수준에서 태스크 할당을 고려할 때 태스크 정의 내 GPU 개수를 지정할 수 있습니다. Amazon ECS는 GPU를 지원하는 사용 가능한 컨테이너 인스턴스로 예약하고 최적의 성능을 위해 물리적 GPU를 적절한 컨테이너에 고정합니다.

다음과 같은 Amazon EC2 GPU 기반 인스턴스 유형이 지원됩니다. 자세한 내용은 [Amazon EC2 P2 인스턴스](https://aws.amazon.com/ec2/instance-types/p2/), [Amazon EC2 P3 인스턴스](https://aws.amazon.com/ec2/instance-types/p3/), [Amazon EC2 P4d 인스턴스](https://aws.amazon.com/ec2/instance-types/p4/), [Amazon EC2 P5 인스턴스](https://aws.amazon.com/ec2/instance-types/p5/), [Amazon EC2 G3 인스턴스](https://aws.amazon.com/ec2/instance-types/g3/), [Amazon EC2 G4 인스턴스](https://aws.amazon.com/ec2/instance-types/g4/), [Amazon EC2 G5 인스턴스](https://aws.amazon.com/ec2/instance-types/g5/), [Amazon EC2 G6 인스턴스](https://aws.amazon.com/ec2/instance-types/g6/), [Amazon EC2 G6e 인스턴스](https://aws.amazon.com/ec2/instance-types/g6e/)를 참조하세요.


|  인스턴스 유형  |  GPU  |  GPU 메모리(GiB)  |  vCPU  |  메모리(GiB)  | 
| --- | --- | --- | --- | --- | 
|  p3.2xlarge  |  1  |  16  |  8  |  61  | 
|  p3.8xlarge  |  4  |  64  |  32  |  244  | 
|  p3.16xlarge  |  8  |  128  |  64  |  488  | 
|  p3dn.24xlarge  |  8  |  256  |  96  |  768  | 
|  p4d.24xlarge  | 8 | 320 | 96 | 1152 | 
| p5.48xlarge | 8 | 640 | 192 | 2048 | 
|  g3s.xlarge  |  1  |  8  |  4  |  30.5  | 
|  g3.4xlarge  |  1  |  8  |  16  |  122  | 
|  g3.8xlarge  |  2  |  16  |  32  |  244  | 
|  g3.16xlarge  |  4  |  32  |  64  |  488  | 
|  g4dn.xlarge  |  1  |  16  |  4  |  16  | 
|  g4dn.2xlarge  |  1  |  16  |  8  |  32  | 
|  g4dn.4xlarge  |  1  |  16  |  16  |  64  | 
|  g4dn.8xlarge  |  1  |  16  |  32  |  128  | 
|  g4dn.12xlarge  |  4  |  64  |  48  |  192  | 
|  g4dn.16xlarge  |  1  |  16  |  64  |  256  | 
|  g5.xlarge  |  1  |  24  |  4  |  16  | 
|  g5.2xlarge  |  1  |  24  |  8  |  32  | 
|  g5.4xlarge  |  1  |  24  |  16  |  64  | 
|  g5.8xlarge  |  1  |  24  |  32  |  128  | 
|  g5.16xlarge  |  1  |  24  |  64  |  256  | 
|  g5.12xlarge  |  4  |  96  |  48  |  192  | 
|  g5.24xlarge  |  4  |  96  |  96  |  384  | 
|  g5.48xlarge  |  8  |  192  |  192  |  768  | 
| g6.xlarge | 1 | 24 | 4 | 16 | 
| g6.2xlarge | 1 | 24 | 8 | 32 | 
| g6.4xlarge | 1 | 24 | 16 | 64 | 
| g6.8xlarge | 1 | 24 | 32 | 128 | 
| g6.16.xlarge | 1 | 24 | 64 | 256 | 
| g6.12xlarge | 4 | 96 | 48 | 192 | 
| g6.24xlarge | 4 | 96 | 96 | 384 | 
| g6.48xlarge | 8 | 192 | 192 | 768 | 
| g6.metal | 8 | 192 | 192 | 768 | 
| gr6.4xlarge | 1 | 24 | 16 | 128 | 
| g6e.xlarge | 1 | 48 | 4 | 32 | 
| g6e.2xlarge | 1 | 48 | 8 | 64 | 
| g6e.4xlarge | 1 | 48 | 16 | 128 | 
| g6e.8xlarge | 1 | 48 | 32 | 256 | 
| g6e16.xlarge | 1 | 48 | 64 | 512 | 
| g6e12.xlarge | 4 | 192 | 48 | 384 | 
| g6e24.xlarge | 4 | 192 | 96 | 768 | 
| g6e48.xlarge | 8 | 384 | 192 | 1536 | 
| gr6.8xlarge | 1 | 24 | 32 | 256 | 

AWS Systems Manager Parameter Store API를 쿼리하여 Amazon ECS 최적화 AMI의 Amazon Machine Image(AMI) ID를 검색할 수 있습니다. 이 파라미터를 사용하면 Amazon ECS 최적화 AMI ID를 수동으로 조회할 필요가 없습니다. Systems Manager 파라미터 스토어 API에 대한 자세한 내용은 [GetParameter](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html) 섹션을 참조하세요. Amazon ECS 최적화 AMI 메타데이터를 검색하려면 사용자에 `ssm:GetParameter` IAM 권한이 있어야 합니다.

```
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/gpu/recommended --region us-east-1
```

# Amazon ECS 관리형 인스턴스에서 GPU 사용
<a name="managed-instances-gpu"></a>

Amazon ECS 관리형 인스턴스는 다음 Amazon EC2 인스턴스 유형을 통한 기계 학습, 고성능 컴퓨팅 및 비디오 처리와 같은 워크로드에 대해 GPU 가속 컴퓨팅을 지원합니다. Amazon ECS 관리형 인스턴스에서 지원하는 인스턴스 유형에 대한 자세한 내용은 [Amazon ECS 관리형 인스턴스의 인스턴스 유형](managed-instances-instance-types.md) 섹션을 참조하세요.

다음은 Amazon ECS 관리형 인스턴스에서 지원하는 GPU 기반 인스턴스 유형의 하위 세트입니다.
+ `g4dn`: NVIDIA T4 GPUs로 구동되며 기계 학습 추론, 컴퓨터 비전 및 그래픽 집약적인 애플리케이션에 적합합니다.
+ `g5`: NVIDIA A10G GPUs로 구동되며 그래픽 집약적인 애플리케이션 및 기계 학습 워크로드에 더 높은 성능을 제공합니다.
+ `p3`: NVIDIA V100 GPUs로 구동되며 고성능 컴퓨팅 및 딥 러닝 훈련을 위해 설계되었습니다.
+ `p4d`: NVIDIA A100 GPUs로 구동되며 기계 학습 훈련 및 고성능 컴퓨팅을 위한 최고의 성능을 제공합니다.

Amazon ECS 관리형 인스턴스에서 GPU 지원 인스턴스 유형을 사용하는 경우 NVIDIA 드라이버와 CUDA 툴킷은 인스턴스에 사전 설치되어 GPU 가속 워크로드를 더 쉽게 실행할 수 있습니다.

## GPU 지원 인스턴스 선택
<a name="managed-instances-gpu-instance-selection"></a>

Amazon ECS 관리형 인스턴스 워크로드에 대해 GPU 지원 인스턴스 유형을 선택하려면 용량 공급자의 시작 템플릿에 있는 `instanceRequirements` 객체를 사용합니다. 다음 코드 조각에서는 GPU 지원 인스턴스를 선택하는 데 사용할 수 있는 속성을 보여줍니다.

```
{
  "instanceRequirements": {
    "acceleratorTypes": "gpu",
    "acceleratorCount": 1,
    "acceleratorManufacturers": ["nvidia"]
  }
}
```

다음 코드 조각에서는 시작 템플릿에서 GPU 지원 인스턴스 유형을 지정하는 데 사용할 수 있는 속성을 보여줍니다.

```
{
  "instanceRequirements": {
    "allowedInstanceTypes": ["g4dn.xlarge", "p4de.24xlarge"]
  }
}
```

## GPU 지원 컨테이너 이미지
<a name="managed-instances-gpu-container-images"></a>

컨테이너에서 GPU를 사용하려면 필요한 GPU 라이브러리 및 도구가 포함된 컨테이너 이미지를 사용해야 합니다. NVIDIA는 다음을 포함하여 GPU 워크로드의 기반으로 사용할 수 있는 몇 가지 사전 빌드된 컨테이너 이미지를 제공합니다.
+ `nvidia:cuda`: GPU 컴퓨팅용 CUDA 툴킷이 포함된 기본 이미지.
+ `tensorflow/tensorflow:latest-gpu`: TensorFlow(GPU지원 포함).
+ `pytorch/pytorch:latest-cuda`: PyTorch(GPU지원 포함).

GPU 사용과 관련된 Amazon ECS 관리형 인스턴스의 Amazon ECS에 대한 태스크 정의 예제는 [Amazon ECS 작업 정의에서 GPU 지정](ecs-gpu-specifying.md) 섹션을 참조하세요.

## 고려 사항
<a name="gpu-considerations"></a>

**참고**  
g2 인스턴스 패밀리 유형에 대한 지원은 더 이상 사용되지 않습니다.  
p2 인스턴스 유형 패밀리는 `20230912` 이전 버전의 Amazon ECS GPU 최적화 AMI에서만 지원됩니다. p2 인스턴스를 계속 사용해야 하는 경우 [P2 인스턴스가 필요한 경우 수행할 작업](#p2-instance)를 참조하세요.  
이 두 인스턴스 패밀리 유형에서 NVIDIA/CUDA 드라이버를 현재 위치 업데이트하면 잠재적인 GPU 워크로드 실패가 발생합니다.

Amazon ECS에서 GPU 작업을 시작하기 전에 다음 사항을 고려하는 것이 좋습니다.
+ 클러스터에 GPU와 비-GPU 컨테이너 인스턴스가 혼재되어 있을 수 있습니다.
+ 외부 인스턴스에서 GPU 워크로드를 실행할 수 있습니다. 클러스터에 외부 인스턴스를 등록할 때 `--enable-gpu` 플래그가 설치 스크립트에 포함되어 있는지 확인합니다. 자세한 정보는 [Amazon ECS 클러스터에 외부 인스턴스 등록](ecs-anywhere-registration.md)을 참조하세요.
+ 에이전트 구성 파일에서 `ECS_ENABLE_GPU_SUPPORT`를 `true`로 설정해야 합니다. 자세한 정보는 [Amazon ECS 컨테이너 에이전트 구성](ecs-agent-config.md)을 참조하세요.
+ 태스크를 실행하거나 서비스를 생성할 경우 작업 배치 제약 조건을 구성할 때 인스턴스 유형 속성을 사용하여 태스크가 시작될 컨테이너 인스턴스를 결정할 수 있습니다. 이렇게 하면 리소스를 더욱 효과적으로 사용할 수 있습니다. 자세한 정보는 [Amazon ECS가 컨테이너 인스턴스에 작업을 배치하는 방법](task-placement.md) 섹션을 참조하세요.

  다음 예제는 기본 클러스터의 `g4dn.xlarge` 컨테이너 인스턴스에서 태스크를 시작합니다.

  ```
  aws ecs run-task --cluster default --task-definition ecs-gpu-task-def \
       --placement-constraints type=memberOf,expression="attribute:ecs.instance-type ==  g4dn.xlarge" --region us-east-2
  ```
+ 컨테이너 정의에 지정된 GPU 리소스 요구 사항이 있는 각 컨테이너에 대해 Amazon ECS는 컨테이너 런타임을 NVIDIA 컨테이너 런타임으로 설정합니다.
+ NVIDIA 컨테이너 런타임이 제대로 작동하려면 컨테이너에 일부 환경 변수를 설정해야 합니다. 이러한 환경 변수 목록은 [Specialized Configurations with Docker](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/docker-specialized.html?highlight=environment%20variable)를 참조하세요. Amazon ECS는 Amazon ECS가 컨테이너에 할당하는 GPU 디바이스 ID의 목록이 될 `NVIDIA_VISIBLE_DEVICES` 환경 변수 값을 설정합니다. 다른 필수 환경 변수의 경우, Amazon ECS가 이러한 변수를 설정하지 않습니다. 따라서 컨테이너 이미지가 해당 변수를 설정하거나 컨테이너 정의에 설정되어 있어야 합니다.
+ p5 인스턴스 유형 패밀리는 `20230929` 이상 버전의 Amazon ECS GPU 최적화 AMI에서 지원됩니다.
+ g4 인스턴스 유형 패밀리는 `20230913` 이상 버전의 Amazon ECS GPU 최적화 AMI에서 지원됩니다. 자세한 내용은 [Amazon ECS 최적화 Linux AMI](ecs-optimized_AMI.md) 섹션을 참조하세요. Amazon ECS 콘솔의 클러스터 생성 워크플로에서는 지원되지 않습니다. 이러한 인스턴스 유형을 사용하려면 Amazon EC2 콘솔, AWS CLI 또는 API를 사용하고 클러스터에 인스턴스를 수동으로 등록해야 합니다.
+ p4d.24xlarge 인스턴스 유형은 CUDA 11 이상에서만 작동합니다.
+ Amazon ECS GPU 최적화 AMI는 IPv6가 활성화되어 있어서 `yum`을 사용할 때 문제가 발생합니다. 다음 명령으로 IPv4를 사용하도록 `yum`을 구성하면 문제가 해결됩니다.

  ```
  echo "ip_resolve=4" >> /etc/yum.conf
  ```
+  NVIDIA/CUDA 기본 이미지를 사용하지 않는 컨테이너 이미지를 구축할 때는 `NVIDIA_DRIVER_CAPABILITIES` 컨테이너 런타임 변수를 다음 값 중 하나로 설정해야 합니다.
  + `utility,compute`
  + `all`

  변수를 설정하는 방법에 대한 자세한 정보는 NVIDIA 웹사이트에서 [NVIDIA Container Runtime 제어](https://sarus.readthedocs.io/en/stable/user/custom-cuda-images.html#controlling-the-nvidia-container-runtime)를 참조하세요.
+ GPU는 Windows 컨테이너에서 지원되지 않습니다.

# Amazon ECS에 대한 GPU 컨테이너 인스턴스 시작
<a name="gpu-launch"></a>

Amazon EC2 기반 Amazon ECS에서 GPU 인스턴스를 사용하려면 시작 템플릿과 사용자 데이터 파일을 생성하고 인스턴스를 시작해야 합니다.

그런 다음, GPU용으로 구성된 작업 정의를 사용하는 작업을 실행할 수 있습니다.

## 시작 템플릿 사용
<a name="gpu-launch-template"></a>

시작 템플릿을 생성할 수 있습니다.
+ AMI에 대해 Amazon ECS 최적화 GPU AMI ID를 사용하는 시작 템플릿을 생성합니다. 시작 템플릿을 생성하는 방법에 대한 자세한 내용은 **Amazon EC2 사용 설명서의 [정의한 파라미터를 사용하여 새 시작 템플릿 생성](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-launch-template.html#create-launch-template-define-parameters)을 참조하세요.

  **Amazon 머신 이미지**에 대해 이전 단계의 AMI ID를 사용합니다. Systems Manager 파라미터를 사용하여 AMI ID를 지정하는 방법에 대한 자세한 내용은 Amazon EC2 사용 설명서의 [시작 템플릿에 Systems Manager 파라미터 지정](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-launch-template.html#use-an-ssm-parameter-instead-of-an-ami-id)을 참조하세요.**

  시작 템플릿의 **사용자 데이터**에 다음을 추가합니다. *cluster-name*을 해당 클러스터의 이름으로 바꿉니다.

  ```
  #!/bin/bash
  echo ECS_CLUSTER=cluster-name >> /etc/ecs/ecs.config;
  echo ECS_ENABLE_GPU_SUPPORT=true >> /etc/ecs/ecs.config
  ```

## AWS CLI 사용
<a name="gpu-launch-cli"></a>

AWS CLI를 사용하여 컨테이너 인스턴스를 시작할 수 있습니다.

1. `userdata.toml`이라는 파일을 생성합니다. 이 파일은 인스턴스 사용자 데이터로 사용됩니다. *cluster-name*을 해당 클러스터의 이름으로 바꿉니다.

   ```
   #!/bin/bash
   echo ECS_CLUSTER=cluster-name >> /etc/ecs/ecs.config;
   echo ECS_ENABLE_GPU_SUPPORT=true >> /etc/ecs/ecs.config
   ```

1. 다음 명령을 실행하여 GPU AMI ID를 가져옵니다. 다음 단계에서 이 정보를 사용합니다.

   ```
   aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/gpu/recommended --region us-east-1
   ```

1. 다음 명령을 실행하여 GPU 인스턴스를 시작합니다. 다음 파라미터를 대체해야 합니다.
   + *subnet*을 인스턴스가 시작될 프라이빗 또는 퍼블릭 서브넷의 ID로 바꿉니다.
   + *gpu\$1ami*를 이전 단계의 AMI ID로 바꿉니다.
   + *t3.large*를 사용하려는 인스턴스 유형으로 바꿉니다.
   + *region*을 리전 코드로 바꿉니다.

   ```
   aws ec2 run-instances --key-name ecs-gpu-example \
      --subnet-id subnet \
      --image-id gpu_ami \
      --instance-type t3.large \
      --region region \
      --tag-specifications 'ResourceType=instance,Tags=[{Key=GPU,Value=example}]' \
      --user-data file://userdata.toml \
      --iam-instance-profile Name=ecsInstanceRole
   ```

1. 다음 명령을 실행하여 컨테이너 인스턴스가 클러스터에 등록되었는지 확인합니다. 이 명령을 실행할 때 다음 파라미터를 바꿔야 합니다.
   + *cluster*를 클러스터 이름으로 바꿉니다.
   + *region*을 리전 코드로 바꿉니다.

   ```
   aws ecs list-container-instances --cluster cluster-name --region region
   ```

# Amazon ECS 작업 정의에서 GPU 지정
<a name="ecs-gpu-specifying"></a>

Docker GPU 실행 시간과 컨테이너 인스턴스의 GPU를 이용하려면 태스크 정의 시 컨테이너에 필요한 GPU 수를 지정해야 합니다. GPU를 지원하는 컨테이너가 배치되면 Amazon ECS 컨테이너 에이전트가 원하는 수의 물리적 GPU를 적절한 컨테이너에 고정합니다. 태스크의 모든 컨테이너에 예약된 GPU 수가 태스크가 실행되는 컨테이너 인스턴스에서 사용할 수 있는 GPU 수를 초과할 수 없습니다. 자세한 정보는 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md)을 참조하세요.

**중요**  
태스크 정의 때 GPU 조건을 지정하지 않으면 해당 태스크에서 기본 Docker 실행 시간이 사용됩니다.

다음은 태스크 정의 시 GPU 조건의 JSON 형식입니다.

```
{
  "containerDefinitions": [
     {
        ...
        "resourceRequirements" : [
            {
               "type" : "GPU", 
               "value" : "2"
            }
        ],
     },
...
}
```

다음 예제는 GPU 조건을 지정하는 Docker 컨테이너용 구문을 보여줍니다. 이 컨테이너는 GPU 2개를 사용하고, `nvidia-smi` 유틸리티를 실행한 후 종료합니다.

```
{
  "containerDefinitions": [
    {
      "memory": 80,
      "essential": true,
      "name": "gpu",
      "image": "nvidia/cuda:11.0.3-base",
      "resourceRequirements": [
         {
           "type":"GPU",
           "value": "2"
         }
      ],
      "command": [
        "sh",
        "-c",
        "nvidia-smi"
      ],
      "cpu": 100
    }
  ],
  "family": "example-ecs-gpu"
}
```

다음 태스크 정의 예제에서는 사용 가능한 GPU 수를 인쇄하는 TensorFlow 컨테이너를 보여줍니다. 태스크는 Amazon ECS 관리형 인스턴스에서 실행되고, 하나의 GPU가 필요하며, `g4dn.xlarge` 인스턴스를 사용합니다.

```
{
  "family": "tensorflow-gpu",
  "networkMode": "awsvpc",
  "executionRoleArn": "arn:aws:iam::account-id:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "tensorflow",
      "image": "tensorflow/tensorflow:latest-gpu",
      "essential": true,
      "command": [
        "python",
        "-c",
        "import tensorflow as tf; print('Num GPUs Available: ', len(tf.config.list_physical_devices('GPU')))"
      ],
      "resourceRequirements": [
        {
          "type": "GPU",
          "value": "1"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/tensorflow-gpu",
          "awslogs-region": "region",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ],
  "requiresCompatibilities": [
    "MANAGED_INSTANCES"
  ],
  "cpu": "4096",
  "memory": "8192",
}
```

## GPU 공유
<a name="share-gpu"></a>

GPU를 공유하려면 다음을 구성해야 합니다.

1. 공유되어야 하는 GPU를 Amazon ECS가 예약하지 않도록 태스크 정의에서 GPU 리소스 요구 사항을 제거합니다.

1. GPU를 공유하려면 다음과 같은 사용자 데이터를 인스턴스에 추가합니다. 이렇게 하면 nvidia가 컨테이너 인스턴스의 기본 Docker 컨테이너 런타임이 되므로 모든 Amazon ECS 컨테이너가 GPU를 사용할 수 있습니다. 자세한 내용은 *Amazon EC2 사용 설명서*의 [사용자 데이터 입력을 사용하여 EC2 인스턴스를 시작할 때 명령 실행](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html)을 참조하세요.

   ```
   const userData = ec2.UserData.forLinux();
    userData.addCommands(
    'sudo rm /etc/sysconfig/docker',
    'echo DAEMON_MAXFILES=1048576 | sudo tee -a /etc/sysconfig/docker',
    'echo OPTIONS="--default-ulimit nofile=32768:65536 --default-runtime nvidia" | sudo tee -a /etc/sysconfig/docker',
    'echo DAEMON_PIDFILE_TIMEOUT=10 | sudo tee -a /etc/sysconfig/docker',
    'sudo systemctl restart docker',
   );
   ```

1. 컨테이너에서 `NVIDIA_VISIBLE_DEVICES` 환경 변수를 설정합니다. 태스크 정의에서 환경 변수를 지정하면 됩니다. 유효한 값에 대한 자세한 내용은 NVIDIA 설명서 사이트의 [GPU Enumeration](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/docker-specialized.html#gpu-enumeration)을 참조하세요.

## P2 인스턴스가 필요한 경우 수행할 작업
<a name="p2-instance"></a>

P2 인스턴스를 사용해야 하는 경우 다음 옵션 중 하나를 사용하여 인스턴스를 계속 사용할 수 있습니다.

두 옵션 모두 인스턴스 사용자 데이터를 수정해야 합니다. 자세한 내용은 *Amazon EC2 사용 설명서*의 [사용자 데이터 입력을 사용하여 EC2 인스턴스를 시작할 때 명령 실행](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html)을 참조하세요.

**마지막으로 지원되는 GPU 최적화 AMI 사용**

GPU 최적화 AMI `20230906` 버전을 사용하고 인스턴스 사용자 데이터에 다음을 추가할 수 있습니다.

cluster-name을 해당 클러스터의 이름으로 바꿉니다.

```
#!/bin/bash
echo "exclude=*nvidia* *cuda*" >> /etc/yum.conf
echo "ECS_CLUSTER=cluster-name" >> /etc/ecs/ecs.config
```

**최신 GPU 최적화 AMI 사용 및 사용자 데이터 업데이트**

인스턴스 사용자 데이터에 다음을 추가할 수 있습니다. 이렇게 하면 Nvidia 535/Cuda12.2 드라이버가 제거되고 Nvidia 470/Cuda11.4 드라이버가 설치되고 버전이 수정됩니다.

```
#!/bin/bash
yum remove -y cuda-toolkit* nvidia-driver-latest-dkms*
tmpfile=$(mktemp)
cat >$tmpfile <<EOF
[amzn2-nvidia]
name=Amazon Linux 2 Nvidia repository
mirrorlist=\$awsproto://\$amazonlinux.\$awsregion.\$awsdomain/\$releasever/amzn2-nvidia/latest/\$basearch/mirror.list
priority=20
gpgcheck=1
gpgkey=https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/7fa2af80.pub
enabled=1
exclude=libglvnd-*
EOF

mv $tmpfile /etc/yum.repos.d/amzn2-nvidia-tmp.repo
yum install -y system-release-nvidia cuda-toolkit-11-4 nvidia-driver-latest-dkms-470.182.03
yum install -y libnvidia-container-1.4.0 libnvidia-container-tools-1.4.0 nvidia-container-runtime-hook-1.4.0 docker-runtime-nvidia-1

echo "exclude=*nvidia* *cuda*" >> /etc/yum.conf
nvidia-smi
```

**자체 P2 호환 GPU 최적화 AMI 생성**

P2 인스턴스와 호환되는 사용자 지정 Amazon ECS GPU 최적화 AMI를 생성한 다음 AMI를 사용하여 P2 인스턴스를 시작할 수 있습니다.

1. 다음 명령을 실행하여 `amazon-ecs-ami repo`를 복제합니다.

   ```
   git clone https://github.com/aws/amazon-ecs-ami
   ```

1. `release.auto.pkrvars.hcl` 또는 `overrides.auto.pkrvars.hcl`에서 필요한 Amazon ECS 에이전트 및 소스 Amazon Linux AMI 버전을 설정합니다.

1. 다음 명령을 실행하여 프라이빗 P2 호환 EC2 AMI를 빌드합니다.

   region을 인스턴스 리전이 리전으로 바꿉니다.

   ```
   REGION=region make al2keplergpu
   ```

1. AMI에서 다음 인스턴스 사용자 데이터를 사용하여 Amazon ECS 클러스터에 연결합니다.

   cluster-name을 해당 클러스터의 이름으로 바꿉니다.

   ```
   #!/bin/bash
   echo "ECS_CLUSTER=cluster-name" >> /etc/ecs/ecs.config
   ```

# 비디오 트랜스코딩 워크로드에 대한 Amazon ECS 태스크 정의
<a name="ecs-vt1"></a>

Amazon ECS에서 비디오 트랜스코딩 워크로드를 사용하려면 [Amazon EC2 VT1](https://aws.amazon.com/ec2/instance-types/vt1/) 인스턴스를 등록합니다. 이러한 인스턴스를 등록한 후, 라이브 및 사전 렌더링된 비디오 트랜스코딩 워크로드를 Amazon ECS에서 태스크로 실행할 수 있습니다. Amazon EC2 VT1 인스턴스는 Xilinx U30 미디어 트랜스코딩 카드를 사용하여 라이브 및 사전 렌더링된 비디오 트랜스코딩 워크로드 속도를 향상합니다.

**참고**  
Amazon ECS가 아닌 컨테이너에서 비디오 트랜스코딩 워크로드를 실행하는 방법에 대한 지침은 [Xilinx 설명서](https://xilinx.github.io/video-sdk/v1.5/container_setup.html#working-with-docker-vt1)를 참조하세요.

## 고려 사항
<a name="ecs-vt1-considerations"></a>

Amazon ECS에 VT1 배포를 시작하기 전에 다음에 주의하세요.
+ 클러스터에 VT1과 VT1이 아닌 인스턴스가 혼재되어 있을 수 있습니다.
+ 가속 AVC(H.264) 및 HEVC(H.265) 코덱으로 Xilinx U30 미디어 트랜스코딩 카드를 사용하는 Linux 애플리케이션이 필요합니다.
**중요**  
다른 코덱을 사용하는 애플리케이션은 VT1 인스턴스에서 성능이 향상되지 않을 수 있습니다.
+ U30 카드에서 트랜스코딩 태스크는 하나만 실행할 수 있습니다. 각 카드에는 연결된 두 개의 디바이스가 있습니다. 각 VT1 인스턴스 카드만큼 트랜스코딩 태스크를 실행할 수 있습니다.
+ 서비스를 생성하거나 독립적 태스크를 실행할 경우 작업 배치 제약 조건을 구성할 때 인스턴스 유형 속성을 사용할 수 있습니다. 이렇게 하면 지정한 컨테이너 인스턴스에서 태스크가 시작됩니다. 또한, 리소스를 효과적으로 사용하고 비디오 트랜스코딩 워크로드에 대한 태스크가 VT1 인스턴스에 있는지 확인할 수 있습니다. 자세한 정보는 [Amazon ECS가 컨테이너 인스턴스에 작업을 배치하는 방법](task-placement.md)을 참조하세요.

  다음의 예제에서는 `default` 클러스터에 있는 `vt1.3xlarge` 인스턴스에서 태스크를 실행합니다.

  ```
  aws ecs run-task \
       --cluster default \
       --task-definition vt1-3xlarge-xffmpeg-processor \
       --placement-constraints type=memberOf,expression="attribute:ecs.instance-type == vt1.3xlarge"
  ```
+ 호스트 컨테이너 인스턴스에서 특정 U30 카드를 사용하도록 컨테이너를 구성합니다. `linuxParameters` 파라미터 및 지정한 디바이스 세부 정보를 사용하여 이 작업을 수행할 수 있습니다. 자세한 정보는 [태스크 정의 요구 사항](#ecs-vt1-requirements)을 참조하세요.

## VT1 AMI 사용
<a name="ecs-vt1-ami"></a>

Amazon ECS 컨테이너 인스턴스용 Amazon EC2에서 AMI를 실행하는 두 가지 옵션이 있습니다. 첫 번째 옵션은 AWS Marketplace에서 Xilinx 공식 AMI를 사용하는 것입니다. 두 번째 옵션은 샘플 저장소에서 자체 AMI를 빌드하는 것입니다.
+ [Xilinx는 AWS Marketplace에서 AMI를 제공합니다](https://aws.amazon.com/marketplace/pp/prodview-phvk6d4mq3hh6).
+ Amazon ECS는 비디오 트랜스코딩 워크로드에 대한 AMI를 빌드하는 데 사용할 수 있는 샘플 리포지토리를 제공합니다. 이 AMI는 Xilinx U30 드라이버와 함께 제공됩니다. [GitHub](https://github.com/aws-samples/aws-vt-baseami-pipeline)에서 Packer 스크립트가 포함된 리포지토리를 찾을 수 있습니다. Packer에 대한 자세한 정보는 [Packer 설명서](https://developer.hashicorp.com/packer/docs)를 참조하세요.

## 태스크 정의 요구 사항
<a name="ecs-vt1-requirements"></a>

Amazon ECS에서 비디오 트랜스코딩 컨테이너를 실행하려면, 태스크 정의에 가속화된 H.264/AVC 및 H.265/HEVC 코덱을 사용하는 비디오 트랜스코딩 애플리케이션이 포함되어야 합니다. 컨테이너 이미지를 빌드하려면 [Xilinx GitHub](https://xilinx.github.io/video-sdk/v1.5/container_setup.html#creating-a-docker-image-for-vt1-usage)에서 다음 단계를 수행합니다.

태스크 정의는 인스턴스 유형에 고유해야 합니다. 인스턴스 유형은 3xlarge, 6xlarge 및 24xlarge입니다. 호스트 컨테이너 인스턴스에서 특정 Xilinx U30 디바이스를 사용하도록 컨테이너를 구성해야 합니다. `linuxParameters` 파라미터를 사용해 이 작업을 수행할 수 있습니다. 다음 표에는 각 인스턴스 유형에 해당하는 카드 및 디바이스 SoC가 자세히 나와 있습니다.


| 인스턴스 유형 | vCPU | RAM(GiB) | U30 액셀러레이터 카드 | 주소 지정 가능한 XCU30 SoC 디바이스 | 디바이스 경로 | 
| --- | --- | --- | --- | --- | --- | 
| vt1.3xlarge | 12 | 24 | 1 | 2 | /dev/dri/renderD128,/dev/dri/renderD129 | 
| vt1.6xlarge | 24 | 48 | 2 | 4 | /dev/dri/renderD128,/dev/dri/renderD129,/dev/dri/renderD130,/dev/dri/renderD131 | 
| vt1.24xlarge | 96 | 182 | 8 | 16 | /dev/dri/renderD128,/dev/dri/renderD129,/dev/dri/renderD130,/dev/dri/renderD131,/dev/dri/renderD132,/dev/dri/renderD133,/dev/dri/renderD134,/dev/dri/renderD135,/dev/dri/renderD136,/dev/dri/renderD137,/dev/dri/renderD138,/dev/dri/renderD139,/dev/dri/renderD140,/dev/dri/renderD141,/dev/dri/renderD142,/dev/dri/renderD143 | 

**중요**  
작업 정의에 EC2 인스턴스에 없는 디바이스가 나열되면 태스크가 실행되지 않습니다. 태스크가 실패하면 다음과 같이 오류 메시지가 표시됩니다. `stoppedReason`: `CannotStartContainerError: Error response from daemon: error gathering device information while adding custom device "/dev/dri/renderD130": no such file or directory`

# Amazon ECS 작업 정의에서 비디오 트랜스코딩 지정
<a name="task-def-video-transcode"></a>

다음 예에서는 Amazon EC2에서 Linux 컨테이너의 태스크 정의에 사용되는 구문이 제공됩니다. 이 태스크 정의는 [Xilinx 설명서](https://xilinx.github.io/video-sdk/v1.5/container_setup.html#creating-a-docker-image-for-vt1-usage)에서 제공하는 절차에 따라 빌드된 컨테이너 이미지용입니다. 이 예제를 사용하는 경우, 자체 이미지를 사용하여 `image`를 대체하고 비디오 파일을 `/home/ec2-user` 디렉터리의 인스턴스로 복사합니다.

------
#### [ vt1.3xlarge ]

1. 다음 콘텐츠가 포함된 `vt1-3xlarge-ffmpeg-linux.json`이라는 텍스트 파일을 생성합니다.

   ```
   {
       "family": "vt1-3xlarge-xffmpeg-processor",
       "requiresCompatibilities": ["EC2"],
       "placementConstraints": [
           {
               "type": "memberOf",
               "expression": "attribute:ecs.os-type == linux"
           },
           {
               "type": "memberOf",
               "expression": "attribute:ecs.instance-type == vt1.3xlarge"
           }
       ],
       "containerDefinitions": [
           {
               "entryPoint": [
                   "/bin/bash",
                   "-c"
               ],
               "command": ["/video/ecs_ffmpeg_wrapper.sh"],
               "linuxParameters": {
                   "devices": [
                       {
                           "containerPath": "/dev/dri/renderD128",
                           "hostPath": "/dev/dri/renderD128",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD129",
                           "hostPath": "/dev/dri/renderD129",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       }
                   ]
               },
               "mountPoints": [
                   {
                       "containerPath": "/video",
                       "sourceVolume": "video_file"
                   }
               ],
               "cpu": 0,
               "memory": 12000,
               "image": "0123456789012.dkr.ecr.us-west-2.amazonaws.com/aws/xilinx-xffmpeg",
               "essential": true,
               "name": "xilinix-xffmpeg"
           }
       ],
       "volumes": [
           {
               "name": "video_file",
               "host": {"sourcePath": "/home/ec2-user"}
           }
       ]
   }
   ```

1. 작업 정의를 등록합니다.

   ```
   aws ecs register-task-definition --family vt1-3xlarge-xffmpeg-processor --cli-input-json file://vt1-3xlarge-xffmpeg-linux.json --region us-east-1
   ```

------
#### [ vt1.6xlarge ]

1. 다음 콘텐츠가 포함된 `vt1-6xlarge-ffmpeg-linux.json`이라는 텍스트 파일을 생성합니다.

   ```
   {
       "family": "vt1-6xlarge-xffmpeg-processor",
       "requiresCompatibilities": ["EC2"],
       "placementConstraints": [
           {
               "type": "memberOf",
               "expression": "attribute:ecs.os-type == linux"
           },
           {
               "type": "memberOf",
               "expression": "attribute:ecs.instance-type == vt1.6xlarge"
           }
       ],
       "containerDefinitions": [
           {
               "entryPoint": [
                   "/bin/bash",
                   "-c"
               ],
               "command": ["/video/ecs_ffmpeg_wrapper.sh"],
               "linuxParameters": {
                   "devices": [
                       {
                           "containerPath": "/dev/dri/renderD128",
                           "hostPath": "/dev/dri/renderD128",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD129",
                           "hostPath": "/dev/dri/renderD129",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD130",
                           "hostPath": "/dev/dri/renderD130",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD131",
                           "hostPath": "/dev/dri/renderD131",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       }
                   ]
               },
               "mountPoints": [
                   {
                       "containerPath": "/video",
                       "sourceVolume": "video_file"
                   }
               ],
               "cpu": 0,
               "memory": 12000,
               "image": "0123456789012.dkr.ecr.us-west-2.amazonaws.com/aws/xilinx-xffmpeg",
               "essential": true,
               "name": "xilinix-xffmpeg"
           }
       ],
       "volumes": [
           {
               "name": "video_file",
               "host": {"sourcePath": "/home/ec2-user"}
           }
       ]
   }
   ```

1. 작업 정의를 등록합니다.

   ```
   aws ecs register-task-definition --family vt1-6xlarge-xffmpeg-processor --cli-input-json file://vt1-6xlarge-xffmpeg-linux.json --region us-east-1
   ```

------
#### [ vt1.24xlarge ]

1. 다음 콘텐츠가 포함된 `vt1-24xlarge-ffmpeg-linux.json`이라는 텍스트 파일을 생성합니다.

   ```
   {
       "family": "vt1-24xlarge-xffmpeg-processor",
       "requiresCompatibilities": ["EC2"],
       "placementConstraints": [
           {
               "type": "memberOf",
               "expression": "attribute:ecs.os-type == linux"
           },
           {
               "type": "memberOf",
               "expression": "attribute:ecs.instance-type == vt1.24xlarge"
           }
       ],
       "containerDefinitions": [
           {
               "entryPoint": [
                   "/bin/bash",
                   "-c"
               ],
               "command": ["/video/ecs_ffmpeg_wrapper.sh"],
               "linuxParameters": {
                   "devices": [
                       {
                           "containerPath": "/dev/dri/renderD128",
                           "hostPath": "/dev/dri/renderD128",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD129",
                           "hostPath": "/dev/dri/renderD129",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD130",
                           "hostPath": "/dev/dri/renderD130",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD131",
                           "hostPath": "/dev/dri/renderD131",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD132",
                           "hostPath": "/dev/dri/renderD132",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD133",
                           "hostPath": "/dev/dri/renderD133",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD134",
                           "hostPath": "/dev/dri/renderD134",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD135",
                           "hostPath": "/dev/dri/renderD135",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD136",
                           "hostPath": "/dev/dri/renderD136",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD137",
                           "hostPath": "/dev/dri/renderD137",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD138",
                           "hostPath": "/dev/dri/renderD138",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD139",
                           "hostPath": "/dev/dri/renderD139",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD140",
                           "hostPath": "/dev/dri/renderD140",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD141",
                           "hostPath": "/dev/dri/renderD141",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD142",
                           "hostPath": "/dev/dri/renderD142",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       },
                       {
                           "containerPath": "/dev/dri/renderD143",
                           "hostPath": "/dev/dri/renderD143",
                           "permissions": [
                               "read",
                               "write"
                           ]
                       }
                   ]
               },
               "mountPoints": [
                   {
                       "containerPath": "/video",
                       "sourceVolume": "video_file"
                   }
               ],
               "cpu": 0,
               "memory": 12000,
               "image": "0123456789012.dkr.ecr.us-west-2.amazonaws.com/aws/xilinx-xffmpeg",
               "essential": true,
               "name": "xilinix-xffmpeg"
           }
       ],
       "volumes": [
           {
               "name": "video_file",
               "host": {"sourcePath": "/home/ec2-user"}
           }
       ]
   }
   ```

1. 작업 정의를 등록합니다.

   ```
   aws ecs register-task-definition --family vt1-24xlarge-xffmpeg-processor --cli-input-json file://vt1-24xlarge-xffmpeg-linux.json --region us-east-1
   ```

------

# AWS Neuron 기계 학습 워크로드에 대한 Amazon ECS 작업 정의
<a name="ecs-inference"></a>

기계 학습 워크로드를 위해 [Amazon EC2 Trn1](https://aws.amazon.com/ec2/instance-types/trn1/), [Amazon EC2 Trn2](https://aws.amazon.com/ec2/instance-types/trn2/), [Amazon EC2 Inf1](https://aws.amazon.com/ec2/instance-types/inf1/), [Amazon EC2 Inf2](https://aws.amazon.com/ec2/instance-types/inf2/) 인스턴스를 클러스터에 등록할 수 있습니다.

Amazon EC2 Trn1, Trn2 인스턴스는 [AWS Trainium](https://aws.amazon.com/ai/machine-learning/trainium/) 칩으로 구동됩니다. 이러한 인스턴스는 클라우드에서의 기계 학습을 위한 고성능 및 저비용 교육을 제공합니다. Trn1 또는 Trn2 인스턴스에서 AWS Neuron과 함께 기계 학습 프레임워크를 사용하여 기계 학습 추론 모델을 교육시킬 수 있습니다. 그런 다음 Inf1 인스턴스 또는 Inf2 인스턴스에서 모델을 실행하여 AWS Inferentia 칩의 가속을 사용할 수 있습니다.

Amazon EC2 Inf1 인스턴스 및 Inf2 인스턴스는 [AWS Inferentia](https://aws.amazon.com/ai/machine-learning/inferentia/) 칩으로 구동됩니다. 이 칩은 클라우드에서 고성능의 가장 저렴한 추론을 제공합니다.

기계 학습 모델은 특화된 소프트웨어 개발 키트(SDK) [AWS Neuron](https://aws.amazon.com/ai/machine-learning/neuron/)을 사용하여 컨테이너에 배포됩니다. SDK는 AWS 기계 학습 칩의 추론 성능을 최적화하는 컴파일러, 런타임 및 프로파일링 도구로 구성됩니다. AWS Neuron은 TensorFlow, PyTorch, Apache MXNet과 같은 인기 있는 기계 학습 프레임워크를 지원합니다.

## 고려 사항
<a name="ecs-inference-considerations"></a>

Amazon ECS에 Neuron 배포를 시작하기 전에 다음에 주의하세요.
+ 클러스터에 Trn1, Trn2, Inf1, Inf2 및 그 외 인스턴스가 혼재되어 있을 수 있습니다.
+ AWS Neuron을 지원하는 기계 학습 프레임워크를 사용하는 컨테이너에 Linux 애플리케이션이 필요합니다.
**중요**  
다른 프레임워크를 사용하는 애플리케이션은 Trn1, Trn2, Inf1 및 Inf2 인스턴스에서 성능이 향상되지 않을 수 있습니다.
+ 각 [AWSTrainium](https://aws.amazon.com/ai/machine-learning/trainium/) 또는 [AWSInferentia](https://aws.amazon.com/ai/machine-learning/inferentia/) 칩에서 단 하나의 추론 또는 추론 교육 태스크만 실행할 수 있습니다. Inf1의 경우 각 칩에는 4개의 NeuronCore가 있습니다. Trn1, Trn2, Inf2의 경우 각 칩에는 2개의 NeuronCore가 있습니다. 각 Trn1, Trn2, Inf1, Inf2 인스턴스의 칩이 존재하는 만큼 많은 태스크를 실행할 수 있습니다.
+ 서비스를 생성하거나 독립적 태스크를 실행할 경우 작업 배치 제약 조건을 구성할 때 인스턴스 유형 속성을 사용할 수 있습니다. 이렇게 하면 지정한 컨테이너 인스턴스에서 태스크가 시작됩니다. 이렇게 하면 전체 리소스 사용률을 최적화하고 추론 워크로드에 대한 태스크가 Trn1, Trn2, Inf1, Inf2 인스턴스에 있는지 확인할 수 있습니다. 자세한 내용은 [Amazon ECS가 컨테이너 인스턴스에 작업을 배치하는 방법](task-placement.md) 섹션을 참조하세요.

  다음의 예제에서는 `default` 클러스터에 있는 `Inf1.xlarge` 인스턴스에서 태스크를 실행합니다.

  ```
  aws ecs run-task \
       --cluster default \
       --task-definition ecs-inference-task-def \
       --placement-constraints type=memberOf,expression="attribute:ecs.instance-type == Inf1.xlarge"
  ```
+ Neuron 리소스 요구 사항은 태스크 정의에서 정의할 수 없습니다. 그 대신에 호스트 컨테이너 인스턴스에서 특정 AWS Trainium 또는 AWS Inferentia 칩을 사용하도록 컨테이너를 구성합니다. `linuxParameters` 파라미터 및 지정한 디바이스 세부 정보를 사용하여 이 작업을 수행할 수 있습니다. 자세한 내용은 [태스크 정의 요구 사항](#ecs-inference-requirements) 섹션을 참조하세요.

## Amazon ECS 최적화 Amazon Linux 2023(Neuron) AMI 사용
<a name="ecs-inference-ami2023"></a>

Amazon ECS는 AWS Trainium 및 AWS Inferentia 워크로드용 Amazon Linux 2023을 기반으로 하는 Amazon ECS에 최적화된 AMI를 제공합니다. 이는 Docker용 AWS Neuron 드라이버 및 런타임과 함께 제공됩니다. 이 AMI를 사용하면 Amazon ECS에서 더욱 쉽게 기계 학습 인퍼런스 워크로드를 실행할 수 있습니다.

Amazon EC2 Trn1, Inf1, Inf2 인스턴스를 시작할 때 Amazon ECS 최적화 Amazon Linux 2023(Neuron) AMI를 사용하는 것을 권장합니다.

다음 명령으로 AWS CLI를 사용하여 현재 Amazon ECS에 최적화된 Amazon Linux 2023(Neuron) AMI를 검색할 수 있습니다.

```
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2023/neuron/recommended
```

## 태스크 정의 요구 사항
<a name="ecs-inference-requirements"></a>

Amazon ECS에 Neuron을 배포하려면 태스크 정의에 TensorFlow용 추론 모델을 제공하는 사전 구축된 컨테이너에 대한 컨테이너 정의를 포함해야 합니다. AWS 딥 러닝 컨테이너에 의해 제공됩니다. 이 컨테이너에는 AWS Neuron 런타임과 TensorFlow Serving 애플리케이션이 포함됩니다. 시작 시 이 컨테이너는 Amazon S3에서 모델을 가져오고, 저장된 모델로 Neuron TensorFlow Serving을 시작하고, 예측 요청을 기다립니다. 다음 예의 컨테이너 이미지에는 TensorFlow 1.15와 Ubuntu 18.04가 있습니다. Neuron에 최적화된 사전 구축된 Deep Learning Containers의 전체 목록은 GitHub에서 관리됩니다. 자세한 내용은 [Using AWS Neuron TensorFlow Serving](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia-tf-neuron-serving.html)을 참조하세요.

```
763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference-neuron:1.15.4-neuron-py37-ubuntu18.04
```

또는, 자체 Neuron 사이드카 컨테이너 이미지를 구축할 수 있습니다. 자세한 내용은 *AWS Deep Learning AMIs 개발자 안내서*의 [Tutorial: Neuron TensorFlow Serving](https://github.com/aws-neuron/aws-neuron-sdk/blob/master/frameworks/tensorflow/tensorflow-neuron/tutorials/tutorials-tensorflow-utilizing-neuron-capabilities.rst)을 참조하세요.

작업 정의는 단일 인스턴스 유형에만 고유해야 합니다. 호스트 컨테이너 인스턴스에서 특정 AWS Trainium 또는 AWS Inferentia 디바이스를 사용하도록 컨테이너를 구성해야 합니다. `linuxParameters` 파라미터를 사용해 이 작업을 수행할 수 있습니다. 예제 태스크 정의는 [Amazon ECS 작업 정의에서 AWS Neuron 기계 학습 지정](ecs-inference-task-def.md) 섹션을 참조하세요. 다음 표에는 각 인스턴스 유형에 해당하는 칩이 자세히 나와 있습니다.


| 인스턴스 유형 | vCPU | RAM(GiB) | AWS ML 액셀러레이터 칩 | 디바이스 경로 | 
| --- | --- | --- | --- | --- | 
| trn1.2xlarge | 8 | 32 | 1 | /dev/neuron0 | 
| trn1.32xlarge | 128 | 512 | 16 |  /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3, /dev/neuron4, /dev/neuron5, /dev/neuron6, /dev/neuron7, /dev/neuron8, /dev/neuron9, /dev/neuron10, /dev/neuron11, /dev/neuron12, /dev/neuron13, /dev/neuron14, /dev/neuron15  | 
| trn2.48xlarge | 192 | 1536 | 16 |  /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3, /dev/neuron4, /dev/neuron5, /dev/neuron6, /dev/neuron7, /dev/neuron8, /dev/neuron9, /dev/neuron10, /dev/neuron11, /dev/neuron12, /dev/neuron13, /dev/neuron14, /dev/neuron15  | 
| inf1.xlarge | 4 | 8 | 1 | /dev/neuron0 | 
| inf1.2xlarge | 8 | 16 | 1 | /dev/neuron0 | 
| inf1.6xlarge | 24 | 48 | 4 | /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3 | 
| inf1.24xlarge | 96 | 192 | 16 |  /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3, /dev/neuron4, /dev/neuron5, /dev/neuron6, /dev/neuron7, /dev/neuron8, /dev/neuron9, /dev/neuron10, /dev/neuron11, /dev/neuron12, /dev/neuron13, /dev/neuron14, /dev/neuron15  | 
| inf2.xlarge | 8 | 16 | 1 | /dev/neuron0 | 
| inf2.8xlarge | 32 | 64 | 1 | /dev/neuron0 | 
| inf2.24xlarge | 96 | 384 | 6 | /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3, /dev/neuron4, /dev/neuron5,  | 
| inf2.48xlarge | 192 | 768 | 12 | /dev/neuron0, /dev/neuron1, /dev/neuron2, /dev/neuron3, /dev/neuron4, /dev/neuron5, /dev/neuron6, /dev/neuron7, /dev/neuron8, /dev/neuron9, /dev/neuron10, /dev/neuron11 | 

# Amazon ECS 작업 정의에서 AWS Neuron 기계 학습 지정
<a name="ecs-inference-task-def"></a>

다음은 사용할 구문을 표시한 `inf1.xlarge`에 대한 Linux 태스크 정의의 예입니다.

```
{
    "family": "ecs-neuron",
    "requiresCompatibilities": ["EC2"],
    "placementConstraints": [
        {
            "type": "memberOf",
            "expression": "attribute:ecs.os-type == linux"
        },
        {
            "type": "memberOf",
            "expression": "attribute:ecs.instance-type == inf1.xlarge"
        }
    ],
    "executionRoleArn": "${YOUR_EXECUTION_ROLE}",
    "containerDefinitions": [
        {
            "entryPoint": [
                "/usr/local/bin/entrypoint.sh",
                "--port=8500",
                "--rest_api_port=9000",
                "--model_name=resnet50_neuron",
                "--model_base_path=s3://amzn-s3-demo-bucket/resnet50_neuron/"
            ],
            "portMappings": [
                {
                    "hostPort": 8500,
                    "protocol": "tcp",
                    "containerPort": 8500
                },
                {
                    "hostPort": 8501,
                    "protocol": "tcp",
                    "containerPort": 8501
                },
                {
                    "hostPort": 0,
                    "protocol": "tcp",
                    "containerPort": 80
                }
            ],
            "linuxParameters": {
                "devices": [
                    {
                        "containerPath": "/dev/neuron0",
                        "hostPath": "/dev/neuron0",
                        "permissions": [
                            "read",
                            "write"
                        ]
                    }
                ],
                "capabilities": {
                    "add": [
                        "IPC_LOCK"
                    ]
                }
            },
            "cpu": 0,
            "memoryReservation": 1000,
            "image": "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference-neuron:1.15.4-neuron-py37-ubuntu18.04",
            "essential": true,
            "name": "resnet50"
        }
    ]
}
```

# 딥 러닝 인스턴스에 대한 Amazon ECS 작업 정의
<a name="ecs-dl1"></a>

Amazon ECS에서 딥 러닝 워크로드를 사용하려면 [Amazon EC2 DL1](https://aws.amazon.com/ec2/instance-types/dl1/) 인스턴스를 클러스터에 등록합니다. Amazon EC2 DL1 인스턴스는 Habana Labs(Intel 회사)의 Gaudi 액셀러레이터로 구동됩니다. Habana SynapseAI SDK를 사용하여 Habana Gaudi 액셀러레이터에 연결합니다. SDK는 TensorFlow, PyTorch와 같은 인기 있는 기계 학습 프레임워크를 지원합니다.

## 고려 사항
<a name="ecs-dl1-considerations"></a>

Amazon ECS에 DL1 배포를 시작하기 전에 다음에 주의하세요.
+ 클러스터에 DL1과 DL1이 아닌 인스턴스가 혼재되어 있을 수 있습니다.
+ 서비스를 생성하거나 독립적 태스크를 실행할 경우 작업 배치 제약 조건을 구성할 때 인스턴스 유형 속성을 사용하여 태스크가 시작되는 지정 컨테이너 인스턴스를 확인할 수 있습니다. 또한, 리소스를 효과적으로 사용하고 딥 러닝 워크로드에 대한 태스크가 DL1 인스턴스에 있는지 확인할 수 있습니다. 자세한 정보는 [Amazon ECS가 컨테이너 인스턴스에 작업을 배치하는 방법](task-placement.md)을 참조하세요.

  다음의 예제에서는 `default` 클러스터에 있는 `dl1.24xlarge` 인스턴스에서 태스크를 실행합니다.

  ```
  aws ecs run-task \
       --cluster default \
       --task-definition ecs-dl1-task-def \
       --placement-constraints type=memberOf,expression="attribute:ecs.instance-type == dl1.24xlarge"
  ```

## DL1 AMI 사용
<a name="ecs-dl1-ami"></a>

Amazon ECS용 Amazon EC2 DL1 인스턴스에서 AMI를 실행하는 세 가지 옵션이 있습니다.
+ Habana에서 제공하는 AWS Marketplace AMI를 사용합니다([링크](https://aws.amazon.com/marketplace/pp/prodview-h24gzbgqu75zq)).
+ Amazon Web Services에서 제공하는 Habana 딥 러닝 AMI를 사용합니다. 이 AMI는 포함되어 있지 않으므로 Amazon ECS 컨테이너 에이전트를 별도로 설치해야 합니다.
+ Packer를 사용하여 [GitHub 리포지토리](https://github.com/aws-samples/aws-habana-baseami-pipeline)에서 제공하는 사용자 지정 AMI를 빌드합니다. 자세한 정보는 [Packer 설명서](https://developer.hashicorp.com/packer/docs)를 참조하세요.

# Amazon ECS 작업 정의에서 딥 러닝 지정
<a name="ecs-dl1-requirements"></a>

Amazon ECS에서 Habana Gaudi 가속 딥 러닝 컨테이너를 실행하려면, 태스크 정의는 AWS 딥 러닝 컨테이너에서 제공하는 Habana SynapseAI를 사용하여 TensorFlow 또는 PyTorch용 딥 러닝 모델을 제공하는 사전 구축 컨테이너에 대한 컨테이너 정의를 포함해야 합니다.

다음의 컨테이너 이미지에는 TensorFlow 2.7.0과 Ubuntu 20.04가 있습니다. Habana Gaudi 엑셀러레이터에 최적화된 사전 구축된 Deep Learning Containers의 전체 목록은 GitHub에서 관리됩니다. 자세한 정보는 [abana Training Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#habana-training-containers)를 참조하세요.

```
763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training-habana:2.7.0-hpu-py38-synapseai1.2.0-ubuntu20.04
```

다음은 사용할 구문을 표시하는 Amazon EC2의 Linux 컨테이너용 태스크 정의 예입니다. 이 예제에서는 여기(`vault.habana.ai/gaudi-docker/1.1.0/ubuntu20.04/habanalabs/tensorflow-installer-tf-cpu-2.6.0:1.1.0-614`)서 찾은 Habana Labs System Management Interface Tool(HL-SMI)을 포함하는 이미지를 사용합니다.

```
{
    "family": "dl-test",
    "requiresCompatibilities": ["EC2"],
    "placementConstraints": [
        {
            "type": "memberOf",
            "expression": "attribute:ecs.os-type == linux"
        },
        {
            "type": "memberOf",
            "expression": "attribute:ecs.instance-type == dl1.24xlarge"
        }
    ],
    "networkMode": "host",
    "cpu": "10240",
    "memory": "1024",
    "containerDefinitions": [
        {
            "entryPoint": [
                "sh",
                "-c"
            ],
            "command": ["hl-smi"],
            "cpu": 8192,
            "environment": [
                {
                    "name": "HABANA_VISIBLE_DEVICES",
                    "value": "all"
                }
            ],
            "image": "vault.habana.ai/gaudi-docker/1.1.0/ubuntu20.04/habanalabs/tensorflow-installer-tf-cpu-2.6.0:1.1.0-614",
            "essential": true,
            "name": "tensorflow-installer-tf-hpu"
        }
    ]
}
```

# 64비트 ARM 워크로드에 대한 Amazon ECS 작업 정의
<a name="ecs-arm64"></a>

Amazon ECS는 64비트 ARM 애플리케이션 사용을 지원합니다. [AWS Graviton 프로세서](https://aws.amazon.com/ec2/graviton/)로 구동되는 플랫폼에서 애플리케이션을 실행할 수 있습니다. 다양한 워크로드에 적합합니다. 여기에는 애플리케이션 서버, 마이크로 서비스, 고성능 컴퓨팅, CPU 기반 기계 학습 추론, 비디오 인코딩, 전자 설계 자동화, 게임, 오픈 소스 데이터베이스, 인 메모리 캐시 등의 워크로드가 포함됩니다.

## 고려 사항
<a name="ecs-arm64-considerations"></a>

64비트 ARM 아키텍처를 사용하는 태스크 정의 배포를 시작하기 전에 다음에 유의합니다.
+ 애플리케이션에서 Fargate 또는 EC2를 사용할 수 있습니다.
+ 애플리케이션에서 Linux 운영 체제만 사용할 수 있습니다.
+ Fargate 유형의 경우 애플리케이션은 Fargate 플랫폼 버전 `1.4.0` 이상을 사용해야 합니다.
+ 애플리케이션은 모니터링을 위해 Fluent Bit 또는 CloudWatch를 사용할 수 있습니다.
+ Fargate의 경우 다음 AWS 리전에서는 64비트 ARM 워크로드를 지원하지 않습니다.
  + 미국 동부(버지니아 북부), `use1-az3` 가용 영역
+  EC2의 경우 다음을 참조하여 사용하려는 인스턴스 유형을 사용자의 리전에서 지원하는지 확인합니다.
  + [Amazon EC2 M6g 인스턴스](https://aws.amazon.com/ec2/instance-types/m6)
  +  [Amazon EC2 T4g 인스턴스](https://aws.amazon.com/ec2/instance-types/t4/)
  +  [Amazon EC2 C6g 인스턴스](https://aws.amazon.com/ec2/instance-types/c6g/)
  +  [Amazon EC2 R6gd 인스턴스](https://aws.amazon.com/ec2/instance-types/r6/)
  +  [Amazon EC2 X2gd 인스턴스](https://aws.amazon.com/ec2/instance-types/x2/)

  필터와 함께 Amazon EC2 `describe-instance-type-offerings` 명령을 사용하여 해당 리전에 대한 인스턴스 상품을 볼 수도 있습니다.

  ```
  aws ec2 describe-instance-type-offerings --filters Name=instance-type,Values=instance-type --region region
  ```

  다음 예에서는 미국 동부(버지니아 북부)(us-east-1) 리전의 M6 인스턴스 유형 가용성을 확인합니다.

  ```
  aws ec2 describe-instance-type-offerings --filters "Name=instance-type,Values=m6*" --region us-east-1
  ```

  자세한 정보는 *Amazon EC2 Command Line Reference*(Amazon EC2 명령줄 레퍼런스)의 [describe-instance-type-offerings](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instance-type-offerings.html)를 참조하세요.

# Amazon ECS 작업 정의에서 ARM 아키텍처 지정
<a name="ecs-arm-specifying"></a>

ARM 아키텍처를 활용하려면 `cpuArchitecture` 태스크 정의 파라미터에 `ARM64`를 지정합니다.

다음 예에서, ARM 아키텍처는 태스크 정의에 지정됩니다. JSON 형식입니다.

```
{
    "runtimePlatform": {
        "operatingSystemFamily": "LINUX",
        "cpuArchitecture": "ARM64"
    },
...
}
```

다음 예는 "hello world"를 표시하는 ARM 아키텍처에 대한 태스크 정의입니다.

```
{
 "family": "arm64-testapp",
 "networkMode": "awsvpc",
 "containerDefinitions": [
    {
        "name": "arm-container",
        "image": "public.ecr.aws/docker/library/busybox:latest",
        "cpu": 100,
        "memory": 100,
        "essential": true,
        "command": [ "echo hello world" ],
        "entryPoint": [ "sh", "-c" ]
    }
 ],
 "requiresCompatibilities": [ "EC2" ],
 "cpu": "256",
 "memory": "512",
 "runtimePlatform": {
        "operatingSystemFamily": "LINUX",
        "cpuArchitecture": "ARM64"
  },
 "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole"
}
```

# Amazon ECS 로그를 CloudWatch로 전송
<a name="using_awslogs"></a>

CloudWatch Logs로 로그 정보를 전송하도록 태스크의 컨테이너를 구성할 수 있습니다. 태스크에 대해 Fargate를 사용하는 경우 컨테이너에서 로그를 볼 수 있습니다. EC2를 사용하고 있다면 한 곳의 편리한 위치에서 컨테이너의 다양한 로그를 볼 수 있으며 컨테이너 로그가 컨테이너 인스턴스에서 디스크 스페이스를 차지하지 못하도록 방지합니다.

**참고**  
태스크의 컨테이너에서 기록되는 정보 유형은 대부분 `ENTRYPOINT` 명령에 따라 결정됩니다. 기본적으로 수집되는 로그는 컨테이너를 로컬에서 실행했을 때 일반적으로 대화식 터미널에 표시되는 명령 출력(`STDOUT` 및 `STDERR` I/O 스트림)을 나타냅니다. `awslogs` 로그 드라이버는 이러한 로그를 Docker에서 CloudWatch Logs로 전달하는 역할만 합니다. 다른 파일 데이터 또는 스트림을 수집할 수 있는 대체 방법을 포함해 Docker 로그가 처리되는 방식에 대한 자세한 정보는 Docker 설명서에서 [컨테이너 또는 서비스 로그 보기](https://docs.docker.com/engine/logging/) 섹션을 참조하세요.

Amazon ECS 컨테이너 인스턴스에서 CloudWatch Logs로 시스템 로그를 보내려면 *Amazon CloudWatch Logs 사용 설명서*의 [로그 파일 모니터링](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatchLogs.html) 및 [CloudWatch Logs 할당량](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html)을 참조하세요.

## Fargate
<a name="enable_awslogs"></a>

태스크에 Fargate를 사용하는 경우 태스크 정의에 필요한 `logConfiguration` 파라미터를 추가하여 `awslogs` 로그 드라이버를 켜야 합니다. 자세한 내용은 [Amazon ECS 태스크 정의 예제: 로그를 CloudWatch로 라우팅](specify-log-config.md) 섹션을 참조하세요.

Fargate의 Windows 컨테이너의 경우 태스크 정의 파라미터에 특수 문자(예: `& \ < > ^ |`)가 있는 경우 다음 옵션 중 하나를 수행합니다.
+ 전체 파라미터 문자열 주위에 큰따옴표가 포함된 이스케이프(`\`) 추가

  예제

  ```
  "awslogs-multiline-pattern": "\"^[|DEBUG|INFO|WARNING|ERROR\"",
  ```
+ 각 특수 문자 주위에 이스케이프(`^`) 문자 추가

  예제

  ```
  "awslogs-multiline-pattern": "^^[^|DEBUG^|INFO^|WARNING^|ERROR",
  ```

## EC2
<a name="ec2-considerations"></a>

해당 태스크에 EC2를 사용하는 경우 `awslogs` 로그 드라이버를 설정하려면 Amazon ECS 컨테이너 인스턴스에 버전 1.9.0 이상의 컨테이너 에이전트가 필요합니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 정보는 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.

**참고**  
Amazon ECS 최적화 AMI 또는 `ecs-init` 패키지의 최소 버전 `1.9.0-1`이 포함된 사용자 지정 AMI를 사용해야 합니다. 사용자 지정 AMI를 사용하는 경우 **docker run** 문 또는 환경 변수 파일에서 다음 환경 변수를 사용하여 에이전트를 시작할 때 Amazon EC2 인스턴스에서 `awslogs` 로깅 드라이버를 사용할 수 있도록 지정해야 합니다.  

```
ECS_AVAILABLE_LOGGING_DRIVERS=["json-file","awslogs"]
```

또한 Amazon ECS 컨테이너 인스턴스는 컨테이너 인스턴스를 시작할 때 사용하는 IAM 역할에 `logs:CreateLogStream` 및 `logs:PutLogEvents` 권한도 요구합니다. Amazon ECS에서 `awslogs` 로그 드라이버를 사용 설정하기 전에 Amazon ECS 컨테이너 인스턴스 역할을 생성한 경우 이 권한을 추가해야 할 수 있습니다. `ecsTaskExecutionRole`은 태스크에 할당되고 올바른 권한이 포함되어 있을 때 사용됩니다. 작업 실행 역할에 대한 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요. 컨테이너 인스턴스가 컨테이너 인스턴스에 대해 관리형 IAM 정책을 사용하는 경우 컨테이너 인스턴스에 올바른 권한이 부여될 수 있습니다. 컨테이너 인스턴스의 관리형 IAM 정책에 대한 자세한 내용은 [Amazon ECS 컨테이너 인스턴스 IAM 역할](instance_IAM_role.md) 섹션을 참조하세요.

# Amazon ECS 태스크 정의 예제: 로그를 CloudWatch로 라우팅
<a name="specify-log-config"></a>

컨테이너가 `awslogs`로 로그를 전송할 수 있으려면 태스크 정의에서 컨테이너에 대한 CloudWatch 로그 드라이버를 지정해야 합니다. 로그 파라미터에 대한 자세한 내용은 [스토리지 및 로깅](task_definition_parameters.md#container_definition_storage) 섹션을 참조하세요.

다음의 작업 정의 JSON에는 각 컨테이너에 대해 지정된 `logConfiguration` 개체가 있습니다. 하나는 `awslogs-wordpress`라는 로그 그룹에 로그를 보내는 WordPress 컨테이너용입니다. 다른 하나는 `awslogs-mysql`이라는 로그 그룹에 로그를 보내는 MySQL 컨테이너용입니다. 두 컨테이너 모두 `awslogs-example` 로그 스트림 접두사를 사용합니다.

```
{
    "containerDefinitions": [
        {
            "name": "wordpress",
            "links": [
                "mysql"
            ],
            "image": "public.ecr.aws/docker/library/wordpress:latest",
            "essential": true,
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "awslogs-wordpress",
                    "awslogs-region": "us-west-2",
                    "awslogs-stream-prefix": "awslogs-example"
                }
            },
            "memory": 500,
            "cpu": 10
        },
        {
            "environment": [
                {
                    "name": "MYSQL_ROOT_PASSWORD",
                    "value": "password"
                }
            ],
            "name": "mysql",
            "image": "public.ecr.aws/docker/library/mysql:latest",
            "cpu": 10,
            "memory": 500,
            "essential": true,
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "awslogs-mysql",
                    "awslogs-region": "us-west-2",
                    "awslogs-stream-prefix": "awslogs-example",
                    "mode": "non-blocking", 
                    "max-buffer-size": "25m" 
                }
            }
        }
    ],
    "family": "awslogs-example"
}
```

## 다음 단계
<a name="specify-log-config-next-steps"></a>
+ CloudWatch AWS CLI 또는 API를 사용하여 로그 그룹에 대한 보존 정책을 선택적으로 설정할 수 있습니다. 자세한 내용은 *AWS Command Line Interface 참조*의 [put-retention-policy](https://docs.aws.amazon.com/cli/latest/reference/logs/put-retention-policy.html)를 참조하세요.
+ 컨테이너 정의 로그 구성에서 `awslogs` 로그 드라이버로 태스크 정의를 등록한 후 사용하여 태스크를 실행하거나 해당 태스크 정의를 사용하여 CloudWatch Logs로 로그 전송을 시작할 수 있습니다. 자세한 내용은 [애플리케이션을 Amazon ECS 태스크로 실행](standalone-task-create.md) 및 [Amazon ECS 롤링 업데이트 배포 생성](create-service-console-v2.md)(을)를 참조하세요.

# Amazon ECS 로그를 AWS 서비스 또는 AWS Partner로 전송
<a name="using_firelens"></a>

Amazon ECS용 FireLens를 사용하면 작업 정의 파라미터를 사용하여 로그 스토리지 및 분석을 위해 AWS 서비스 또는 AWS Partner Network(APN) 대상으로 로그를 라우팅할 수 있습니다. AWS Partner Network는 프로그램, 전문 지식 및 리소스를 활용하여 고객 제품을 구축, 마케팅 및 판매하는 글로벌 파트너 커뮤니티입니다. 자세한 내용은 [AWS Partner](https://aws.amazon.com/partners/work-with-partners/)를 참조하세요. FireLens는 [Fluentd](https://www.fluentd.org/) 및 [Fluent Bit](https://fluentbit.io/)와 함께 작동합니다. AWS for Fluent Bit 이미지가 제공되거나 자체 Fluentd 또는 Fluent Bit 이미지를 사용할 수 있습니다.

기본적으로 Amazon ECS는 FireLens 컨테이너가 해당 컨테이너를 사용하는 다른 컨테이너보다 먼저 시작되도록 컨테이너 종속성을 구성합니다. 또한 FireLens 컨테이너는 해당 컨테이너를 사용하는 모든 컨테이너가 중지된 후에 중지됩니다.

이 기능을 사용하려면 태스크에 필요한 AWS 서비스 사용에 필수적인 권한을 제공하는 태스크에 IAM 역할을 생성해야 합니다. 예를 들어, 컨테이너가 로그를 Firehose로 라우팅하는 경우 작업에 `firehose:PutRecordBatch` API를 직접 호출할 수 있는 권한이 필요합니다. 자세한 정보는 *IAM 사용 설명서*의 [IAM 자격 증명 권한 추가 및 제거](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) 섹션을 참조하세요.

다음 조건에서는 태스크 수행 시 Amazon ECS 태스크 실행 역할이 필요할 수도 있습니다. 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.
+ 태스크가 Fargate에 호스팅되고 Amazon ECR에서 컨테이너 이미지를 가져오거나 로그 구성의 AWS Secrets Manager에서 민감한 데이터를 참조하는 경우, 태스크 실행 IAM 역할을 포함하고 있어야 합니다.
+ Amazon S3에서 호스팅되는 사용자 지정 구성 파일을 사용하는 경우에는 작업 실행 IAM 역할에 `s3:GetObject` 권한이 포함되어야 합니다.

Amazon ECS용 FireLens를 사용할 때는 다음 사항을 고려해야 합니다.
+ 콘솔에서 컨테이너 이름을 쉽게 구분할 수 있도록 로그 컨테이너 이름에 `my_service_`를 추가하는 것이 좋습니다.
+ Amazon ECS는 기본적으로 애플리케이션 컨테이너와 FireLens 컨테이너 사이에서 시작 컨테이너 순서 종속성을 추가합니다. 애플리케이션 컨테이너와 FireLens 컨테이너 사이에서 컨테이너 순서를 지정하면 기본 시작 컨테이너 순서가 재정의됩니다.
+ Amazon ECS용 FireLens는 Linux의 AWS Fargate와 Linux의 Amazon EC2 모두에서 호스팅되는 작업에 대해 지원됩니다. Windows 컨테이너는 FireLens를 지원하지 않습니다.

  Windows 컨테이너에 대한 중앙 집중식 로깅을 구성하는 방법에 대한 자세한 내용은 [Centralized logging for Windows containers on Amazon ECS using Fluent Bit](https://aws.amazon.com/blogs/containers/centralized-logging-for-windows-containers-on-amazon-ecs-using-fluent-bit/)(Fluent Bit를 사용하여 Amazon ECS에서 Windows 컨테이너에 대한 중앙 집중식 로깅)를 참조하세요.
+ CloudFormation 템플릿을 사용하여 Amazon ECS를 위한 FireLens를 구성할 수 있습니다. 자세한 정보는 *AWS CloudFormation 사용 설명서*의 [<shared id="AWS"/>::ECS::TaskDefinition FirelensConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-firelensconfiguration.html)을 참조하세요.
+ FireLens의 수신 포트는 `24224`이므로 FireLens 로그 라우터가 태스크 범위를 벗어나지 않도록 하기 위해, 태스크에서 사용하는 보안 그룹의 포트 `24224`에서 인바운드 트래픽을 허용해서는 안 됩니다. `awsvpc` 네트워크 모드를 사용하는 작업의 경우 이것은 태스크와 연결된 보안 그룹입니다. `host` 네트워크 모드를 사용하는 태스크의 경우 이것은 태스크를 호스팅하는 Amazon EC2 인스턴스와 연결된 보안 그룹입니다. `bridge` 네트워크 모드를 사용하는 태스크의 경우 포트 `24224`를 사용하는 포트 매핑을 생성하지 마세요.
+ `bridge` 네트워크 모드를 사용하는 작업의 경우 FireLens 구성이 포함된 컨테이너는 해당 컨테이너를 사용하는 모든 애플리케이션 컨테이너가 시작되기 전에 시작해야 합니다. 컨테이너의 시작 순서를 제어하려면 태스크 정의에서 종속성 조건을 사용하세요. 자세한 정보는 [컨테이너 종속성](task_definition_parameters.md#container_definition_dependson) 섹션을 참조하세요.
**참고**  
FireLens 구성과 함께 컨테이너 정의에서 종속성 조건 파라미터를 사용하는 경우 각 컨테이너에 `START` 또는 `HEALTHY` 조건 요구 사항이 있는지 확인하세요.
+ 기본적으로 FireLens는 클러스터 및 태스크 정의 이름을 추가하고 클러스터의 Amazon 리소스 이름(ARN)을 stdout/stderr 컨테이너 로그에 메타데이터 키로 추가합니다. 다음은 메타데이터 형식의 예입니다.

  ```
  "ecs_cluster": "cluster-name",
  "ecs_task_arn": "arn:aws:ecs:region:111122223333:task/cluster-name/f2ad7dba413f45ddb4EXAMPLE",
  "ecs_task_definition": "task-def-name:revision",
  ```

  로그에 메타데이터를 포함시키지 않으려면 태스크 정의의 `firelensConfiguration` 섹션에서 `enable-ecs-log-metadata`를 `false`로 설정합니다.

  ```
  "firelensConfiguration":{
     "type":"fluentbit",
     "options":{
        "enable-ecs-log-metadata":"false",
        "config-file-type":"file",
        "config-file-value":"/extra.conf"
  }
  ```

루트가 아닌 사용자로 실행하도록 FireLens 컨테이너를 구성할 수 있습니다. 다음을 고려하세요.
+  루트가 아닌 사용자로 실행하도록 FireLens 컨테이너를 구성하려면 다음 형식 중 하나로 사용자를 지정해야 합니다.
  + `uid`
  + `uid:gid`
  + `uid:group`

  컨테이너 정의에서 사용자 지정 방법에 대한 자세한 내용은 *Amazon Elastic Container Service API 참조*의 [ContainerDefinition](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html)을 참조하세요.

  FireLens 컨테이너는 UNIX 소켓을 통해 애플리케이션 로그를 수신합니다. Amazon ECS 에이전트는 `uid`를 사용하여 소켓 디렉터리의 소유권을 FireLens 컨테이너에 할당합니다.
+ 루트가 아닌 사용자로 실행하도록 FireLens 컨테이너를 구성하는 방법은 Amazon ECS 에이전트 버전 `1.96.0` 이상 및 Amazon ECS 최적화 AMI 버전 `v20250716` 이상에서 지원됩니다.
+ FireLens 컨테이너에 사용자를 지정할 때 `uid`는 고유해야 하며 태스크 또는 컨테이너 인스턴스의 다른 컨테이너에 속하는 다른 프로세스에는 사용되지 않아야 합니다.

호스팅하는 파일 또는 Amazon S3에 있는 파일을 포함하여 Amazon ECS에서 여러 구성 파일을 사용하는 방법에 대한 자세한 내용은 [Init process for Fluent Bit on ECS, multi-config support](https://github.com/aws/aws-for-fluent-bit/tree/mainline/use_cases/init-process-for-fluent-bit)를 참조하세요.

구성 예제에 대한 자세한 내용은 [Amazon ECS 태스크 정의 예제: 로그를 FireLens로 라우팅](firelens-taskdef.md) 섹션을 참조하세요.

높은 처리량을 위해 로그를 구성하는 방법에 대한 자세한 내용은 [높은 처리량을 위한 Amazon ECS 로그 구성](firelens-docker-buffer-limit.md) 섹션을 참조하세요.

# 높은 처리량을 위한 Amazon ECS 로그 구성
<a name="firelens-docker-buffer-limit"></a>

로그 처리량이 많은 시나리오의 경우, FireLens 및 Fluent Bit와(과) 함께 `awsfirelens` 로그 드라이버를 사용하는 것이 좋습니다. Fluent Bit은(는) 리소스를 효율적으로 사용하며 수백만 개의 로그 레코드를 처리할 수 있는 경량 로그 프로세서입니다. 하지만 대규모 환경에서 최적의 성능을 달성하려면 구성을 조정해야 합니다.

이 섹션에서는 시스템 안정성을 유지하고 데이터 손실이 없도록 보장하면서 높은 로그 처리량을 처리하기 위한 고급 Fluent Bit 최적화 기술을 다룹니다.

FireLens에서 사용자 지정 구성 파일을 사용하는 방법에 대한 자세한 내용은 [사용자 지정 구성 파일 사용](firelens-taskdef.md#firelens-taskdef-customconfig)을(를) 참고하세요. 추가 예제는 GitHub의 [Amazon ECS FireLens 예제](https://github.com/aws-samples/amazon-ecs-firelens-examples)를 확인하세요.

**참고**  
`workers` 및 `threaded`와(과) 같은 이 섹션의 일부 구성 옵션에는 Fluent Bit 버전 3 이상을 위한 AWS이(가) 필요합니다. 사용 가능한 버전에 대한 자세한 내용은 [Fluent Bit 릴리스에 대한 AWS](https://github.com/aws/aws-for-fluent-bit/releases)을(를) 참고하세요.

## 파일 시스템 버퍼링 사용
<a name="firelens-filesystem-buffering"></a>

기본적으로 Fluent Bit은(는) 모든 데이터를 메모리에 버퍼링합니다. 데이터가 출력으로 플러시되는 속도보다 빠르게 수집되면 버퍼가 가득 찹니다. 버퍼가 가득 차면 버퍼 스페이스가 확보될 때까지 입력 플러그인이 일시 중지되며, 이로 인해 백프레셔가 발생하고 애플리케이션 속도가 느려질 수 있습니다.

처리량이 많은 시나리오의 경우 파일 시스템 버퍼링을 사용하는 것이 좋습니다. Fluent Bit이(가) 버퍼링과 스토리지를 관리하는 방법에 대한 자세한 내용은 Fluent Bit 문서의 [버퍼링 및 스토리지](https://docs.fluentbit.io/manual/administration/buffering-and-storage) 섹션을 참고하세요.

파일 시스템 버퍼링은 다음과 같은 장점을 제공합니다:
+ **더 큰 버퍼 용량** – 일반적으로 디스크 스페이스를 메모리보다 훨씬 여유가 있습니다.
+ **지속성** - 버퍼링된 데이터는 Fluent Bit(이)가 재시작되어도 유지됩니다.
+ **점진적 성능 저하** - 출력 오류가 발생해도 데이터가 메모리를 고갈시키는 대신 디스크에 축적됩니다.

파일 시스템 버퍼링을 활성화하려면 사용자 지정 Fluent Bit 구성 파일을 제공하세요. 다음 예시는 권장 구성을 보여줍니다:

```
[SERVICE]
    # Flush logs every 1 second
    Flush 1
    # Wait 120 seconds during shutdown to flush remaining logs
    Grace 120
    # Directory for filesystem buffering
    storage.path             /var/log/flb-storage/
    # Limit chunks stored 'up' in memory (reduce for memory-constrained environments)
    storage.max_chunks_up    32
    # Flush backlog chunks to destinations during shutdown (prevents log loss)
    storage.backlog.flush_on_shutdown On

[INPUT]
    Name forward
    unix_path /var/run/fluent.sock
    # Run input in separate thread to prevent blocking
    threaded true
    # Enable filesystem buffering for persistence
    storage.type filesystem

[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    # Use multiple workers for parallel processing
    workers 2
    # Retry failed flushes up to 15 times
    retry_limit 15
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 10G
```

주요 구성 파라미터:

`storage.path`  
Fluent Bit이(가) 디스크에 버퍼링된 청크를 저장하는 디렉터리입니다.

`storage.backlog.flush_on_shutdown`  
이 기능이 활성화되면 Fluent Bit은(는) 종료 시 백로그에 있는 모든 파일 시스템 청크를 대상지로 플러시하려고 시도합니다. 이는 Fluent Bit이(가) 중지되기 전에 데이터 전달을 보장하는 데 도움이 되지만, 종료 시간이 늘어날 수 있습니다.

`storage.max_chunks_up`  
메모리에 남아 있는 청크의 수입니다. 기본값은 128개 청크이며, 각 청크가 최대 4\$15MB를 사용할 수 있기 때문에 500MB 이상의 메모리를 소비할 수 있습니다. 메모리가 제한된 환경에서는 이 값을 낮추세요. 예를 들어 버퍼링에 사용할 수 있는 공간이 50MB라면, 이 값을 8\$110개 청크로 설정합니다.

`storage.type filesystem`  
입력 플러그인에 대해 파일 시스템 스토리지를 활성화합니다. 이름과 달리 Fluent Bit은(는) `mmap`을(를) 사용하여 청크를 메모리와 디스크 모두에 매핑하며, 성능 저하 없이 지속성을 제공합니다.

`threaded true`  
Fluent Bit의 메인 이벤트 루프와 별개로 입력을 자체 스레드에서 실행합니다. 이렇게 하면 느린 입력이 전체 파이프라인을 차단하는 것을 방지합니다.

## 출력 구성 최적화
<a name="firelens-output-optimization"></a>

네트워크 문제, 서비스 중단, 대상지의 스로틀링 등으로 인해 로그가 전달되지 않을 수 있습니다. 적절한 출력 구성은 데이터 손실 없는 복원력을 보장합니다.

출력 플러시가 실패하면 Fluent Bit은(는) 해당 작업을 재시도할 수 있습니다. 다음 파라미터는 재시도 동작을 제어합니다:

`retry_limit`  
레코드를 삭제하기 전까지의 최대 재시도 횟수입니다. 기본값은 1입니다. 프로덕션 환경의 경우 15회 이상으로 설정하는 것을 권장하며, 이는 지수 백오프를 통해 몇 분간의 장애 상황을 커버할 수 있습니다.

`scheduler.base`  
재시도 간의 최소 초 단위 시간입니다. 10초를 권장합니다.

`scheduler.cap`  
지수 백오프 사용 시 재시도 간의 최대 초 단위 시간입니다. 60초를 권장합니다.

`workers`  
병렬 출력 처리를 위한 스레드 수입니다. 여러 워커를 사용하면 플러시를 동시에 수행할 수 있어, 많은 청크를 처리할 때 처리량이 향상됩니다.

`[SERVICE]` 섹션의 `Grace` 파라미터는 종료 시 버퍼링된 데이터를 플러시하기 위해 Fluent Bit이(가) 대기하는 시간을 설정합니다. `Grace` 기간은 컨테이너의 `stopTimeout`와(과) 연계하여 조정해야 합니다. Fluent Bit이(가) `SIGKILL`을(를) 받기 전에 플러시를 완료할 수 있도록 `stopTimeout`이(가) `Grace` 기간을 초과하도록 설정하세요. 예를 들어 `Grace`이(가) 120초라면, `stopTimeout`은(는) 150초로 설정합니다.

다음 예시는 높은 처리량 시나리오를 위해 권장되는 모든 설정이 포함된 전체 Fluent Bit 구성을 보여줍니다.

```
[SERVICE]
    # Flush logs every 1 second
    Flush 1
    # Wait 120 seconds during shutdown to flush remaining logs
    Grace 120
    # Directory for filesystem buffering
    storage.path             /var/log/flb-storage/
    # Limit chunks stored 'up' in memory (reduce for memory-constrained environments)
    storage.max_chunks_up    32
    # Flush backlog chunks to destinations during shutdown (prevents log loss)
    storage.backlog.flush_on_shutdown On
    # Minimum seconds between retries
    scheduler.base           10
    # Maximum seconds between retries (exponential backoff cap)
    scheduler.cap            60

[INPUT]
    Name forward
    unix_path /var/run/fluent.sock
    # Run input in separate thread to prevent blocking
    threaded true
    # Enable filesystem buffering for persistence
    storage.type filesystem

[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    # Use multiple workers for parallel processing
    workers 2
    # Retry failed flushes up to 15 times
    retry_limit 15
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 10G
```

## 안전성을 위해 다중 대상 로깅 사용
<a name="firelens-multi-destination"></a>

로그를 여러 대상으로 전송하면 단일 장애점을 제거할 수 있습니다. 예를 들어 CloudWatch Logs에 장애가 발생하더라도 로그는 여전히 Amazon S3에 도달합니다.

다중 대상 로깅은 다음과 같은 이점을 제공합니다. Amazon S3 출력 플러그인은 gzip 및 Parquet 형식과 같은 압축 옵션도 지원하여 스토리지 비용을 절감할 수 있습니다. 자세한 내용은 Fluent Bit 문서의 [S3 압축](https://docs.fluentbit.io/manual/pipeline/outputs/s3#compression) 섹션을 참고하세요.

다중 대상 로깅은 다음과 같은 이점을 제공할 수 있습니다:
+ **중복성** - 한 곳의 대상지에 장애가 발생해도 로그는 다른 곳에 도달합니다.
+ **복구** - 한 시스템의 데이터 공백을 다른 시스템을 통해 재구성합니다.
+ **내구성** - 장기 보관을 위해 Amazon S3에 로그를 아카이빙합니다.
+ **비용 최적화** - .최근 로그는 보관 주기가 짧고 쿼리가 빠른 CloudWatch Logs에 보관하고, 모든 로그는 장기 보관을 위해 비용이 저렴한 Amazon S3 스토리지에 아카이빙합니다.

다음 Fluent Bit 구성은 CloudWatch Logs와 Amazon S3 모두에 로그를 전송합니다.

```
[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    workers 2
    retry_limit 15

[OUTPUT]
    Name s3
    Match *
    bucket my-logs-bucket
    region us-west-2
    total_file_size 100M
    s3_key_format /fluent-bit-logs/$(ecs_task_id)/%Y%m%d/%H/%M/$UUID
    upload_timeout 10m
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 5G
```

두 출력 모두 동일한 `Match *` 패턴을 사용하므로, 모든 레코드가 두 대상지에 각각 독립적으로 전송됩니다. 한 곳의 대상지에 장애가 발생하더라도 로그는 다른 곳으로 계속 흐르며, 실패한 플러시는 나중에 재시도할 수 있도록 파일 시스템 버퍼에 축적됩니다.

## tail 입력 플러그인을 사용한 파일 기반 로깅 사용
<a name="firelens-tail-input"></a>

로그 손실이 중요한 문제인 높은 처리량 시나리오에서는 대안적인 접근 방식을 사용할 수 있습니다. 애플리케이션이 로그를 디스크 파일에 쓰고, Fluent Bit이(가) `tail` 입력 플러그인을 사용하여 해당 파일을 읽도록 구성하는 방식입니다. 이 방식은 Docker 로깅 드라이버 레이어를 완전히 우회합니다.

tail 플러그인을 사용한 파일 기반 로깅은 다음과 같은 이점을 제공합니다:
+ **오프셋 추적** - tail 플러그인은 (`DB` 옵션을 사용하여) 데이터베이스 파일에 파일 오프셋을 저장할 수 있어, Fluent Bit 재시작 시에도 내구성을 제공합니다. 컨테이너 재시작 시 로그 손실이 발생하는 것을 방지하는 데 도움이 됩니다.
+ **입력 수준 버퍼링** - `Mem_Buf_Limit`을(를) 사용하여 입력 플러그인에서 직접 메모리 버퍼 제한을 구성할 수 있으며, 이를 통해 메모리 사용량을 더욱 세밀하게 제어할 수 있습니다.
+ **Docker 오버헤드 방지** – 로그가 Docker의 로그 버퍼를 거치지 않고 파일에서 Fluent Bit(으)로 직접 전달됩니다.

이 방식을 사용하려면 애플리케이션이 `stdout` 대신 파일에 로그를 기록해야 합니다. 애플리케이션 컨테이너와 Fluent Bit 컨테이너 모두 로그 파일이 저장된 공유 볼륨을 마운트합니다.

다음 예시는 모범 사례가 적용된 tail 입력 구성을 보여줍니다.

```
[INPUT]
    Name tail
    # File path or glob pattern to tail
    Path /var/log/app.log
    # Database file for storing file offsets (enables resuming after restart)
    DB /var/log/flb_tail.db
    # when true, controls that only fluent-bit will access the database (improves performance)
    DB.locking true
    # Skip long lines instead of skipping the entire file
    Skip_Long_Lines On
    # How often (in seconds) to check for new files matching the glob pattern
    Refresh_Interval 10
    # Extra seconds to monitor a file after rotation to account for pending flush
    Rotate_Wait 30
    # Maximum size of the buffer for a single line
    Buffer_Max_Size 10MB
    # Initial allocation size for reading file data
    Buffer_Chunk_Size 1MB
    # Maximum memory buffer size (tail pauses when full)
    Mem_Buf_Limit 75MB
```

tail 입력 플러그인을 사용할 때는 다음 사항을 고려하세요:
+ 디스크 소진을 방지하기 위해 애플리케이션 로그에 대한 로그 로테이션을 구현하세요. 성능을 측정하기 위해 기본 볼륨 메트릭을 모니터링합니다.
+ 로그 형식에 따라 `Ignore_Older`, `Read_from_Head` 및 멀티라인 파서와 같은 설정을 고려하세요.

자세한 내용은 Fluent Bit 문서의 [Tail](https://docs.fluentbit.io/manual/pipeline/inputs/tail) 섹션을 참고하세요. 모범 사례는 AWS을(를) 위한 Fluent Bit 문제 해결 가이드의 [Tail config with best practices](https://github.com/aws/aws-for-fluent-bit/blob/mainline/troubleshooting/debugging.md#tail-config-with-best-practices)를 참고하세요.

## FireLens로 직접 로깅
<a name="firelens-environment-variables"></a>

`awsfirelens` 로그 드라이버가 태스크 정의에 지정되어 있으면 Amazon ECS 컨테이너 에이전트는 다음 환경 변수를 컨테이너에 주입합니다.

`FLUENT_HOST`  
FireLens 컨테이너에 할당된 IP 주소입니다.  
`bridge` 네트워크 모드에서 EC2를 사용하는 경우 FireLens 로그 라우터 컨테이너(컨테이너 정의에 `firelensConfiguration` 객체가 있는 컨테이너)를 다시 시작한 후 애플리케이션 컨테이너의 `FLUENT_HOST` 환경 변수가 부정확해질 수 있습니다. 이는 `FLUENT_HOST`가 동적 IP 주소이며 재시작 후 변경될 수 있기 때문입니다. 애플리케이션 컨테이너에서 `FLUENT_HOST` IP 주소로 직접 로깅하면 주소가 변경된 후 실패하기 시작할 수 있습니다. 개별 컨테이너를 재시작하는 방법에 대한 자세한 내용은 [컨테이너 재시작 정책이 있는 Amazon ECS 작업의 개별 컨테이너 재시작](container-restart-policy.md) 섹션을 참조하세요.

`FLUENT_PORT`  
Fluent Forward 프로토콜이 수신 대기 중인 포트입니다.

이 환경 변수들을 사용하면 `stdout`에 기록하는 대신 Fluent Forward 프로토콜을 사용하여 애플리케이션 코드에서 Fluent Bit 로그 라우터로 직접 로그를 보낼 수 있습니다. 이 방식은 Docker 로깅 드라이버 레이어를 우회하며 다음과 같은 이점을 제공합니다:
+ **낮은 대기 시간** – 로그가 Docker의 로깅 인프라를 거치지 않고 Fluent Bit(으)로 직접 전달됩니다.
+ **구조화된 로깅** - JSON 인코딩 오버헤드 없이 구조화된 로그 데이터를 기본적으로 전송합니다.
+ **제어력 향상** - 애플리케이션이 자체적인 버퍼링 및 오류 처리 로직을 구현할 수 있습니다.

다음 Fluent 로거 라이브러리는 Fluent Forward 프로토콜을 지원하며 Fluent Bit(으)로 로그를 직접 보내는 데 사용할 수 있습니다.
+ **Go** – [fluent-logger-golang](https://github.com/fluent/fluent-logger-golang)
+ **Python** – [fluent-logger-python](https://github.com/fluent/fluent-logger-python)
+ **Java** – [fluent-logger-java](https://github.com/fluent/fluent-logger-java)
+ **Node.js** – [fluent-logger-node](https://github.com/fluent/fluent-logger-node)
+ **Ruby** – [fluent-logger-ruby](https://github.com/fluent/fluent-logger-ruby)

## Docker 버퍼 제한 구성
<a name="firelens-buffer-limit"></a>

태스크 정의를 생성할 때 `log-driver-buffer-limit`에 값을 지정하여 메모리에 버퍼링되는 로그 라인의 수를 지정할 수 있습니다. 이는 Docker와 Fluent Bit 사이의 버퍼를 제어합니다. 자세한 정보는 Docker 설명서의 [Fluentd logging driver](https://docs.docker.com/engine/logging/drivers/fluentd/)(Fluentd 로깅 드라이버)를 참조하세요.

Docker에서 버퍼 메모리가 부족하여 새 메시지를 추가할 수 있도록 버퍼 메시지를 삭제할 수 있으므로 처리량이 많을 때 이 옵션을 사용합니다.

이 옵션을 사용할 때 다음 사항을 고려하세요:
+ 이 옵션은 플랫폼 버전 `1.4.0` 이상의 EC2 및 Fargate 유형에서 지원됩니다.
+ 이 옵션은 `logDriver`가 `awsfirelens`로 설정된 경우에만 유효합니다.
+ 기본 버퍼 제한은 `1048576`개의 로그 줄입니다.
+ 버퍼 제한은 로그 라인 `0`줄 이상, `536870912`줄 미만이어야 합니다.
+ 이 버퍼에 사용되는 최대 메모리 양은 각 로그 줄의 크기와 버퍼 크기를 곱한 값입니다. 예를 들어 애플리케이션의 로그 라인이 평균 `2`KiB라면, 버퍼 제한을 4096으로 설정했을 때 최대 `8`MiB를 사용합니다. 작업 수준에서 할당된 총 메모리 양은 로그 드라이버 메모리 버퍼 외에도 모든 컨테이너에 할당된 메모리 양보다 커야 합니다.

다음 태스크 정의는 `log-driver-buffer-limit`을(를) 구성하는 방법을 보여줍니다.

```
{
    "containerDefinitions": [
        {
            "name": "my_service_log_router",
            "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:3",
            "cpu": 0,
            "memoryReservation": 51,
            "essential": true,
            "firelensConfiguration": {
                "type": "fluentbit"
            }
        },
        {
            "essential": true,
            "image": "public.ecr.aws/docker/library/httpd:latest",
            "name": "app",
            "logConfiguration": {
                "logDriver": "awsfirelens",
                "options": {
                    "Name": "firehose",
                    "region": "us-west-2",
                    "delivery_stream": "my-stream",
                    "log-driver-buffer-limit": "52428800"
                }
            },
            "dependsOn": [
                {
                    "containerName": "my_service_log_router",
                    "condition": "START"
                }
            ],
            "memoryReservation": 100
        }
    ]
}
```

# Amazon ECS용 Fluent Bit 이미지 리포지토리에 대한 AWS
<a name="firelens-using-fluentbit"></a>

AWS는 CloudWatch Logs 및 Firehose 모두에 대해 플러그인과 함께 Fluent Bit 이미지를 제공합니다. Fluent Bit가 Fluentd보다 리소스 사용률이 낮으므로 Fluent Bit를 로그 라우터로 사용하는 것이 좋습니다. 자세한 정보는 [Fluent Bit용 CloudWatch Logs](https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit) 및 [Fluent Bit용 Amazon Kinesis Firehose](https://github.com/aws/amazon-kinesis-firehose-for-fluent-bit)를 참조하세요.

**AWS for Fluent Bit** 이미지는 고가용성을 위해 Amazon ECR 퍼블릭 갤러리와 Amazon ECR 리포지토리에 있는 Amazon ECR에 사용할 수 있습니다.

## Amazon ECR 퍼블릭 갤러리
<a name="firelens-image-ecrpublic"></a>

AWS for Fluent Bit 이미지는 Amazon ECR 퍼블릭 갤러리에서 사용할 수 있습니다. Amazon ECR 퍼블릭 갤러리는 퍼블릭 리포지토리이며 모든 AWS 리전에서 사용할 수 있으므로 여기에 AWS for Fluent Bit 이미지를 다운로드하는 것이 좋습니다. 자세한 정보는 Amazon ECR 퍼블릭 갤러리의 [aws-for-fluent-bit](https://gallery.ecr.aws/aws-observability/aws-for-fluent-bit)를 참조하세요.

### Linux
<a name="firelens-image-ecrpublic-linux"></a>

Amazon ECR 퍼블릭 갤러리의 AWS for Fluent Bit 이미지는 `ARM64` 또는 `x86-64` 아키텍처가 있는 Amazon Linux 운영 체제를 지원합니다.

원하는 이미지 태그로 리포지토리 URL을 지정하여 Amazon ECR 퍼블릭 갤러리에서 AWS for Fluent Bit 이미지를 가져올 수 있습니다. 사용 가능한 이미지 태그는 Amazon ECR 퍼블릭 갤러리의 **이미지 태그(Image tags)** 탭에서 확인할 수 있습니다.

Docker CLI에 사용할 구문은 다음과 같습니다.

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:tag
```

예를 들어, 이 Docker CLI 명령을 사용하여 Fluent Bit 릴리스를 위한 AWS의 "3.x" 제품군 최신 이미지를 가져올 수 있습니다.

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:3
```

**참고**  
인증되지 않은 풀은 허용되지만 인증된 가져오기보다 속도 제한이 낮습니다. 가져오기 전 AWS 계정을 인증하려면 다음 명령을 사용합니다.  

```
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
```

#### Fluent Bit 3.0.0에 대한 AWS
<a name="firelens-image-ecrpublic-linux-3.0.0"></a>

기존의 AWS for Fluent Bit 버전 `2.x` 외에도, AWS for Fluent Bit는 새 주 버전 `3.x`을 지원합니다. 새 주 버전에는 Amazon Linux 2에서 Amazon Linux 2023으로 이미지를 업그레이드하고 Fluent Bit 버전 `1.9.10`을 `4.1.1`로 업그레이드하는 작업이 포함되어 있습니다. 자세한 내용은 GitHub의 [AWS for Fluent Bit repository](https://github.com/aws/aws-for-fluent-bit/blob/mainline/VERSIONS.md)를 참조하세요.

다음 예제에서는 AWS for Fluent Bit `3.x` 이미지에 대한 업데이트된 태그를 보여줍니다.

AWS for Fluent Bit 이미지에 대해 다중 아키텍처 태그를 사용할 수 있습니다.

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:3
```

### Windows
<a name="firelens-image-ecrpublic-windows"></a>

Amazon ECR 퍼블릭 갤러리의 AWS for Fluent Bit 이미지는 다음 운영 체제를 사용하는 `AMD64` 아키텍처를 지원합니다.
+ Windows Server 2022 Full
+ Windows Server 2022 Core
+ Windows Server 2019 Full
+ Windows Server 2019 Core

AWS Fargate에 있는 Windows 컨테이너는 FireLens를 지원하지 않습니다.

원하는 이미지 태그로 리포지토리 URL을 지정하여 Amazon ECR 퍼블릭 갤러리에서 AWS for Fluent Bit 이미지를 가져올 수 있습니다. 사용 가능한 이미지 태그는 Amazon ECR 퍼블릭 갤러리의 **이미지 태그(Image tags)** 탭에서 확인할 수 있습니다.

Docker CLI에 사용할 구문은 다음과 같습니다.

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:tag
```

예를 들어 이 Docker CLI 명령을 사용하여 안정적인 최신 AWS for Fluent Bit 이미지를 가져올 수 있습니다.

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:windowsservercore-stable
```

**참고**  
인증되지 않은 풀은 허용되지만 인증된 가져오기보다 속도 제한이 낮습니다. 가져오기 전 AWS 계정을 인증하려면 다음 명령을 사용합니다.  

```
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
```

## Amazon ECR
<a name="firelens-image-ecr"></a>

Fluent Bit용 AWS 이미지는 고가용성을 위해 Amazon ECR에서 사용할 수 있습니다. 다음 명령을 사용하여 지정된 AWS 리전에서 이미지 URI를 검색하고 이미지 가용성을 설정할 수 있습니다.

### Linux
<a name="firelens-image-ecr-linux"></a>

다음 명령을 사용하여 안정적인 AWS for Fluent Bit 이미지 URI를 검색할 수 있습니다.

```
aws ssm get-parameters \
      --names /aws/service/aws-for-fluent-bit/stable \
      --region us-east-1
```

다음 명령을 사용하여 모든 버전의 Fluent Bit용 AWS 이미지를 나열하고 Systems Manager 파라미터 스토어 파라미터를 쿼리할 수 있습니다.

```
aws ssm get-parameters-by-path \
      --path /aws/service/aws-for-fluent-bit \
      --region us-east-1
```

안정적인 최신 AWS for Fluent Bit 이미지는 Systems Manager Parameter Store 이름을 참조하여 CloudFormation 템플릿에서 참조할 수 있습니다. 다음은 예제입니다.

```
Parameters:
  FireLensImage:
    Description: Fluent Bit image for the FireLens Container
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/aws-for-fluent-bit/stable
```

**참고**  
명령이 실패하거나 출력이 없는 경우 명령이 직접 호출되는 AWS 리전에서 이미지를 사용할 수 없습니다.

### Windows
<a name="firelens-image-ecr-windows"></a>

다음 명령을 사용하여 안정적인 AWS for Fluent Bit 이미지 URI를 검색할 수 있습니다.

```
aws ssm get-parameters \
      --names /aws/service/aws-for-fluent-bit/windowsservercore-stable \
      --region us-east-1
```

다음 명령을 사용하여 모든 버전의 Fluent Bit용 AWS 이미지를 나열하고 Systems Manager 파라미터 스토어 파라미터를 쿼리할 수 있습니다.

```
aws ssm get-parameters-by-path \
      --path /aws/service/aws-for-fluent-bit/windowsservercore \
      --region us-east-1
```

안정적인 최신 AWS for Fluent Bit 이미지는 Systems Manager 파라미터 스토어 이름을 참조하여 CloudFormation 템플릿에서 참조할 수 있습니다. 다음은 예제입니다.

```
Parameters:
  FireLensImage:
    Description: Fluent Bit image for the FireLens Container
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/aws-for-fluent-bit/windowsservercore-stable
```

# Amazon ECS 태스크 정의 예제: 로그를 FireLens로 라우팅
<a name="firelens-taskdef"></a>

FireLens에서 사용자 정의 로그 라우팅을 사용하려면 태스크 정의에 다음 사항을 지정해야 합니다.
+ FireLens 구성을 포함하는 로그 라우터 컨테이너. 컨테이너는 `essential`로 표시하는 것이 좋습니다.
+ `awsfirelens` 로그 드라이버를 지정하는 로그 구성이 포함된 하나 이상의 애플리케이션 컨테이너.
+ 태스크가 로그를 라우팅하는 데 필요한 권한이 포함된 태스크 IAM 역할 Amazon 리소스 이름(ARN).

AWS Management Console을 사용하여 새로운 태스크 정의를 생성할 때 로그 라우터 컨테이너를 쉽게 추가할 수 있는 FireLens 통합 섹션이 있습니다. 자세한 정보는 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md) 섹션을 참조하세요.

Amazon ECS는 로그 구성을 변환하고 Fluentd 또는 Fluent Bit 출력 구성을 생성합니다. 출력 구성은 Fluent Bit의 경우 `/fluent-bit/etc/fluent-bit.conf`, Fluentd의 경우 `/fluentd/etc/fluent.conf`에서 로그 라우팅 컨테이너에 마운트됩니다.

**중요**  
FireLens의 수신 포트는 `24224`입니다. 그러므로 FireLens 로그 라우터가 태스크 범위를 벗어나지 않도록 태스크에서 사용하는 보안 그룹의 포트 `24224`에서 수신 트래픽을 허용해서는 안 됩니다. `awsvpc` 네트워크 모드를 사용하는 작업의 경우 이것은 태스크와 연결된 보안 그룹입니다. `host` 네트워크 모드를 사용하는 태스크의 경우 이것은 태스크를 호스팅하는 Amazon EC2 인스턴스와 연결된 보안 그룹입니다. `bridge` 네트워크 모드를 사용하는 태스크의 경우 포트 `24224`를 사용하는 포트 매핑을 생성하지 마세요.

기본적으로 Amazon ECS는 로그 원본을 식별하는 데 도움이 되는 추가 필드를 로그 항목에 추가합니다.
+ `ecs_cluster` - 태스크가 속한 클러스터의 이름입니다.
+ `ecs_task_arn` – 컨테이너가 속한 태스크의 전체 Amazon 리소스 이름(ARN)
+ `ecs_task_definition` - 태스크에서 사용 중인 태스크 정의 이름 및 개정입니다.
+ `ec2_instance_id` – 컨테이너가 호스팅되는 Amazon EC2 인스턴스 ID입니다. 이 필드는 EC2 시작 유형을 사용하는 태스크에서만 유효합니다.

메타데이터를 원하지 않는 경우 `enable-ecs-log-metadata`를 `false`로 설정할 수 있습니다.

다음 태스크 정의 예에서는 Fluent Bit를 사용하여 로그를 CloudWatch Logs로 라우팅하는 로그 라우터 컨테이너를 정의합니다. 또한 로그 구성을 사용하여 Amazon Data Firehose로 로그를 라우팅하고 이벤트를 버퍼링하는 데 사용되는 메모리를 2MiB로 설정하는 애플리케이션 컨테이너를 정의합니다.

**참고**  
자세한 작업 정의 예제는 GitHub의 [Amazon ECS FireLens examples](https://github.com/aws-samples/amazon-ecs-firelens-examples)를 참조하세요.

```
{
  "family": "firelens-example-firehose",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecs_task_iam_role",
  "containerDefinitions": [
    {
            "name": "log_router",
            "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:3",
            "cpu": 0,
            "memoryReservation": 51,
            "portMappings": [],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/ecs-aws-firelens-sidecar-container",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "us-east-1",
                    "awslogs-stream-prefix": "firelens"
                },
                "secretOptions": []
            },
            "systemControls": [],
            "firelensConfiguration": {
                "type": "fluentbit"
            }
        },
    {
      "essential": true,
      "image": "public.ecr.aws/docker/library/httpd:latest",
      "name": "app",
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "options": {
          "Name": "firehose",
          "region": "us-west-2",
          "delivery_stream": "my-stream",
          "log-driver-buffer-limit": "1048576"
        }
      },
      "memoryReservation": 100
    }
  ]
}
```

`logConfiguration` 객체에 옵션으로 지정된 키 값 페어는 Fluentd 또는 Fluent Bit 출력 구성을 생성하는 데 사용됩니다. 다음은 Fluent Bit 출력 정의의 코드 예시입니다.

```
[OUTPUT]
    Name   firehose
    Match  app-firelens*
    region us-west-2
    delivery_stream my-stream
```

**참고**  
FireLens는 `match` 구성을 관리합니다. 태스크 정의에서 `match` 구성을 지정하지 않습니다.

## 사용자 지정 구성 파일 사용
<a name="firelens-taskdef-customconfig"></a>

사용자 지정 구성 파일을 지정할 수 있습니다. 구성 파일 형식은 사용 중인 로그 라우터의 기본 형식입니다. 자세한 정보는 [Fluentd Config 파일 구문](https://docs.fluentd.org/configuration/config-file)과 [YAML 구성](https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/yaml)을 참조하세요.

사용자 정의 구성 파일에서 `bridge` 또는 `awsvpc` 네트워크 모드를 사용하는 태스크의 경우 FireLens가 입력 구성에 Fluentd나 Fluent Bit를 추가하기 때문에 TCP를 통해 Fluentd 또는 Fluent Bit 전달 입력을 설정하지 않습니다.

사용자 정의 구성 파일을 지정하려면 FireLens 구성에 다음 옵션이 포함되어야 합니다.

`config-file-type`  
사용자 정의 구성 파일의 원본 위치입니다. 사용할 수 있는 옵션은 `s3` 또는 `file`입니다.  
AWS Fargate에 호스팅된 태스크는 `file` 구성 파일 유형만을 지원합니다. 하지만 AWS for Fluent Bit 초기화(init) 컨테이너를 사용하면 AWS Fargate에서 Amazon S3에 호스팅된 구성 파일을 사용할 수 있습니다. 자세한 내용은 GitHub의 [Init process for Fluent Bit on ECS, multi-config support](https://github.com/aws/aws-for-fluent-bit/blob/mainline/use_cases/init-process-for-fluent-bit/README.md)를 참고하세요.

`config-file-value`  
사용자 정의 구성 파일의 원본입니다. `s3` 구성 파일 유형을 사용하는 경우 구성 파일 값은 Amazon S3 버킷 및 파일의 전체 ARN입니다. `file` 구성 파일 유형을 사용하는 경우 구성 파일 값은 컨테이너 이미지 또는 컨테이너에 마운트된 볼륨에 있는 구성 파일의 전체 경로입니다.  
사용자 정의 구성 파일을 사용할 때는 FireLens가 사용하는 경로가 아닌 다른 경로를 지정해야 합니다. Amazon ECS는 Fluent Bit의 경우 `/fluent-bit/etc/fluent-bit.conf` 파일 경로를, Fluentd의 경우 `/fluentd/etc/fluent.conf` 파일 경로를 예약합니다.

다음 예에는 사용자 정의 구성을 지정할 때 필요한 구문이 나와 있습니다.

**중요**  
Amazon S3에서 호스팅되는 사용자 정의 구성 파일을 지정하려면 적절한 권한이 있는 태스크 실행 IAM 역할을 생성했는지 확인하세요.

다음은 사용자 정의 구성을 지정할 때 필요한 구문입니다.

```
{
  "containerDefinitions": [
    {
      "essential": true,
      "image": "906394416424.dkr.ecr.us-west-2.amazonaws.com/aws-for-fluent-bit:3",
      "name": "log_router",
      "firelensConfiguration": {
        "type": "fluentbit",
        "options": {
          "config-file-type": "s3 | file",
          "config-file-value": "arn:aws:s3:::amzn-s3-demo-bucket/fluent.conf | filepath"
        }
      }
    }
  ]
}
```

**참고**  
AWS Fargate에 호스팅된 태스크는 `file` 구성 파일 유형만을 지원합니다. 하지만 AWS for Fluent Bit 초기화(init) 컨테이너를 사용하면 AWS Fargate에서 Amazon S3에 호스팅된 구성 파일을 사용할 수 있습니다. 자세한 내용은 GitHub의 [Init process for Fluent Bit on ECS, multi-config support](https://github.com/aws/aws-for-fluent-bit/blob/mainline/use_cases/init-process-for-fluent-bit/README.md)를 참고하세요.

# Amazon ECS에서 AWS 컨테이너가 아닌 이미지 사용
<a name="private-auth"></a>

프라이빗 레지스트리를 사용하여 AWS Secrets Manager에 자격 증명을 저장한 후 작업 정의에서 참조합니다. 이는 태스크 정의에서 인증이 필요한 AWS 외부의 프라이빗 레지스트리에 있는 컨테이너 이미지를 참조하는 방법을 제공합니다. 이 기능은 Fargate, Amazon EC2 인스턴스 및 Amazon ECS Anywhere를 사용하는 외부 인스턴스에서 호스팅되는 태스크에서 지원됩니다.

**중요**  
태스크 정의가 Amazon ECR에 저장된 이미지를 참조하는 경우 이 주제가 적용되지 않습니다. 자세한 정보는 *Amazon Elastic Container Registry 사용 설명서*의 [Amazon ECS에서 Amazon ECR 이미지 사용](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_ECS.html)을 참조하세요.

Amazon EC2 인스턴스에서 호스팅되는 태스크의 경우 이 기능을 사용하려면 버전 `1.19.0` 이상의 컨테이너 에이전트가 있어야 합니다. 그러나 최신 버전의 컨테이너 에이전트를 사용하는 것이 좋습니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 정보는 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.

Fargate에서 호스팅되는 태스크의 경우 이 기능을 사용하려면 플랫폼 버전 `1.2.0` 이상이 필요합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.

컨테이너 정의에서 자신이 생성한 암호의 세부 정보와 함께 `repositoryCredentials` 객체를 지정합니다. 참조하는 보안 암호는 다른 AWS 리전 또는 이를 사용하는 태스크와 다른 계정에서 가져온 것일 수 있습니다.

**참고**  
Amazon ECS API, AWS CLI 또는 AWS SDK를 사용할 때 시작하는 태스크와 같은 AWS 리전에 암호가 존재할 경우, 암호의 전체 ARN 또는 이름을 사용할 수 있습니다. 암호가 다른 계정에 있는 경우 암호의 전체 ARN을 지정해야 합니다. AWS Management Console을 사용할 때는 항상 암호의 전체 ARN을 지정해야 합니다.

다음은 필요한 파라미터를 나타낸 태스크 정의의 예제 조각입니다.

다음 파라미터를 대체합니다.
+ *private-repo*를 프라이빗 리포지토리 호스트 이름으로 대체 
+ *private-image*를 이미지 이름으로 대체
+ *arn:aws:secretsmanager:region:aws\$1account\$1id:secret:secret\$1name*을 보안 암호의 Amazon 리소스 이름(ARN)으로 대체

```
"containerDefinitions": [
    {
        "image": "private-repo/private-image",
        "repositoryCredentials": {
            "credentialsParameter": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name"
        }
    }
]
```

**참고**  
프라이빗 레지스트리 인증을 활성화할 수 있는 또 한 가지 방법은 Amazon ECS 컨테이너 에이전트 환경 변수를 사용해 프라이빗 레지스트리를 인증하는 것입니다. 이 방법은 Amazon EC2 인스턴스에서 호스팅되는 태스크에만 지원됩니다. 자세한 내용은 [프라이빗 Docker 이미지를 위한 Amazon ECS 컨테이너 인스턴스 구성](private-auth-container-instances.md) 섹션을 참조하세요.

**프라이빗 레지스트리를 사용하는 방법**

1. 태스크 정의에는 태스크 실행 역할이 있어야 합니다. 컨테이너 에이전트는 이 기능을 통해 컨테이너 이미지를 가져올 수 있습니다. 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.

   프라이빗 레지스트리 인증을 사용하면 Amazon ECS 태스크가 인증 자격 증명이 필요한 AWS 외부의 프라이빗 레지스트리(예: Docker Hub, Quay.io 또는 자체 프라이빗 레지스트리)에서 컨테이너 이미지를 가져올 수 있습니다. 이 기능은 Secrets Manager를 사용하여 레지스트리 자격 증명을 안전하게 저장한 다음, `repositoryCredentials` 파라미터를 사용하여 태스크 정의에서 참조합니다.

   프라이빗 레지스트리 인증 구성에 대한 자세한 내용은 [Amazon ECS에서 AWS 외의 컨테이너 이미지 사용](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth.html)을 참조하세요.

   프라이빗 레지스트리 자격 증명이 포함된 암호에 액세스 권한을 부여하려면 다음 권한을 인라인 정책으로 태스크 실행 역할에 추가합니다. 자세한 정보는 [IAM 정책 추가 및 제거](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) 섹션을 참조하세요.
   + `secretsmanager:GetSecretValue` - Secrets Manager에서 프라이빗 레지스트리 자격 증명을 검색하는 데 필요합니다.
   + `kms:Decrypt` ― 암호가 사용자 지정 KMS 키를 사용하고 기본 키를 사용하지 않는 경우에 필요합니다. 사용자 지정 키의 Amazon 리소스 이름(ARN)을 리소스로 추가해야 합니다.

   다음 예제에서는 인라인 정책이 권한을 추가합니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "kms:Decrypt",
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": [
                   "arn:aws:secretsmanager:us-east-1:111122223333:secret:secret_name",
                   "arn:aws:kms:us-east-1:111122223333:key/key_id"
               ]
           }
       ]
   }
   ```

------

1. AWS Secrets Manager에서 프라이빗 레지스트리 자격 증명에 사용할 암호를 생성합니다. 보안 암호 생성 방법에 대한 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [Create an AWS Secrets Manager secret](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)을 참조하세요.

   다음 형식을 사용하여 프라이빗 레지스트리 자격 증명을 입력합니다.

   ```
   {
     "username" : "privateRegistryUsername",
     "password" : "privateRegistryPassword"
   }
   ```

1. 태스크 정의 등록. 자세한 내용은 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md) 섹션을 참조하세요.

# 컨테이너 재시작 정책이 있는 Amazon ECS 작업의 개별 컨테이너 재시작
<a name="container-restart-policy"></a>

태스크 정의에 정의된 각 필수 및 비필수 컨테이너에 대한 재시작 정책을 사용하여 일시적 장애를 더 빠르게 극복하고 태스크 가용성을 유지할 수 있습니다. 컨테이너의 재시작 정책을 활성화하면 Amazon ECS에서 컨테이너가 종료되면 작업을 교체할 필요 없이 컨테이너를 다시 시작할 수 있습니다.

컨테이너에는 기본적으로 재시작 정책이 활성화되어 있지 않습니다. 컨테이너에 대한 재시작 정책을 활성화하면 컨테이너를 다시 시작하지 않을 종료 코드를 지정할 수 있습니다. 이는 성공을 나타내는 종료 코드일 수 있으며(예: 종료 코드 `0`), 이는 다시 시작할 필요가 없습니다. 컨테이너를 성공적으로 실행해야 재시작을 시도할 수 있는 기간도 지정할 수 있습니다. 이런 파라미터에 대한 자세한 내용은 [재시작 정책](task_definition_parameters.md#container_definition_restart_policy) 섹션을 참조하세요. 이러한 값을 지정하는 작업 정의의 예는 [Amazon ECS 작업 정의에서 컨테이너 재시작 정책 지정](container-restart-policy-example.md) 섹션을 참조하세요.

Amazon ECS 작업 메타데이터 엔드포인트 또는 CloudWatch 컨테이너 인사이트를 사용하여 컨테이너가 재시작된 횟수를 모니터링할 수 있습니다. 태스크 메타데이터 엔드포인트에 관한 자세한 내용은 [Amazon ECS 작업 메타데이터 엔드포인트 버전 4](task-metadata-endpoint-v4.md) 및 [Fargate의 작업에 대한 Amazon ECS 작업 메타데이터 엔드포인트 버전 4](task-metadata-endpoint-v4-fargate.md) 섹션을 참조하세요. Amazon ECS의 Container Insights 지표에 관한 자세한 내용은 *Amazon CloudWatch 사용자 설명서*의 [Amazon ECS Container Insights 지표](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html)를 참조하세요.

컨테이너 재시작 정책은 Fargate, Amazon EC2 인스턴스 및 Amazon ECS Anywhere를 사용하는 외부 인스턴스에서 호스팅되는 태스크에서 지원됩니다.

## 고려 사항
<a name="container-restart-policy-considerations"></a>

컨테이너에 대해 재시작 정책을 활성화하기 전에 다음 사항을 고려합니다.
+ Fargate에서 Windows 컨테이너에는 재시작 정책이 지원되지 않습니다.
+ Amazon EC2 인스턴스에서 호스팅되는 태스크의 경우 이 기능을 사용하려면 버전 `1.86.0` 이상의 컨테이너 에이전트가 있어야 합니다. 그러나 최신 버전의 컨테이너 에이전트를 사용하는 것이 좋습니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 정보는 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.
+ `bridge` 네트워크 모드에서 EC2를 사용하는 경우 FireLens 로그 라우터 컨테이너(컨테이너 정의에 `firelensConfiguration` 객체가 있는 컨테이너)를 다시 시작한 후 애플리케이션 컨테이너의 `FLUENT_HOST` 환경 변수가 부정확해질 수 있습니다. 이는 `FLUENT_HOST`가 동적 IP 주소이며 재시작 후 변경될 수 있기 때문입니다. 애플리케이션 컨테이너에서 `FLUENT_HOST` IP 주소로 직접 로깅하면 주소가 변경된 후 실패하기 시작할 수 있습니다. `FLUENT_HOST`에 대한 자세한 정보는 [높은 처리량을 위한 Amazon ECS 로그 구성](firelens-docker-buffer-limit.md) 섹션을 참조하세요.
+ Amazon ECS 에이전트는 컨테이너 재시작 정책을 처리합니다. 예상치 못한 이유로 Amazon ECS 에이전트가 실패하거나 더 이상 실행되지 않는 경우 컨테이너가 재시작되지 않습니다.
+  정책에 정의된 재시작 시도 기간에 따라 Amazon ECS가 컨테이너를 재시작하기 전에 컨테이너가 실행되어야 하는 시간(초)이 결정됩니다.

# Amazon ECS 작업 정의에서 컨테이너 재시작 정책 지정
<a name="container-restart-policy-example"></a>

작업 정의에서 컨테이너의 재시작 정책을 지정하려면 컨테이너 정의 내에서 `restartPolicy` 객체를 지정합니다. `restartPolicy` 객체에 대한 자세한 정보는 [재시작 정책](task_definition_parameters.md#container_definition_restart_policy) 섹션을 참조하세요.

다음은 웹 서버를 설정하는 Fargate에서 Linux 컨테이너를 사용하는 태스크 정의입니다. 컨테이너 정의에는 `restartPolicy` 객체가 포함되며, 컨테이너의 재시작 정책을 활성화하려면 true로 `enabled`가 설정됩니다. 컨테이너를 180초 동안 실행해야 다시 시작할 수 있으며, 성공했음을 나타내는 종료 코드 `0`과 함께 종료되면 다시 시작되지 않습니다.

```
{
  "containerDefinitions": [
    {
      "command": [
        "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
      ],
      "entryPoint": ["sh", "-c"],
      "essential": true,
      "image": "public.ecr.aws/docker/library/httpd:2.4",
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/fargate-task-definition",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "name": "sample-fargate-app",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
        }
      ],
      "restartPolicy": {
        "enabled": true,
        "ignoredExitCodes": [0],
        "restartAttemptPeriod": 180
      }
    }
  ],
  "cpu": "256",
  "executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
  "family": "fargate-task-definition",
  "memory": "512",
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX"
  },
  "requiresCompatibilities": ["FARGATE"]
}
```

컨테이너 정의에서 `restartPolicy` 객체로 작업 정의를 등록한 후 해당 작업 정의를 사용하여 작업을 실행하거나 서비스를 생성할 수 있습니다. 자세한 내용은 [애플리케이션을 Amazon ECS 태스크로 실행](standalone-task-create.md) 및 [Amazon ECS 롤링 업데이트 배포 생성](create-service-console-v2.md)(을)를 참조하세요.

# Amazon ECS 컨테이너로 민감한 데이터 전달
<a name="specifying-sensitive-data"></a>

데이터베이스의 보안 인증과 같은 중요 데이터를 컨테이너로 안전하게 전달할 수 있습니다.

API 키 및 데이터베이스 보안 인증과 같은 보안 암호는 애플리케이션이 다른 시스템에 액세스하는 데 자주 사용됩니다. 일반적으로 보안 암호는 사용자 이름과 암호, 인증서 또는 API 키로 구성됩니다. 이러한 보안 암호는 IAM을 사용하는 특정 IAM 보안 주체로 액세스를 제한하고 런타임 시 컨테이너에 주입해야 합니다.

AWS Secrets Manager 및 Amazon EC2 Systems Manager Parameter Store에서 컨테이너에 보안 암호를 원활하게 주입할 수 있습니다. 이러한 보안 암호는 작업에서 다음 중 하나로 참조할 수 있습니다.

1. `secrets` 컨테이너 정의 파라미터를 사용하는 환경 변수로 참조합니다.

1. 로깅 플랫폼에 인증이 필요한 경우 `secretOptions`로 참조합니다. 자세한 내용은 [logging configuration options](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html#API_LogConfiguration_Contents)를 참조하세요.

1. 컨테이너가 풀되는 레지스트리에 인증이 필요한 경우 `repositoryCredentials` 컨테이너 정의 파라미터를 사용하여 이미지에 의해 풀되는 보안 암호로 참조합니다. Amazon ECR 퍼블릭 갤러리에서 이미지를 풀할 때 이 방법을 사용합니다. 자세한 내용은 [Private registry authentication for tasks](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth.html)를 참조하세요.

보안 암호 관리를 설정할 때 다음을 수행하는 것이 좋습니다.

## AWS Secrets Manager 또는 AWS Systems Manager Parameter Store를 사용하여 보안 암호 자료 저장
<a name="security-secrets-management-recommendations-storing-secret-materials"></a>

API 키, 데이터베이스 자격 증명 및 기타 보안 암호 자료를 안전하게 Secrets Manager에 저장하거나 Systems Manager Parameter Store에 암호화된 파라미터로 저장해야 합니다. 두 서비스 모두 민감한 데이터를 암호화하는 AWS KMS를 사용하는 관리형 키-값 저장소라는 점에서 유사합니다. 하지만 Secrets Manager는 보안 암호를 자동으로 교체하고, 보안 암호를 무작위로 생성하고, 계정 간에 보안 암호를 공유하는 기능도 포함합니다. 이러한 기능을 활용하려면 Secrets Manager를 사용합니다. 그렇지 않으면 Systems Manager Parameter Store에서 암호화된 파라미터를 사용합니다.

**중요**  
보안 암호가 변경되면 새 배포를 강제로 적용하고 새 작업을 시작하여 최신 보안 암호 값을 검색해야 합니다. 자세한 내용은 다음 항목을 참조하세요.  
태스크 - 태스크를 중지했다가 시작합니다. 자세한 내용은 [Amazon ECS 태스크 중지](standalone-task-stop.md) 및 [애플리케이션을 Amazon ECS 태스크로 실행](standalone-task-create.md)(을)를 참조하세요.
서비스 - 서비스를 업데이트하고 새 배포 강제 적용 옵션을 사용합니다. 자세한 내용은 [Amazon ECS 서비스 업데이트](update-service-console-v2.md) 섹션을 참조하세요.

## 암호화된 Amazon S3 버킷에서 데이터 검색
<a name="security-secrets-management-recommendations-encrypted-s3-buckets"></a>

보안 암호를 암호화된 Amazon S3 버킷에 저장하고 작업 역할을 사용하여 이러한 보안 암호에 대한 액세스를 제한해야 합니다. 이렇게 하면 환경 변수 값이 실수로 로그에 누출되어 `docker inspect`를 실행할 때 표시되는 문제를 방지할 수 있습니다. 이렇게 하는 경우, Amazon S3 버킷에서 보안 암호를 읽도록 애플리케이션을 작성해야 합니다. 자세한 내용은 [Amazon S3 버킷에 대한 기본 서버 측 암호화 동작 설정](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html)을 참조하세요.

## 사이드카 컨테이너를 사용하여 보안 암호를 볼륨에 마운트
<a name="security-secrets-management-recommendations-mount-secret-volumes"></a>

환경 변수를 사용하면 데이터 누출 위험이 높아지므로 보안 암호를 AWS Secrets Manager에서 읽고 공유 볼륨에 쓰는 사이드카 컨테이너를 실행해야 합니다. [Amazon ECS 컨테이너 순서](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDependency.html)를 사용하면 이 컨테이너를 애플리케이션 컨테이너보다 먼저 실행하고 종료할 수 있습니다. 이렇게 하면 이후 애플리케이션 컨테이너는 보안 암호가 기록된 볼륨을 마운트합니다. Amazon S3 버킷 방법과 마찬가지로 공유 볼륨에서 보안 암호를 읽도록 애플리케이션을 작성해야 합니다. 이 볼륨은 범위가 작업으로 지정되므로 작업이 중지되면 자동으로 삭제됩니다. 예제는 [task-def.json](https://github.com/aws-samples/aws-secret-sidecar-injector/blob/master/ecs-task-def/task-def.json) 프로젝트를 참조하세요.

Amazon EC2에서는 보안 암호가 기록되는 볼륨을 AWS KMS 고객 관리형 키로 암호화할 수 있습니다. AWS Fargate에서는 서비스 관리형 키를 사용하여 볼륨 스토리지를 자동으로 암호화합니다.

# 개별 환경 변수를 Amazon ECS 컨테이너로 전달
<a name="taskdef-envfiles"></a>

**중요**  
민감한 데이터는 AWS Secrets Manager 암호 또는 AWS Systems Manager 파라미터 스토어 파라미터에 저장하는 것이 좋습니다. 자세한 내용은 [Amazon ECS 컨테이너로 민감한 데이터 전달](specifying-sensitive-data.md) 섹션을 참조하세요.  
작업 정의에 지정된 환경 변수는 작업 정의에 대해 `DescribeTaskDefinition` 작업이 허용된 모든 사용자 및 역할에서 읽을 수 있습니다.

환경 변수는 다음과 같은 방법으로 컨테이너에 전달할 수 있습니다.
+ `environment` 컨테이너 정의 파라미터를 개별적으로 사용합니다. 이것은 [https://docs.docker.com/reference/cli/docker/container/run/](https://docs.docker.com/reference/cli/docker/container/run/)에 대한 `--env` 옵션에 매핑됩니다.
+ 대량으로 `environmentFiles` 컨테이너 정의 파라미터를 사용하여 환경 변수를 포함하는 하나 이상의 파일을 나열합니다. 파일은 Amazon S3에서 호스팅되어야 합니다. 이것은 [https://docs.docker.com/reference/cli/docker/container/run/](https://docs.docker.com/reference/cli/docker/container/run/)에 대한 `--env-file` 옵션에 매핑됩니다.

다음은 개별 환경 변수를 지정하는 방법을 보여주는 태스크 정의의 조각입니다.

```
{
    "family": "",
    "containerDefinitions": [
        {
            "name": "",
            "image": "",
            ...
            "environment": [
                {
                    "name": "variable",
                    "value": "value"
                }
            ],
            ...
        }
    ],
    ...
}
```

# 환경 변수를 Amazon ECS 컨테이너로 전달
<a name="use-environment-file"></a>

**중요**  
민감한 데이터는 AWS Secrets Manager 암호 또는 AWS Systems Manager 파라미터 스토어 파라미터에 저장하는 것이 좋습니다. 자세한 내용은 [Amazon ECS 컨테이너로 민감한 데이터 전달](specifying-sensitive-data.md) 섹션을 참조하세요.  
환경 변수 파일은 Amazon S3의 객체이며 모든 Amazon S3 보안 고려 사항이 적용됩니다.  
Windows 컨테이너와 Fargate의 Windows 컨테이너에서는 `environmentFiles` 파라미터를 사용할 수 없습니다.

환경 변수 파일을 생성하고 Amazon S3에 저장하여 컨테이너로 환경 변수를 전달할 수 있습니다.

파일에 환경 변수를 지정하여 환경 변수를 대량으로 주입할 수 있습니다. 컨테이너 정의 내에서 환경 변수 파일이 포함된 Amazon S3 버킷 목록을 이용해 `environmentFiles` 객체를 지정합니다.

Amazon ECS는 환경 변수에 크기 제한을 적용하지 않지만 용량이 큰 환경 변수 파일로 인해 디스크 스페이스가 가득 찰 수도 있습니다. 환경 변수 파일을 사용하는 각 태스크는 해당 파일 사본을 디스크에 다운로드합니다. Amazon ECS에서는 작업 정리의 일부로 파일을 제거합니다.

지원되는 환경 변수에 대한 자세한 내용은 [Advanced container definition parameters- Environment](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_environment)를 참조하세요.

컨테이너 정의에서 환경 변수 파일을 지정할 때는 다음 사항을 고려합니다.
+ Amazon EC2에 있는 Amazon ECS 태스크의 경우 이 기능을 사용하기 위해 컨테이너 인스턴스에 버전 `1.39.0` 이상의 컨테이너 에이전트가 필요합니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 정보는 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.
+ AWS Fargate에 있는 Amazon ECS 태스크의 경우 이 기능을 사용하기 위해 플랫폼 버전 `1.4.0` 이상(Linux)을 사용해야 합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.

  변수가 운영 체제 플랫폼에 대해 지원되는지 확인합니다. 자세한 내용은 [컨테이너 정의](task_definition_parameters.md#container_definitions) 및 [기타 태스크 정의 파라미터](task_definition_parameters.md#other_task_definition_params) 단원을 참조하세요.
+ 파일은 `.env` 파일 확장명과 UTF-8 인코딩을 사용해야 합니다.
+ 태스크 실행 역할은 Amazon S3에 대한 추가 권한과 함께 이 기능을 사용해야 합니다. 이렇게 하면 컨테이너 에이전트가 Amazon S3에서 환경 변수 파일을 가져올 수 있습니다. 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.
+ 작업 정의당 파일 수는 10개로 제한됩니다.
+ 환경 파일의 각 줄에는 `VARIABLE=VALUE` 형식의 환경 변수를 포함합니다. 공백이나 인용 부호는 Amazon ECS 파일 값의 일부로 **포함됩니다**. `#`으로 시작하는 줄은 주석으로 처리되며 무시됩니다. 환경 변수 파일 구문에 대한 자세한 내용은 Docker 설명서의 [환경 변수 설정(-e, --env, --env-file)](https://docs.docker.com/reference/cli/docker/container/run/#env)을 참조하세요.

  다음은 적절한 구문입니다.

  ```
  #This is a comment and will be ignored
  VARIABLE=VALUE
  ENVIRONMENT=PRODUCTION
  ```
+ 컨테이너 정의에서 `environment` 파라미터를 사용하여 지정된 환경 변수가 있는 경우 환경 파일 내에 포함된 변수보다 우선합니다.
+ 여러 환경 파일이 지정되고 동일한 변수를 포함하는 경우 입력 순서대로 처리됩니다. 즉, 변수의 첫 번째 값이 사용되고 중복 변수의 후속 값은 무시됩니다. 고유한 변수 이름을 사용하는 것이 좋습니다.
+ 환경 파일이 컨테이너 재정의로 지정된 경우 해당 파일이 사용됩니다. 또한 컨테이너 정의에 지정된 다른 환경 파일은 무시됩니다.
+ Fargate에는 다음 규칙이 적용됩니다.
  + 파일은 네이티브 Docker env 파일과 유사하게 처리됩니다.
  + 비어 있는 상태로 Amazon S3에 저장된 환경 변수를 참조하는 컨테이너 정의는 컨테이너에 표시되지 않습니다.
  + 셸 이스케이프 처리는 지원되지 않습니다.
  + 컨테이너 진입점은 `VARIABLE` 값을 해석합니다.

## 예제
<a name="environment-file-example"></a>

다음은 환경 변수 파일을 지정하는 방법을 보여주는 태스크 정의의 조각입니다.

```
{
    "family": "",
    "containerDefinitions": [
        {
            "name": "",
            "image": "",
            ...
            "environmentFiles": [
                {
                    "value": "arn:aws:s3:::amzn-s3-demo-bucket/envfile_object_name.env",
                    "type": "s3"
                }
            ],
            ...
        }
    ],
    ...
}
```

# Amazon ECS에서 프로그래밍 방식으로 Secrets Manager 보안 암호 전달
<a name="secrets-app-secrets-manager"></a>

애플리케이션에서 민감한 정보를 일반 텍스트로 하드 코딩하는 대신, Secrets Manager를 사용하여 민감한 데이터를 저장할 수 있습니다.

중요 데이터를 검색할 때 이 방법을 권장하는 이유는 이후에 Secrets Manager 보안 암호가 업데이트되면 애플리케이션이 자동으로 최신 버전의 보안 암호를 검색하기 때문입니다.

Secrets Manager에서 보안 암호를 생성합니다. Secrets Manager 보안 암호를 생성한 후 애플리케이션 코드를 업데이트하여 보안 암호를 검색하세요.

Secrets Manager에서 중요 데이터를 보호하기 전에 다음 고려 사항을 검토하세요.
+ [CreateSecret](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_CreateSecret.html) API의 `SecretString` 파라미터로 생성된 암호이며 텍스트 데이터를 저장하는 암호만이 지원됩니다. 이진 데이터를 저장하는 보안 암호([CreateSecret](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_CreateSecret.html) API의 `SecretBinary` 파라미터로 생성된 보안 암호임)는 지원되지 않습니다.
+ 인터페이스 VPC 엔드포인트를 사용하여 보안 제어를 강화합니다. Secrets Manager용 인터페이스 VPC 엔드포인트를 생성해야 합니다. VPC 엔드포인트에 대한 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [VPC 종단점 생성](https://docs.aws.amazon.com/secretsmanager/latest/userguide/setup-create-vpc.html)을 참조하세요.
+ 작업에서 사용하는 VPC는 DNS 확인을 사용해야 합니다.
+ 태스크 정의에서 Secrets Manager에 대한 추가 권한을 보유한 태스크 역할을 사용해야 합니다. 자세한 내용은 [Amazon ECS 작업 IAM 역할](task-iam-roles.md) 섹션을 참조하세요.

## Secrets Manager 보안 암호 생성
<a name="secrets-app-secrets-manager-create-secret"></a>

Secrets Manager 콘솔을 사용하여 민감한 데이터에 대한 암호를 생성할 수 있습니다. 보안 암호 생성 방법에 대한 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [AWS Secrets Manager 보안 암호 생성](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)을 참조하세요.

## 애플리케이션을 업데이트하여 프로그래밍 방식으로 Secrets Manager 보안 암호 검색
<a name="secrets-app-secrets-manager-update-app"></a>

애플리케이션에서 직접 Secrets Manager API를 호출하여 보안 암호를 검색할 수 있습니다. 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [Retrieve secrets from AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html)를 참조하세요.

AWS Secrets Manager에 저장된 민감한 데이터를 검색하려면 *AWS SDK 코드 예제 코드 라이브러리*의 [Code examples for AWS Secrets Manager using AWS SDKs](https://docs.aws.amazon.com/code-library/latest/ug/secrets-manager_code_examples.html)를 참조하세요.

# Amazon ECS에서 프로그래밍 방식으로 Systems Manager Parameter Store 보안 암호 전달
<a name="secrets-app-ssm-paramstore"></a>

Systems Manager Parameter Store는 보안 저장 및 보안 암호 관리 기능을 제공합니다. 애플리케이션에 이 정보를 하드 코딩하는 대신 암호, 데이터베이스 문자열, EC2 인스턴스 ID, AMI ID, 라이선스 코드와 같은 데이터를 파라미터 값으로 저장할 수 있습니다. 값을 일반 텍스트 또는 암호화된 데이터로 저장할 수 있습니다.

민감한 데이터를 검색할 때 이 방법을 권장하는 이유는 이후에 Secrets Manager Parameter Store 파라미터가 업데이트되면 애플리케이션이 자동으로 최신 버전을 검색하기 때문입니다.

Systems Manager Parameter Store에서 중요 데이터를 보호하기 전에 다음 고려 사항을 검토하세요.
+ 텍스트 데이터를 저장하는 보안 암호만 지원됩니다. 이진 데이터를 저장하는 보안 암호는 지원되지 않습니다.
+ 인터페이스 VPC 엔드포인트를 사용하여 보안 제어를 강화합니다.
+ 작업에서 사용하는 VPC는 DNS 확인을 사용해야 합니다.
+ EC2를 사용하는 태스크의 경우 이 기능을 사용하려면 Amazon ECS 에이전트 구성 변수인 `ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE=true`를 사용해야 합니다. 컨테이너 인스턴스를 생성할 때 이를 `/etc/ecs/ecs.config` 파일에 추가하거나 기존 인스턴스에 추가한 다음 ECS 에이전트를 다시 시작할 수 있습니다. 자세한 내용은 [Amazon ECS 컨테이너 에이전트 구성](ecs-agent-config.md) 섹션을 참조하세요.
+ 태스크 정의에서 Systems Manager Parameter Store에 대한 추가 권한을 보유한 태스크 역할을 사용해야 합니다. 자세한 내용은 [Amazon ECS 작업 IAM 역할](task-iam-roles.md) 섹션을 참조하세요.

## 파라미터 생성
<a name="secrets-app-ssm-paramstore-create-secret"></a>

Systems Manager 콘솔을 사용하면 중요 데이터에 대한 Systems Manager Parameter Store 파라미터를 생성할 수 있습니다. 자세한 내용은 *AWS Systems Manager 사용 설명서*의 [Systems Manager 파라미터 생성(콘솔)](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-create-console.html) 또는 [Systems Manager 파라미터 생성(AWS CLI)](https://docs.aws.amazon.com/systems-manager/latest/userguide/param-create-cli.html)을 참조하세요.

## 애플리케이션을 업데이트하여 프로그래밍 방식으로 Systems Manager Parameter Store 보안 암호 검색
<a name="secrets-app-ssm-paramstore-update-app"></a>

Systems Manager Parameter Store 파라미터에 저장된 민감한 데이터를 검색하려면 *AWS SDK 코드 예제 코드 라이브러리*의 [Code examples for Systems Manager using AWS SDKs](https://docs.aws.amazon.com/code-library/latest/ug/ssm_code_examples.html)를 참조하세요.

# Amazon ECS 환경 변수를 통해 Secrets Manager 보안 암호 전달
<a name="secrets-envvar-secrets-manager"></a>

암호를 환경 변수로 주입하는 경우 암호의 전체 내용, 암호 내 특정 JSON 키를 지정할 수 있습니다. 이는 컨테이너에 노출되는 민감한 데이터를 제어하는 데 도움이 됩니다. 암호 버전 관리에 대한 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [Secrets Manager에는 무엇이 있습니까?](https://docs.aws.amazon.com/secretsmanager/latest/userguide/whats-in-a-secret.html#term_version)를 참조하세요.

환경 변수를 사용하여 컨테이너에 Secrets Manager 보안 암호를 삽입할 때 다음을 고려해야 합니다.
+ 컨테이너가 처음 시작될 때 해당 컨테이너에 중요한 정보가 주입됩니다. 암호가 이후에 업데이트되거나 교체되면 컨테이너가 업데이트된 값을 자동으로 받지 않습니다. 새 태스크를 시작해야 하거나 작업이 서비스의 일부인 경우 서비스를 업데이트하고 **새 배포 강제 적용**을 사용하여 서비스에서 새 태스크를 시작하도록 강제로 지정할 수 있습니다.
+ 컨테이너에서 실행되는 애플리케이션, 컨테이너 로그 및 디버깅 도구는 환경 변수에 액세스할 수 있습니다.
+ AWS Fargate에서의 Amazon ECS 태스크의 경우 다음 사항을 고려합니다.
  + 암호의 전체 내용을 환경 변수 또는 로그 구성으로 주입하려면 플랫폼 버전 `1.3.0` 이상을 사용해야 합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.
  + 암호의 JSON 키 또는 버전을 환경 변수 또는 로그 구성으로 주입하려면 플랫폼 버전 `1.4.0` 이상(Linux) 또는 `1.0.0`(Windows)을 사용해야 합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.
+ EC2에서의 Amazon ECS 태스크의 경우 다음 사항을 고려해야 합니다.
  + 암호의 특정 JSON 키 또는 버전을 사용하여 암호를 주입하려면 컨테이너 인스턴스에 컨테이너 에이전트 버전 `1.37.0` 이상이 있어야 합니다. 그러나 최신 버전의 컨테이너 에이전트를 사용하는 것이 좋습니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 내용은 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.

    암호의 전체 내용을 환경 변수로 주입하거나 로그 구성에 암호를 주입하려면 컨테이너 인스턴스에 컨테이너 에이전트 버전 `1.22.0` 이상이 있어야 합니다.
+ 인터페이스 VPC 엔드포인트를 사용하여 보안 제어를 향상하고 프라이빗 서브넷을 통해 Secrets Manager에 연결합니다. Secrets Manager용 인터페이스 VPC 엔드포인트를 생성해야 합니다. VPC 엔드포인트에 대한 자세한 내용은 *AWS Secrets Manager 사용 설명서*의 [VPC 종단점 생성](https://docs.aws.amazon.com/secretsmanager/latest/userguide/setup-create-vpc.html)을 참조하세요. Secrets Manager 및 Amazon VPC 사용에 대한 자세한 내용은 [How to connect to Secrets Manager service within a Amazon VPC](https://aws.amazon.com/blogs//security/how-to-connect-to-aws-secrets-manager-service-within-a-virtual-private-cloud/)를 참조하세요.
+ `awslogs` 로깅 드라이버를 사용하도록 구성된 Windows 태스크의 경우 컨테이너 인스턴스에 `ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE` 환경 변수도 설정해야 합니다. 다음 구문을 사용합니다.

  ```
  <powershell>
  [Environment]::SetEnvironmentVariable("ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE", $TRUE, "Machine")
  Initialize-ECSAgent -Cluster <cluster name> -EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]'
  </powershell>
  ```
+ 태스크 정의에서 Secrets Manager에 대한 추가 권한을 보유한 작업 실행 역할을 사용해야 합니다. 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.

## AWS Secrets Manager 보안 암호 생성
<a name="secrets-envvar-secrets-manager-create-secret"></a>

Secrets Manager 콘솔을 사용하여 민감한 데이터에 대한 암호를 생성할 수 있습니다. 자세한 정보는 *AWS Secrets Manager 사용 설명서*의 [AWS Secrets Manager 보안 암호 생성](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)을 참조하세요.

## 컨테이너 정의에 환경 변수 추가
<a name="secrets-envvar-secrets-manager-update-container-definition"></a>

컨테이너 정의 내에서 다음을 지정할 수 있습니다.
+ 컨테이너에 설정할 환경 변수의 이름을 포함하는 `secrets` 객체
+ Secrets Manager 암호의 Amazon 리소스 이름(ARN)
+ 컨테이너에 제공할 중요한 데이터를 포함하는 추가 파라미터

다음 예제에서는 Secrets Manager 암호에 대해 지정해야 하는 전체 구문을 보여 줍니다.

```
arn:aws:secretsmanager:region:aws_account_id:secret:secret-name:json-key:version-stage:version-id
```

다음 섹션에서는 추가 파라미터에 대해 설명합니다. 이러한 파라미터는 선택 사항이지만 사용하지 않는 경우 기본값을 사용하려면 콜론(`:`)을 포함시켜야 합니다. 추가 컨텍스트에 대한 예제가 아래에 나와 있습니다.

`json-key`  
환경 변수 값으로 설정할 값과 함께 키-값 쌍의 키 이름을 지정합니다. JSON 형식의 값만 지원됩니다. JSON 키를 지정하지 않으면 암호의 전체 내용이 사용됩니다.

`version-stage`  
사용할 암호 버전의 스테이징 레이블을 지정합니다. 버전 스테이징 레이블이 지정된 경우 버전 ID를 지정할 수 없습니다. 버전 단계가 지정되지 않은 경우 기본 동작은 `AWSCURRENT` 스테이징 레이블을 사용하여 암호를 검색하는 것입니다.  
스테이징 레이블은 암호가 업데이트되거나 교체되는 경우 암호의 여러 버전을 추적하는 데 사용됩니다. 암호의 각 버전에는 하나 이상의 스테이징 레이블과 ID가 있습니다.

`version-id`  
사용하고자 하는 암호 버전의 고유 식별자를 지정합니다. 버전 ID가 지정된 경우 버전 스테이징 레이블을 지정할 수 없습니다. 버전 ID가 지정되지 않은 경우 기본 동작은 `AWSCURRENT` 스테이징 레이블을 사용하여 암호를 검색하는 것입니다.  
버전 ID는 암호가 업데이트되거나 교체되는 경우 암호의 여러 버전을 추적하는 데 사용됩니다. 암호의 각 버전에는 ID가 있습니다. 자세한 정보는 *AWS Secrets Manager 사용 설명서*의 [AWS Secrets Manager의 주요 개념 및 용어](https://docs.aws.amazon.com/secretsmanager/latest/userguide/terms-concepts.html#term_secret)를 참조하세요.

### 컨테이너 정의 예제
<a name="secrets-examples"></a>

다음 예제에서는 컨테이너 정의에서 Secretes Manager 암호를 참조할 수 있는 방법을 보여 줍니다.

**Example 전체 암호 참조**  
다음은 Secret Manager 암호의 전체 텍스트를 참조할 때 형식을 나타내는 태스크 정의의 조각입니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-AbCdEf"
    }]
  }]
}
```
컨테이너 내에서 이 보안 암호의 값에 액세스하려면 `$environment_variable_name` 변수를 호출해야 합니다.

**Example 전체 시크릿 참조**  
다음은 여러 Secret Manager 시크릿의 전체 텍스트를 참조할 때 형식을 나타내는 태스크 정의의 조각입니다.  

```
{
  "containerDefinitions": [{
     "secrets": [
      {
        "name": "environment_variable_name1",
         "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-AbCdEf"
      },
      {
        "name": "environment_variable_name2",
         "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-abcdef"
      },
      {
        "name": "environment_variable_name3",
        "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-ABCDEF"
      }
    ]
  }]
}
```
컨테이너 내에서 이 시크릿의 값에 액세스하려면 `$environment_variable_name1`, `$environment_variable_name2`, `$environment_variable_name3`을 직접적으로 호출해야 합니다.

**Example 암호 내에서 특정 키 참조**  
다음은 암호의 내용을 관련 버전 스테이징 레이블 및 버전 ID와 함께 표시하는 [get-secret-value](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/get-secret-value.html) 명령의 출력 예를 보여 줍니다.  

```
{
    "ARN": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf",
    "Name": "appauthexample",
    "VersionId": "871d9eca-18aa-46a9-8785-981ddEXAMPLE",
    "SecretString": "{\"username1\":\"password1\",\"username2\":\"password2\",\"username3\":\"password3\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1581968848.921
}
```
ARN 끝에 키 이름을 지정하여 컨테이너 정의에서 이전 출력의 특정 키를 참조합니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1::"
    }]
  }]
}
```

**Example 특정 비밀 버전 참조**  
다음은 암호의 암호화되지 않은 내용을 모든 버전의 암호에 대한 메타데이터와 함께 표시하는 [describe-secret](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/describe-secret.html) 명령의 출력 예입니다.  

```
{
    "ARN": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf",
    "Name": "appauthexample",
    "Description": "Example of a secret containing application authorization data.",
    "RotationEnabled": false,
    "LastChangedDate": 1581968848.926,
    "LastAccessedDate": 1581897600.0,
    "Tags": [],
    "VersionIdsToStages": {
        "871d9eca-18aa-46a9-8785-981ddEXAMPLE": [
            "AWSCURRENT"
        ],
        "9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE": [
            "AWSPREVIOUS"
        ]
    }
}
```
ARN 끝에 키 이름을 지정하여 컨테이너 정의에서 이전 출력의 특정 버전 스테이징 레이블을 참조합니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf::AWSPREVIOUS:"
    }]
  }]
}
```
ARN 끝에 키 이름을 지정하여 컨테이너 정의에서 이전 출력의 특정 버전 ID를 참조합니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:::9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE"
    }]
  }]
}
```

**Example 암호의 특정 키 및 버전 스테이징 레이블 참조**  
다음은 암호 내 특정 키와 특정 버전 스테이징 레이블을 모두 참조하는 방법을 보여줍니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1:AWSPREVIOUS:"
    }]
  }]
}
```
특정 키 및 버전 ID를 지정하려면 다음 구문을 사용합니다.  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1::9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE"
    }]
  }]
}
```

환경 변수에 지정된 보안 암호를 사용하여 태스크 정의를 생성하는 방법에 대한 자세한 내용은 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md) 섹션을 참조하세요.

# Amazon ECS 환경 변수를 통해 Systems Manager 파라미터 전달
<a name="secrets-envvar-ssm-paramstore"></a>

Amazon ECS를 사용하면 AWS Systems Manager Parameter Store 파라미터에 민감한 데이터를 저장한 후 컨테이너 정의에서 참조하여 컨테이너에 민감한 데이터를 주입할 수 있습니다.

환경 변수를 사용하여 Systems Manager 보안 암호를 컨테이너에 주입할 때 다음을 고려하세요.
+ 컨테이너가 처음 시작될 때 해당 컨테이너에 중요한 정보가 주입됩니다. 암호가 이후에 업데이트되거나 교체되면 컨테이너가 업데이트된 값을 자동으로 받지 않습니다. 새 태스크를 시작해야 하거나 작업이 서비스의 일부인 경우 서비스를 업데이트하고 **새 배포 강제 적용**을 사용하여 서비스에서 새 태스크를 시작하도록 강제로 지정할 수 있습니다.
+ AWS Fargate에서의 Amazon ECS 태스크의 경우 다음 사항을 고려해야 합니다.
  + 암호의 전체 내용을 환경 변수 또는 로그 구성으로 주입하려면 플랫폼 버전 `1.3.0` 이상을 사용해야 합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.
  + 암호의 JSON 키 또는 버전을 환경 변수 또는 로그 구성으로 주입하려면 플랫폼 버전 `1.4.0` 이상(Linux) 또는 `1.0.0`(Windows)을 사용해야 합니다. 자세한 내용은 [Amazon ECS에 대한 Fargate 플랫폼 버전](platform-fargate.md) 섹션을 참조하세요.
+ EC2에서의 Amazon ECS 태스크의 경우 다음 사항을 고려해야 합니다.
  + 암호의 특정 JSON 키 또는 버전을 사용하여 암호를 주입하려면 컨테이너 인스턴스에 컨테이너 에이전트 버전 `1.37.0` 이상이 있어야 합니다. 그러나 최신 버전의 컨테이너 에이전트를 사용하는 것이 좋습니다. 에이전트 버전을 확인하고 최신 버전으로 업데이트하는 방법에 대한 자세한 내용은 [Amazon ECS 컨테이너 에이전트 업데이트](ecs-agent-update.md) 섹션을 참조하세요.

    암호의 전체 내용을 환경 변수로 주입하거나 로그 구성에 암호를 주입하려면 컨테이너 인스턴스에 컨테이너 에이전트 버전 `1.22.0` 이상이 있어야 합니다.
+ 인터페이스 VPC 엔드포인트를 사용하여 보안 제어를 강화합니다. Systems Manager용 인터페이스 VPC 엔드포인트를 생성해야 합니다. VPC 엔드포인트에 대한 자세한 내용은 *AWS Systems Manager 사용 설명서*의 [Systems Manager용 VPC 엔드포인트를 사용하여 EC2 인스턴스의 보안 개선](https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-create-vpc.html)을 참조하세요.
+ 태스크 정의에서는 Systems Manager Parameter Store에 대한 추가 권한을 보유한 태스크 실행 역할을 사용해야 합니다. 자세한 내용은 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.
+ `awslogs` 로깅 드라이버를 사용하도록 구성된 Windows 태스크의 경우 컨테이너 인스턴스에 `ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE` 환경 변수도 설정해야 합니다. 다음 구문을 사용합니다.

  ```
  <powershell>
  [Environment]::SetEnvironmentVariable("ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE", $TRUE, "Machine")
  Initialize-ECSAgent -Cluster <cluster name> -EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]'
  </powershell>
  ```

## Systems Manager 파라미터 생성
<a name="secrets-envvar-ssm-paramstore-create-parameter"></a>

Systems Manager 콘솔을 사용하면 중요 데이터에 대한 Systems Manager Parameter Store 파라미터를 생성할 수 있습니다. 자세한 내용은 **AWS Systems Manager 사용 설명서의 [Systems Manager 파라미터 생성(콘솔)](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-create-console.html) 또는 [Systems Manager 파라미터 생성(AWS CLI)](https://docs.aws.amazon.com/systems-manager/latest/userguide/param-create-cli.html)을 참조하세요.

## 컨테이너 정의에 환경 변수 추가
<a name="secrets-ssm-paramstore-update-container-definition"></a>

태스크 정의의 컨테이너 정의 내에서 컨테이너에 설정할 환경 변수의 이름으로 `secrets`를 지정하여 컨테이너에 제공할 민감한 데이터가 들어있는 Systems Manager Parameter Store 파라미터의 전체 ARN을 지정합니다. 자세한 내용은 [secrets](task_definition_parameters.md#ContainerDefinition-secrets) 섹션을 참조하세요.

다음은 Systems Manager 파라미터 스토어 파라미터를 참조할 때 형식을 나타내는 태스크 정의의 조각입니다. Systems Manager 파라미터 스토어 파라미터가 현재 실행 중인 태스크와 동일한 리전에 있는 경우, 파라미터의 전체 ARN 또는 이름을 사용할 수 있습니다. 파라미터가 다른 리전에 있다면 전체 ARN을 지정합니다.

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:ssm:region:aws_account_id:parameter/parameter_name"
    }]
  }]
}
```

환경 변수에 지정된 보안 암호를 사용하여 태스크 정의를 생성하는 방법에 대한 자세한 내용은 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md) 섹션을 참조하세요.

## 애플리케이션을 업데이트하여 프로그래밍 방식으로 Systems Manager Parameter Store 보안 암호 검색
<a name="secrets-ssm-paramstore-update-app"></a>

Systems Manager Parameter Store 파라미터에 저장된 민감한 데이터를 검색하려면 *AWS SDK 코드 예제 코드 라이브러리*의 [Code examples for Systems Manager using AWS SDKs](https://docs.aws.amazon.com/code-library/latest/ug/ssm_code_examples.html)를 참조하세요.

# Amazon ECS 로깅 구성에 대한 보안 암호 전달
<a name="secrets-logconfig"></a>

`logConfiguration`에서 `secretOptions` 파라미터를 사용하여 로깅에 사용되는 민감한 데이터를 전달할 수 있습니다.

Secrets Manager 또는 Systems Manager에 보안 암호를 저장할 수 있습니다.

## Secrets Manager 사용
<a name="secrets-logconfig-secrets-manager"></a>

컨테이너 정의 내에서, `logConfiguration`을 지정할 때 컨테이너에 설정할 로그 드라이버 옵션의 이름과 컨테이너에 제공할 민감한 데이터가 들어있는 Secret Manager 암호의 전체 ARN을 사용하여 `secretOptions`를 지정할 수 있습니다. 시크릿 생성에 대한 자세한 내용은 [Create an AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)를 참조하세요.

다음은 Secrets Manager 암호를 참조할 때 형식을 나타내는 태스크 태스크의 조각입니다.

```
{
  "containerDefinitions": [{
    "logConfiguration": [{
      "logDriver": "splunk",
      "options": {
        "splunk-url": "https://your_splunk_instance:8088"
      },
      "secretOptions": [{
        "name": "splunk-token",
        "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-AbCdEf"
      }]
    }]
  }]
}
```

## 컨테이너 정의에 환경 변수 추가
<a name="secrets-envvar-ssm-paramstore-update-container-definition"></a>

컨테이너 정의 내에서 컨테이너에 설정할 환경 변수의 이름으로 `secrets`(을)를 지정하여 컨테이너에 제공할 민감한 데이터가 들어있는 Systems Manager 파라미터 스토어 파라미터의 전체 ARN을 지정합니다. 자세한 내용은 [secrets](task_definition_parameters.md#ContainerDefinition-secrets) 섹션을 참조하세요.

다음은 Systems Manager 파라미터 스토어 파라미터를 참조할 때 형식을 나타내는 태스크 정의의 조각입니다. Systems Manager 파라미터 스토어 파라미터가 현재 실행 중인 태스크와 동일한 리전에 있는 경우, 파라미터의 전체 ARN 또는 이름을 사용할 수 있습니다. 파라미터가 다른 리전에 있다면 전체 ARN을 지정합니다.

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:ssm:region:aws_account_id:parameter/parameter_name"
    }]
  }]
}
```

환경 변수에 지정된 보안 암호를 사용하여 태스크 정의를 생성하는 방법에 대한 자세한 내용은 [콘솔을 사용하여 Amazon ECS 작업 정의 생성](create-task-definition.md) 섹션을 참조하세요.

## Systems Manager 사용
<a name="secrets-logconfig-ssm-paramstore"></a>

로그 구성에 중요 데이터를 삽입할 수 있습니다. 컨테이너 정의 내에서, `logConfiguration`을 정의할 때 컨테이너에 설정할 로그 드라이버 옵션의 이름과 컨테이너에 제공할 민감한 데이터가 들어있는 Systems Manager 파라미터 스토어 파라미터의 전체 ARN을 사용하여 `secretOptions`를 지정할 수 있습니다.

**중요**  
Systems Manager 파라미터 스토어 파라미터가 현재 실행 중인 태스크와 동일한 리전에 있는 경우, 파라미터의 전체 ARN 또는 이름을 사용할 수 있습니다. 파라미터가 다른 리전에 있다면 전체 ARN을 지정합니다.

다음은 Systems Manager 파라미터 스토어 파라미터를 참조할 때 형식을 나타내는 태스크 정의의 조각입니다.

```
{
  "containerDefinitions": [{
    "logConfiguration": [{
      "logDriver": "fluentd",
      "options": {
        "tag": "fluentd demo"
      },
      "secretOptions": [{
        "name": "fluentd-address",
        "valueFrom": "arn:aws:ssm:region:aws_account_id:parameter:/parameter_name"
      }]
    }]
  }]
}
```

# Amazon ECS에서 Secrets Manager 암호를 사용하여 민감한 데이터 지정
<a name="specifying-sensitive-data-tutorial"></a>

Amazon ECS에서는 AWS Secrets Manager 암호에 민감한 데이터를 저장하고 컨테이너 정의에서 참조하는 방식으로 컨테이너에 민감한 데이터를 삽입할 수 있습니다. 자세한 내용은 [Amazon ECS 컨테이너로 민감한 데이터 전달](specifying-sensitive-data.md) 섹션을 참조하세요.

Secrets Manager 보안 암호를 생성하고, Amazon ECS 태스크 정의에서 보안 암호를 참조한 다음, 보안 암호 내용을 표시하는 컨테이너 내부의 환경 변수를 쿼리하여 작동하는지 확인하는 방법을 알아보세요.

## 사전 조건
<a name="specifying-sensitive-data-tutorial-prereqs"></a>

이 자습서에서는 다음 사전 조건이 충족되었다고 가정합니다.
+ [Amazon ECS 사용 설정](get-set-up-for-amazon-ecs.md)의 단계가 완료되었습니다.
+ 사용자에게는 Secrets Manager 및 Amazon ECS 리소스를 생성하는 데 필요한 IAM 권한이 있습니다.

## 1단계: Secrets Manager 보안 암호 생성
<a name="specifying-sensitive-data-tutorial-create-secret"></a>

Secrets Manager 콘솔을 사용하여 민감한 데이터에 대한 암호를 생성할 수 있습니다. 이 자습서에서는 이후 컨테이너에서 참조할 기본 사용자 이름 및 암호를 저장하는 기본 보안을 생성합니다. 자세한 정보는 *AWS Secrets Manager 사용 설명서*의 [AWS Secrets Manager 보안 암호 생성](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)을 참조하세요.

**이 보안 암호에 저장되는 키/값 페어**는 자습서 마지막에 있는 컨테이너의 환경 변수 값입니다.

**Secret ARN**(보안 암호 ARN)을 저장하여 이후 단계의 작업 실행 IAM 정책 및 작업 정의에 참조합니다.

## 2단계: 태스크 실행 역할에 보안 암호 권한 추가
<a name="specifying-sensitive-data-tutorial-update-iam"></a>

Amazon ECS가 Secrets Manager 보안 암호에서 민감한 데이터를 가져오려면 작업 실행 역할에 대한 보안 암호 권한을 보유해야 합니다. 자세한 내용은 [Secrets Manager 또는 Systems Manager 권한](task_execution_IAM_role.md#task-execution-secrets) 섹션을 참조하세요.

## 3단계: 태스크 정의 생성
<a name="specifying-sensitive-data-tutorial-create-taskdef"></a>

Amazon ECS 콘솔을 사용하면 Secrets Manager 암호를 참조하는 태스크 정의를 생성할 수 있습니다.

**암호를 지정하는 태스크 정의를 생성하려면**

IAM 콘솔을 사용해 작업 실행 역할에 필요한 권한을 업데이트합니다.

1. [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2)에서 콘솔을 엽니다.

1. 탐색 창에서 **작업 정의**를 선택합니다.

1. **새 태스크 정의 생성(Create new task definition)**, **JSON으로 새 태스크 정의 생성(Create new task definition with JSON)**을 선택합니다.

1. JSON 편집기 상자에 다음 태스크 정의 JSON 문자열을 입력하여 1단계에서 생성한 Secrets Manager 보안 암호의 전체 ARN과 2단계에서 업데이트한 작업 실행 역할을 지정했는지 확인합니다. **저장**을 선택합니다.

1. 

   ```
   {
       "executionRoleArn": "arn:aws:iam::aws_account_id:role/ecsTaskExecutionRole",
       "containerDefinitions": [
           {
               "entryPoint": [
                   "sh",
                   "-c"
               ],
               "portMappings": [
                   {
                       "hostPort": 80,
                       "protocol": "tcp",
                       "containerPort": 80
                   }
               ],
               "command": [
                   "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
               ],
               "cpu": 10,
               "secrets": [
                   {
                       "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:username_value",
                       "name": "username_value"
                   }
               ],
               "memory": 300,
               "image": "public.ecr.aws/docker/library/httpd:2.4",
               "essential": true,
               "name": "ecs-secrets-container"
           }
       ],
       "family": "ecs-secrets-tutorial"
   }
   ```

1. **생성(Create)**을 선택합니다.

## 4단계: 클러스터 생성
<a name="specifying-sensitive-data-tutorial-create-cluster"></a>

Amazon ECS 콘솔을 사용해 태스크를 실행할 컨테이너 인스턴스가 있는 클러스터를 생성합니다. 기존 클러스터에 자습서를 위한 태스크 정의 인스턴스를 실행할 수 있는 가용 리소스가 있는 컨테이너 인스턴스가 적어도 하나 등록된 경우에는 다음 단계로 이동합니다.

이 자습서에서는 Amazon ECS 최적화 Amazon Linux 2 AMI를 사용하여 하나의 `t2.micro` 컨테이너 인스턴스로 클러스터를 생성합니다.

EC2에 대한 클러스터를 생성하는 방법에 대한 자세한 내용은 [Amazon EC2 워크로드에 대한 Amazon ECS 클러스터 생성](create-ec2-cluster-console-v2.md) 섹션을 참조하세요.

## 5단계: 태스크 실행
<a name="specifying-sensitive-data-tutorial-run-task"></a>

Amazon ECS 콘솔을 사용해 생성한 태스크 정의로 태스크를 실행할 수 있습니다. 이 자습서에서는 이전 단계에서 생성한 클러스터에서 EC2를 사용해 태스크를 실행합니다.

작업을 실행하는 방법에 대한 정보는 [애플리케이션을 Amazon ECS 태스크로 실행](standalone-task-create.md) 섹션을 참조하세요.

## 6단계: 확인
<a name="specifying-sensitive-data-tutorial-verify"></a>

모든 단계가 성공적으로 완료되었으며 다음 단계를 따라 컨테이너 내에서 생성한 환경 변수가 잘 생성되었는지 확인합니다.

**생성한 환경 변수 확인**

1. 컨테이너 인스턴스의 퍼블릭 IP 또는 DNS 주소를 찾습니다.

   1. [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2)에서 콘솔을 엽니다.

   1. 탐색 창에서 **클러스터**를 선택한 다음, 생성한 클러스터를 선택합니다.

   1. **Infrastructure**(인프라)를 선택한 다음 컨테이너 인스턴스를 선택합니다.

   1. 인스턴스로 인스턴스의 **Public IP**(퍼블릭 IP) 또는 **Public DNS**(퍼블릭 DNS)를 기록합니다.

1. Mac OS 또는 Linux 컴퓨터를 사용 중인 경우, 다음 명령을 사용하여 인스턴스에 연결해 프라이빗 키 경로와 인스턴스의 퍼블릭 주소를 대체합니다.

   ```
   $ ssh -i /path/to/my-key-pair.pem ec2-user@ec2-198-51-100-1.compute-1.amazonaws.com
   ```

   Windows 컴퓨터 사용에 대한 자세한 내용은 *Amazon EC2 사용 설명서*의 [PuTTY를 사용하여 Linux 인스턴스에 연결](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-linux-inst-from-windows.html)을 참조하세요.
**중요**  
인스턴스 연결 문제에 대한 자세한 내용은 **Amazon EC2 사용 설명서의 [인스턴스에 연결 문제 해결](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html)을 참조하세요.

1. 인스턴스에서 실행되는 컨테이너 목록을 표시합니다. `ecs-secrets-tutorial` 컨테이너의 컨테이너 ID를 기록합니다.

   ```
   docker ps
   ```

1. 이전 단계의 결과로 얻은 컨테이너 ID를 사용해 `ecs-secrets-tutorial` 컨테이너에 연결합니다.

   ```
   docker exec -it container_ID /bin/bash
   ```

1. `echo` 명령을 사용해 환경 변수 값을 프린트합니다.

   ```
   echo $username_value
   ```

   자습서가 성공했다면 다음 결과가 표시되어야 합니다.

   ```
   password_value
   ```
**참고**  
또한 `env`(또는 `printenv`) 명령을 사용해 컨테이너 내의 모든 환경 변수 목록을 표시할 수 있습니다.

## 7단계: 정리
<a name="specifying-sensitive-data-tutorial-cleanup"></a>

이 자습서로 완료를 한 후에 사용하지 않는 리소스에 대해 요금이 발생하는 것을 방지하기 위해 연결된 리소스를 정리해야 합니다.

**리소스 정리**

1. [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2)에서 콘솔을 엽니다.

1. 탐색 창에서 **클러스터**를 선택합니다.

1. **클러스터(Clusters)** 페이지에서 클러스터를 선택합니다.

1. **클러스터 삭제(Delete Cluster)**를 선택합니다.

1. 확인 상자에 **delete *cluster name***을 입력한 다음 **삭제**를 선택합니다.

1. IAM 콘솔([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/))을 엽니다.

1. 탐색 창에서 **역할**을 선택합니다.

1. 역할 목록에서 `ecsTaskExecutionRole`을 검색하고 선택합니다.

1. **Permissions**(권한)를 선택한 다음 **ECSSecretsTutorial** 옆에 있는 **X**를 선택합니다. **** 제거를 선택합니다.

1. [https://console.aws.amazon.com/secretsmanager/](https://console.aws.amazon.com/secretsmanager/)에서 Secrets Manager 콘솔을 엽니다.

1. 생성한 **username\$1value** 보안 암호를 선택하고 **작업(Actions)**, **보안 암호 삭제(Delete secret)**를 선택합니다.