

# Amazon ECS에 대한 바인드 탑재 예제
<a name="bind-mount-examples"></a>

다음 예제에서는 컨테이너에 바인드 탑재를 사용하는 일반적인 사용 사례를 다룹니다.

**Fargate 태스크를 위한 임시 스토리지 스페이스의 증가된 양을 할당하는 방법**

플랫폼 버전 `1.4.0` 이상(Linux) 또는 `1.0.0` 이상(Windows)을 사용하여 Fargate에서 호스팅되는 Amazon ECS 태스크의 경우 태스크의 컨테이너에 사용할 임시 스토리지 공간의 기본 양 이상을 할당할 수 있습니다. 이 예제는 다른 예제에 포함하여 Fargate 태스크에 더 많은 임시 스토리지를 할당할 수 있습니다.
+ 태스크 정의에서 `ephemeralStorage` 객체를 정의합니다. `sizeInGiB`는 `21`과 `200` 값 사이의 정수여야 하며 GiB로 표현합니다.

  ```
  "ephemeralStorage": {
      "sizeInGiB": integer
  }
  ```

**하나 이상의 컨테이너에 빈 데이터 볼륨을 제공하는 방법**

경우에 따라 태스크의 컨테이너에 스크래치 스페이스를 제공합니다. 예를 들어 태스크 도중 동일한 스크래치 파일 스토리지 위치에 액세스해야 하는 2개의 데이터베이스 컨테이너가 있을 수 있습니다. 이 태스크는 바인드 탑재를 사용하여 수행할 수 있습니다.

1. 태스크 정의 `volumes` 섹션에서 이름이 `database_scratch`인 바인드 탑재를 정의합니다.

   ```
     "volumes": [
       {
         "name": "database_scratch"
       }
     ]
   ```

1. `containerDefinitions` 섹션에서 데이터베이스 컨테이너 정의를 생성합니다. 이는 볼륨을 탑재하기 위함입니다.

   ```
   "containerDefinitions": [
       {
         "name": "database1",
         "image": "my-repo/database",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "database_scratch",
             "containerPath": "/var/scratch"
           }
         ]
       },
       {
         "name": "database2",
         "image": "my-repo/database",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "database_scratch",
             "containerPath": "/var/scratch"
           }
         ]
       }
     ]
   ```

**Dockerfile의 경로와 콘텐츠를 컨테이너에 노출하는 방법**

이 예제에서는 컨테이너 내부에 탑재할 데이터를 쓰는 Dockerfile이 있습니다. 이 예제는 Fargate 또는 Amazon EC2 .인스턴스에서 호스팅되는 태스크에 적용됩니다.

1. Dockerfile을 생성합니다. 다음 예제에서는 퍼블릭 Amazon Linux 2 컨테이너 이미지를 사용하고 `/var/log/exported` 디렉토리에서 컨테이너 내부에 탑재하려는 `examplefile`이라는 파일을 생성합니다. `VOLUME` 명령은 절대 경로를 지정해야 합니다.

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN mkdir -p /var/log/exported
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

   기본적으로 볼륨 권한은 `0755`로 설정되고 소유자는 `root`로 설정됩니다. 이러한 권한은 Dockerfile에서 변경할 수 있습니다. 다음 예에서는 `/var/log/exported` 디렉터리의 소유자를 `node`로 정의합니다.

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN yum install -y shadow-utils && yum clean all
   RUN useradd node
   RUN mkdir -p /var/log/exported && chown node:node /var/log/exported					    
   USER node
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

1. 태스크 정의 `volumes` 섹션에서 이름이 `application_logs`인 볼륨을 정의합니다.

   ```
     "volumes": [
       {
         "name": "application_logs"
       }
     ]
   ```

1. `containerDefinitions` 섹션에서 애플리케이션 컨테이너 정의를 생성합니다. 이에 따라 스토리지를 탑재합니다. `containerPath` 값은 Dockerfile의 `VOLUME` 명령에서 지정한 절대 경로와 일치해야 합니다.

   ```
     "containerDefinitions": [
       {
         "name": "application1",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       },
       {
         "name": "application2",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       }
     ]
   ```

**호스트 Amazon EC2 인스턴스의 수명 주기에 연결된 컨테이너에 빈 데이터 볼륨을 제공하는 방법**

