AWS

[AWS] aws-cli를 이용한 Fargate Cluster와 Repository 생성

sklass 2021. 12. 9. 16:45

AWS Fargate란, EC2 인스턴스의 서버나 클러스터를 관리할 필요 없이 컨테이너를 실행하기 위해 Amazon ECS(Elastic Container Service)에 사용할 수 있는 기술로, Fargate를 사용하면 더 이상 컨테이너를 실행하기 위해 가상 머신의 클러스터를 프로비저닝, 구성 또는 조정할 필요가 없어서, 관리면에서 사용자 편의성을 높여줍니다.

Fargate는 어떻게 작동합니까?

Fargate를 활용하여 애플리케이션 컨테이너 배포를 관리하려면 ECR 또는 DockerHub와 같은 컨테이너 레지스트리에 컨테이너를 저장하고 ECS 또는 EKS를 통해 작업 및 클러스터를 설정해야합니다.

 

배포주기의 단계는 다음과 같습니다.

  1. 컨테이너 이미지 빌드
  2. 레지스트리 (예 : Amazon ECR 또는 DockerHub)에서 호스팅
  3. 오케스트레이션 서비스 (Amazon ECS 또는 EKS) 선택
  4. AWS Fargate 옵션을 사용하여 클러스터 생성

AWS Fargate과 AWS ECR(Elastic Container Registry) 도식화

Fargate와 ECR 도식화

ECR Repository 생성

해당 문서는 Ubuntu 환경에서 Django 웹프레임워크로 튜토리얼을 진행하니 이 점 유의해서 봐주시기 바랍니다.

 

먼저, ECR Repository를 생성해보겠습니다. Repsitory란 로컬이나 혹은 리모트 서버에서 빌드한 이미지를 저장하는 저장소라고 생각하시면 됩니다.

 

그럼 우선 아래의 명령어로 Docker를 설치하겠습니다.

$ curl -fsSL https://get.docker.com/ | sudo sh
$ sudo usermod -aG docker $USER

그 후, Dockerfile을 생성하고, 아래의 내용을 넣어줍니다.

FROM python:3.6.7

ENV PYTHONUNBUFFERED 1

RUN apt-get -y update
RUN apt-get -y install vim

RUN mkdir /srv/docker-django
ADD . /srv/docker-django

WORKDIR /srv/docker-django

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

 

위에서 생성한 Dockerfile을 이용해서 아래의 명령어로 docker 이미지를 server_dev/django라는 이름으로 빌드해보겠습니다.

$ docker build -t server_dev/django .

 

aws-cli를 설치해줍니다.

$ sudo apt install awscli

그 후, 아래의 명령어로 aws ACCESS 정보를 업데이트 해줍니다.

$ aws configure

 

이제 아래의 명령어를 이용해서 AWS ECR로 로그인 해보겠습니다.

$ aws ecr get-login --no-include-email --region us-west-2

위의 명령어를 치면 아래와 같은 output이 나오는데, 이거를 그대로 복사해서 커맨드 라인에서 실행시킵니다.

$ docker login -u AWS -p <AWS_PASSWORD>== https://<USER_ID>.dkr.ecr.us-west-2.amazonaws.com

 

이제 hello-cli라는 이름으로 Repository를 생성해보겠습니다.

$ aws ecr create-repository --repository-name hello-cli --region us-west-2

 

그 후, docker 명령어를 이용해서, 로컬이나 리모트 서버에 빌드한 이미지의 ID에 방금 생성한 AWS Repository URI를 를 태깅해줍니다.

$ docker tag <IMAGE_ID> <AWS_ECR_REPOSITORY_URI>

이제 해당 이미지를 생성한 AWS ECR Repository로 push해줍니다.

$ docker push <AWS_ECR_REPOSITORY_URI>

 

여기까지하면, 로컬이나 리모트 서버에서 빌드한 이미지를 AWS ECR 레포지토리에 push하는 것까지 하였습니다. 이제 Fargate Cluster를 생성하는 부분을 보겠습니다.

 

aws-cli를 이용한 Fargate Cluster 생성

아래의 명령어를 사용하여 클러스터를 생성합니다.

aws ecs create-cluster --cluster-name <CLUSTER_NAME>

Output:

{
    "cluster": {
        "status": "ACTIVE", 
        "statistics": [], 
        "clusterName": "fargate-cluster", 
        "registeredContainerInstancesCount": 0, 
        "pendingTasksCount": 0, 
        "runningTasksCount": 0, 
        "activeServicesCount": 0, 
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster"
    }
}

 

그 후, 작업 정의를 생성해주어야하는데, 작업 정의를 생성하기 위해서는 우선 json 파일을 하나 만들어 작업 정의에 필요한 세팅을 먼저 해주고, 해당 json을 이용해서 명령어로 작업 정의를 생성하는 방식입니다.

 

