Amazon ECS용 바인드 마운트 예시

Amazon ECS용 바인드 마운트 예시

다음 예제는 컨테이너에 바인드 마운트(bind mount)를 사용하는 일반적인 사용 사례를 다뤄요.

출처: 문서

본문

Fargate 태스크에 더 많은 임시 스토리지 공간 할당 플랫폼 버전 1.4.0 이상(Linux) 또는 1.0.0(Windows)을 사용하는 Fargate에서 호스팅되는 Amazon ECS 태스크의 경우 태스크의 컨테이너가 사용할 기본 임시 스토리지 양보다 더 많이 할당할 수 있어요. 이 예제는 다른 예제에 통합해 Fargate 태스크에 더 많은 임시 스토리지를 할당할 수 있어요.

태스크 정의에서 ephemeralStorage 오브젝트를 정의해 주세요. sizeInGiB 는 21 과 200 사이의 정수여야 하며 GiB 단위로 표현돼요.

"ephemeralStorage": {
    "sizeInGiB": integer
}

하나 이상의 컨테이너에 빈 데이터 볼륨 제공 어떤 경우에는 태스크의 컨테이너에 일부 임시 공간(scratch space)을 제공하고 싶을 수 있어요. 예를 들어 태스크 중에 동일한 임시 파일 스토리지 위치에 액세스해야 하는 두 데이터베이스 컨테이너가 있을 수 있어요. 이는 바인드 마운트를 사용해 달성할 수 있어요.

태스크 정의의 volumes 섹션에서 database_scratch 라는 이름의 바인드 마운트를 정의해 주세요.

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

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"]
    
  2. 태스크 정의의 volumes 섹션에서 application_logs 라는 이름의 볼륨을 정의합니다.
      "volumes": [
        {
          "name": "application_logs"
        }
      ]
    
  3. 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 명령으로 항상 동일한 Amazon EC2 인스턴스를 태스크 시작 시점에 지정해 주세요. 영구 스토리지에 Amazon EFS 볼륨을 사용할 수도 있어요. 자세한 내용은 Use Amazon EFS volumes with Amazon ECS 를 참고해 주세요.

  1. 태스크 정의의 volumes 섹션에서 name 과 sourcePath 값으로 바인드 마운트를 정의합니다. 다음 예제에서 호스트 Amazon EC2 인스턴스에는 컨테이너 내부에 마운트하려는 /ecs/webdata 에 데이터가 있습니다.
      "volumes": [
        {
          "name": "webdata",
          "host": {
            "sourcePath": "/ecs/webdata"
          }
        }
      ]
    
  2. 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"
          }
        }
      ]
    
  2. 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로 이미지에 내장된 볼륨 모두에 적용돼요.

(선택 사항) 이미지에 내장된 볼륨을 공유하려면 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 섹션에서는 Docker 데몬이 관리하는 empty 라는 빈 볼륨을 만듭니다. 또한 호스트 컨테이너 인스턴스의 /etc 폴더를 내보내는 host_etc 라는 호스트 볼륨도 정의되어 있습니다.
    {
      "family": "test-volumes-from",
      "volumes": [
        {
          "name": "empty",
          "host": {}
        },
        {
          "name": "host_etc",
          "host": {
            "sourcePath": "/etc"
          }
        }
      ],
    
  2. 컨테이너 정의 섹션에서 앞서 정의한 볼륨을 마운트하는 컨테이너를 만듭니다. 이 예제에서 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
        },
    
  3. 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 컨테이너의 명령이 각 볼륨 폴더에 date 라는 파일로 날짜와 시간을 기록합니다. 그러면 폴더가 web 컨테이너가 표시하는 웹사이트에 표시됩니다.

참고 busybox 컨테이너는 빠른 명령을 실행한 후 종료되므로 컨테이너 정의에서 "essential": false 로 설정해야 해요. 그렇지 않으면 종료할 때 전체 태스크가 중지돼요.

더 알아보기 (Learn more)