Amazon EC2 인스턴스에서 호스팅되는 태스크의 경우 바인드 탑재를 사용하여 호스트 Amazon EC2 인스턴스의 수명 주기에 데이터를 연결할 수 있습니다. 이 태스크는 `host` 파라미터를 사용하고 `sourcePath` 값을 지정하여 수행할 수 있습니다. `sourcePath`에 있는 모든 파일의 `containerPath` 값이 컨테이너에 표시됩니다. `containerPath` 값으로 기록된 모든 파일은 호스트 Amazon EC2 인스턴스에서 `sourcePath` 값으로 기록됩니다.
**중요**  
Amazon ECS는 Amazon EC2 인스턴스에 스토리지를 동기화하지 않습니다. 영구 스토리지를 사용하는 태스크는 클러스터에서 가용 용량이 있는 어떤 Amazon EC2 인스턴스에도 배치할 수 있습니다. 태스크 중단 및 재시작 후 영구 스토리지가 필요한 경우에는 항상 AWS CLI [start-task](https://docs.aws.amazon.com/cli/latest/reference/ecs/start-task.html) 명령을 사용하여 태스크 시작 시 동일한 Amazon EC2 인스턴스를 지정합니다. 영구 스토리지용 Amazon EFS 볼륨을 사용할 수도 있습니다. 자세한 정보는 [Amazon ECS에서 Amazon EFS 볼륨 사용](efs-volumes.md) 섹션을 참조하세요.

1. 태스크 정의 `volumes` 섹션에서 `name` 및 `sourcePath` 값을 사용하여 바인드 탑재를 정의합니다. 다음 예에서 호스트 Amazon EC2 인스턴스에는 컨테이너 내부에 탑재하려는 `/ecs/webdata`의 데이터가 포함됩니다.

   ```
     "volumes": [
       {
         "name": "webdata",
         "host": {
           "sourcePath": "/ecs/webdata"
         }
       }
     ]
   ```

1. `containerDefinitions` 섹션에서 바인드 탑재 이름과 컨테이너에서 바인드 탑재를 탑재할 `mountPoints` 값을 참조하는 `containerPath` 값을 사용하여 컨테이너를 정의합니다.

   ```
     "containerDefinitions": [
       {
         "name": "web",
         "image": "public.ecr.aws/docker/library/nginx:latest",
         "cpu": 99,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webdata",
             "containerPath": "/usr/share/nginx/html"
           }
         ]
       }
     ]
   ```

**정의된 볼륨을 여러 위치에 있는 여러 컨테이너에 탑재하는 방법**

태스크 정의에서 데이터 볼륨을 정의하여 해당 볼륨을 여러 컨테이너의 여러 위치에 탑재할 수 있습니다. 예를 들어, 호스트 컨테이너의 `/data/webroot`에 웹 사이트 데이터 폴더가 있습니다. 문서 루트가 서로 다른 두 웹 서버에 해당 데이터 볼륨을 읽기 전용으로 탑재할 수 있습니다.

1. 태스크 정의 `volumes` 섹션에서 이름 `webroot` 및 소스 경로 `/data/webroot`를 사용하여 데이터 볼륨을 정의합니다.

   ```
     "volumes": [
       {
         "name": "webroot",
         "host": {
           "sourcePath": "/data/webroot"
         }
       }
     ]
   ```

1. `containerDefinitions` 섹션에서 `mountPoints` 볼륨을 해당 컨테이너의 문서 루트를 가리키는 `webroot` 값과 연결하는 `containerPath` 값을 사용하여 각 웹 서버의 컨테이너를 정의합니다.

   ```
     "containerDefinitions": [
       {
         "name": "web-server-1",
         "image": "my-repo/ubuntu-apache",
         "cpu": 100,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webroot",
             "containerPath": "/var/www/html",
             "readOnly": true
           }
         ]
       },
       {
         "name": "web-server-2",
         "image": "my-repo/sles11-apache",
         "cpu": 100,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 8080,
             "hostPort": 8080
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webroot",
             "containerPath": "/srv/www/htdocs",
             "readOnly": true
           }
         ]
       }
     ]
   ```

**`volumesFrom`을 사용하여 다른 컨테이너로부터 볼륨을 탑재하는 방법**

Amazon EC2 인스턴스에서 호스팅되는 태스크의 경우 컨테이너에 하나 이상의 볼륨을 정의한 후 다른 컨테이너 정의(동일한 태스크 내)의 `volumesFrom` 파라미터를 사용하여 원래 정의된 탑재 지점에서 `sourceContainer`로부터 모든 볼륨을 탑재할 수 있습니다. `volumesFrom` 파라미터는 태스크 정의에 정의된 볼륨과 Dockerfile을 사용하여 이미지에 내장된 볼륨에 적용됩니다.

1. (선택 사항) 이미지에 내장된 볼륨을 공유하려면 Dockerfile의 명령인 `VOLUME`을 사용합니다. 다음 예제 Dockerfile은 `httpd` 이미지를 사용한 후 볼륨을 추가하고 Apache 문서 루트에서 `dockerfile_volume`에 탑재합니다. 이 폴더는 `httpd` 웹 서버에서 사용하는 폴더입니다.

   ```
   FROM httpd
   VOLUME ["/usr/local/apache2/htdocs/dockerfile_volume"]
   ```

   이 Dockerfile을 사용하여 이미지를 만들어 Docker Hub와 같은 리포지토리에 푸시한 후 태스크 정의에서 사용할 수 있습니다. 다음 단계에서 사용된 `my-repo/httpd_dockerfile_volume` 이미지 예제는 위의 Dockerfile을 사용하여 구축되었습니다.

1. 컨테이너에 다른 볼륨 및 탑재 지점을 정의하는 태스크 정의를 생성합니다. 이 예제 `volumes` 섹션에서는 `empty`라는 빈 볼륨을 생성하며, Docker 대몬이 이 볼륨을 관리합니다. `host_etc`라는 호스트 볼륨도 정의되어 있습니다. 호스트 컨테이너 인스턴스에서 `/etc` 폴더를 내보냅니다.

   ```
   {
     "family": "test-volumes-from",
     "volumes": [
       {
         "name": "empty",
         "host": {}
       },
       {
         "name": "host_etc",
         "host": {
           "sourcePath": "/etc"
         }
       }
     ],
   ```

   컨테이너 정의 섹션에서 앞서 정의한 볼륨을 탑재하는 컨테이너를 생성합니다. 이 예제에서 `web` 컨테이너는 `empty` 및 `host_etc` 볼륨을 탑재합니다. 이는 Dockerfile에서 볼륨으로 빌드된 이미지를 사용하는 컨테이너입니다.

   ```
   "containerDefinitions": [
       {
         "name": "web",
         "image": "my-repo/httpd_dockerfile_volume",
         "cpu": 100,
         "memory": 500,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "mountPoints": [
           {
             "sourceVolume": "empty",
             "containerPath": "/usr/local/apache2/htdocs/empty_volume"
           },
           {
             "sourceVolume": "host_etc",
             "containerPath": "/usr/local/apache2/htdocs/host_etc"
           }
         ],
         "essential": true
       },
   ```

   `volumesFrom`을 사용하여 `web` 컨테이너와 연결된 모든 볼륨을 탑재하는 다른 컨테이너를 생성합니다. `web` 컨테이너에 있는 모든 볼륨도 마찬가지로 `busybox` 컨테이너에 탑재됩니다. 여기에는 `my-repo/httpd_dockerfile_volume` 이미지를 빌드하는 데 사용된 Dockerfile에 지정된 볼륨이 포함됩니다.

   ```
       {
         "name": "busybox",
         "image": "busybox",
         "volumesFrom": [
           {
             "sourceContainer": "web"
           }
         ],
         "cpu": 100,
         "memory": 500,
         "entryPoint": [
           "sh",
           "-c"
         ],
         "command": [
           "echo $(date) > /usr/local/apache2/htdocs/empty_volume/date && echo $(date) > /usr/local/apache2/htdocs/host_etc/date && echo $(date) > /usr/local/apache2/htdocs/dockerfile_volume/date"
         ],
         "essential": false
       }
     ]
   }
   ```

   이 태스크가 실행되면 두 컨테이너가 볼륨을 탑재하며, `busybox` 컨테이너의 `command`가 파일에 날짜 및 시간을 씁니다. 이 파일은 각 볼륨 폴더에서 `date`로 호출됩니다. 그러면 `web` 컨테이너가 표시하는 웹 사이트에 이 폴더가 표시됩니다.
**참고**  
`busybox` 컨테이너는 빠른 명령을 실행한 후 종료하므로 컨테이너 정의에서 `"essential": false`를 설정해야 합니다. 그렇지 않으면 컨테이너 종료 후 전체 태스크가 중지됩니다.