우선, 작업 정의를 하기 위한 IAM Role을 하나 생성해보겠습니다. 

아래의 내용으로 json파일을 하나 추가해주세요

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

 

아래의 명령어를 이용해서 ecrTaskRole 라는 이름으로iam role을 생성해보겠습니다.

$ aws iam create-role --role-name ecrTaskRole --assume-role-policy-document file://<PATH_TO_JSON_FILE>

그리고 해당 IAM Role을 attach해줍니다.

$ aws iam attach-role-policy --role-name ecrTaskRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

IAM Role 생성과 관련된 이슈가 있다면 아래 링크를 참고해주세요

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html

 

Amazon ECS task execution IAM role - Amazon Elastic Container Service

The ecr:GetAuthorizationToken API action cannot have the aws:sourceVpc or aws:sourceVpce condition keys applied to it because the GetAuthorizationToken API call goes through the elastic network interface owned by AWS Fargate rather than the elastic network

docs.aws.amazon.com

 

이제 작업 정의를 생성할 json 파일을 만들어보겠습니다.

아래의 내용으로 json파일을 하나 더 생성해주세요.

{
    "family": "fargate-cli",
    "networkMode": "awsvpc",
    "executionRoleArn": "ecrTaskRole",
    "containerDefinitions": [
        {
            "name": "django-cli",
            "image": <ECR_REPOSITORY_IMAGE_URI>,
            "portMappings": [
                {
                    "containerPort": 8000,
                    "hostPort": 8000,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "entryPoint": [
                "sh",
                "-c"
            ]
        }
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "256",
    "memory": "512"
}

options

  • family: 생성될 작업 정의의 이름입니다.
  • executionRoleArn: 위에서 생성한 IAM Role의 이름을 넣어주면 됩니다.
  • containerDefinitions: 작업 정의에서 관리할 컨테이너 관련 설정들입니다.
    • image: 위에서 생성한 ECR Repository의 이미지 URI를 넣어주시면 됩니다.
      • portMappings: containerPort: container로 들어오는 port 입니다.
      • portMappings: hostPort: 해당 작업 정의로 요청이 오면, 들어오게될 port입니다.
        • 즉, 작업 정의로 요청이 hostPort로 통해서 들어오게되고, 해당 요청이 다시 containerPort를 통해서 컨테이너로 가게됩니다.
        • Fargate를 사용하게되면, containerPort와 hostPort의 값은 무조건 같아야 합니다.

위에서 설명한 options에 대한 구체적인 의미가 궁금하다면, 아래의 링크를 참고해주세요.

https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/task_definition_parameters.html

 

태스크 정의 파라미터 - Amazon Elastic Container Service

태스크 정의 파라미터 태스크 정의는 태스크 패밀리, IAM 태스크 역할, 네트워크 모드, 컨테이너 정의, 볼륨, 태스크 배치 제약, 시작 유형 등의 부분으로 나뉩니다. 패밀리 및 컨테이너 정의는 태

docs.aws.amazon.com

 

아래 명령어로 작업 정의를 register 합니다.

$ aws ecs register-task-definition --cli-input-json file://<PATH_TO_JSON_FILE>

 

 

작업 정의가 잘 들어갔는지 확인해봅니다.

$ aws ecs list-task-definitions

 

이제 Service를 생성해야하는데, Service는 private subnet 혹은 public subnet에 설치할 수 있으며, 이번에는 public subnet에 설치해보도록 하겠습니다.

 

아래의 명령어를 이용해서 Service를 생성하세요.

$ aws ecs create-service --cluster <CLUSTER_NAME> \
--service-name <SERVICE_NAME> --task-definition <TASK_DEFINITION_NAME>:1 \
--desired-count 1 --launch-type "FARGATE" \
--network-configuration "awsvpcConfiguration={subnets=[<PUBLIC_SUBNET_ID>],securityGroups=[<SECURITY_GROUP_ID>],assignPublicIp=ENABLED}"

 

Cluster에 Service가 잘 생성되었는지 확인합니다.

$ aws ecs list-services --cluster <CLUSTER_NAME>

삭제

서비스를 삭제합니다.

$ aws ecs delete-service --cluster <CLUSTER_NAME> --service <SERVICE_NAME> --force

클러스터를 삭제합니다.

$ aws ecs delete-cluster --cluster <CLUSTER_NAME>

 

References

https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/ECS_AWSCLI_Fargate.html

 

Tutorial: Creating a cluster with a Fargate Linux task using the AWS CLI - Amazon Elastic Container Service

The benefit of using the default cluster that is provided for you is that you don't have to specify the --cluster cluster_name option in the subsequent commands. If you do create your own, non-default, cluster, you must specify --cluster cluster_name for e

docs.aws.amazon.com