AWS Fargate 소개

AWS Fargate는 AWS의 컨테이너 서비스인 ECS에 포함된 하나의 옵션으로 2017년 부터 시작된 서비스 이며 2018년 말경 한국리전에서도 사용할 수 있게 되었습니다.

기존의 ECS가 Amazon EC2 인스턴스 클러스터를 관리하고, 인스턴스 유형을 선택하고, 컨테이너의 일정을 관리하고, 클러스터 사용률을 최적화해야 했던 것과는 다르게 EC2 자원 관리를 AWS에 맡겨 서버의 프로비저닝이나 스케일링에 대해 걱정할 필요없이 컨테이너 및 어플리케이션에 집중할 수 있습니다. 추가로 네트워크, 보안 및 서비스 통신에 대한 완벽한 제어 기능을 제공하며 보안, 네트워킹, 액세스 제어, 개발자 툴링, 모니터링 및 로깅을 위해 AWS 서비스와 기본적으로 통합되어 있습니다.


서버를 관리하지 않는 것은  AWS의 다른 ServerLess 서비스인 Lambda와 비슷하여 컨테이너 버전의 ServerLess라고 할 수 있으며 성능이나 시간제한이 있었던 Lambda의 단점을 어느정도 채워줄 수 있는 옵션이 될 수 있습니다.


비용

아래는 AWS 홈페이지에 소개된 비용으로 1CPU 1GB 메모리 기준 시간당 약 0.051$의 요금으로 같은 스펙인 t2.micro 의 0.013$ 보다는 비싸편 입니다.

 
  • 아시아 태평양(서울)
요금
시간별 vCPU당0.04656 USD
시간별 GB당0.00511 USD

다만 지원 되는 구성이 다음와 같이 0.25개부터 가능하여 다소 절약은 가능합니다(그것보다 Fargate 덕분에 감소하는 인적 리소스로 인한 감소가 더 클것입니다.)

CPU
메모리 값
0.25vCPU0.5GB, 1GB, 2GB
0.5vCPU최소 1GB 및 최대 4GB(1GB씩 증가)
1vCPU최소 2GB 및 최대 8GB(1GB씩 증가)
2vCPU최소 4GB 및 최대 16GB(1GB씩 증가)
4vCPU최소 8GB 및 최대 30GB(1GB씩 증가)


작업환경 전 준비사항

1. 로컬 데스크탑 환경 - 본 글에서는 ubuntu 리눅스로 진행하지만 간단한 소스 코드에 AWS 콘솔위주이기 때문에 크게 상관 없습니다.

2. AWS 계정

3. 도커에 대한 기본 지식


작업 시작

IAM 계정 생성

AWS를 사용하며 작업중 aws cli를 사용을 위해 Access 키가 필요하여 필요한 IAM 계정을 생성합니다. 다만 aws cli는 간단하게 명령어 만으로 많은 작업을 수행할 수 있는 강력한 도구이기 때문에 막강한 권한을 가진 root 계정 또는 콘솔 로그인이 가능한 계정 보다는 해당 Appication에서 사용하는 특정 권한만을 허용한 계정을 사용하는 것이 보안에 좋습니다.


맨 처음 IAM 설정 권한을 가진 콘솔 계정으로 로그인하여 IAM을 검색, IAM 설정 페이지로 이동 후 user 생성을 위해 사용자 항목으로 이동을 합니다.


사용자 추가를 클릭하여 사용자 추가 화면으로 이동합니다.


1단계에서는 유저 이름 및 엑세스 유형을 입력합니다. 해당 IAM 계정은  Access Key를 필요로 하는 프로그래밍용 계정이므로 프로그래밍 방식 엑세를 선택 후 다음을 클릭합니다.



2단계는  권한 설정을 하는 페이지로 IAM과 ECS, ECR에 관해 깊은 이해가 있으면 필요한 권한만을 붙이는 것이 좋겠지만 현재 작업에서는 기존에 AWS에서 생성되는 작업으로 진항하겠습니다. 

정책 연결을 위해 기존 정책 직접 연결을 클릭 후 ECR 관련 작업을 위해 AmazonEC2ContainerRegistryFullAccess와 ECS 작업을 위해 AmazonEC2ContainerServiceFullAccess 정책을 각각 검색하여연결해 줍니다. 3단계는 해당 IAM에 Tag를 달아주기 위해 Key에 Name Value에 1단계에서 입력한 IAM롤의 이름을 입력하고 다음을 클릭합니다.

4단계에서는 1~3단계에서 작업한 내용을 확인 후 실제 생성을 위해 사용자 만들기를 클릭합니다.



5단계는 Access Key를 확인하는 단계로 ID와 비밀 키가를 확인하거나 CSV 파일로 다운받아 관리할 수 있습니다.

비밀 액세스 키 밑의 표시를 누르면 위와 같이 표시 되니 잘 관리해야 합니다. 계정의 Access Key는 본 페이지 외에서는 확인할 수 없고 분실할 경우에는 IAM 권한을 가진 계정으로 키를 다시 생성하여 다른 키를 사용해야 합니다.


2. 도커 이미지 생성 및 ECR에 등록

- aws cli 환경설정

우선  어플리케이션을 AWS에 push 하기 위해 먼저 aws cli 환경설정을 합니다. aws cli는 Python pip를 통해 설치하는데 시스템 전체에 영향을 주지 않기 위해 virtualenv를 설치합니다.

user:~$ sudo apt-get update -y

...(중략)...

user:~$ sudo apt-get install -y python-virtualenv

...(중략)...

user:~$ mkdir hello_app

user:~$ cd hello_app/

user:~/hello_app$ 

user:~/hello_app$ virtualenv -p python3 venv

Running virtualenv with interpreter /home/user/flaskapp/venv/bin/python3
Using real prefix '/usr'
New python executable in /home/user/hello_app/venv/bin/python3
Also creating executable in /home/user/hello_app/venv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
user:~/hello_app$
user:~/hello_app$ source venv/bin/activate

(venv) user:~/hello_app$ 

Python 3.6.7



다음으로 awscli를 설치하고 기본 설정을 합니다. 설정은 아래와 같이 위에서 설정한 IAM 계정의 Access Key와 비밀키, 기본 리전과 기본 출력 형식을 지정합니다.


(venv) user:~/hello_app$ pip install awscli --upgrade

...(중략)...

(venv) user:~/hello_app$ aws configure

AWS Access Key ID [****************L2DQ]: AKIAIAI5N5YP57AOVZFA

AWS Secret Access Key [****************KEHt]: ssf+...(중략)...DDvp

Default region name [ap-northeast-2]: 

Default output format [json]: 



 -  Docker 이미지용 Application 작성

aws에 이미지를 올리고 컨테이너를 컨트롤할 준비가 되었으면 실제 aws에 올릴 이미지를 작성하겠습니다. 이미지를 생성하기 위해 위해 가장 간단한게 웹페이지에 "Hello World!"를 출력하는 프로그램을 아래와 같이 작성하였습니다. 해당 프로그램은 모든 소스로 부터 접근이 가능하며 80포트로 서비스 하도록 설정되었습니다.

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)


 - ECR에 repository 생성

다음으로 해당 프로그램을 실제 AWS Fargate로 서비스를 하기 위해 ECR에 등록 합니다. 

참고로 ECR은 Amazon Elastic Container Registry의 약자로 사용자가 Docker 컨테이너 이미지를 손쉽게 저장, 관리 및 배포할 수 있게 해주는 완전관리형 Docker 컨테이너 레지스트리입니다. 쉽게 얘기하면 Fargate를 포함한 아마존의 컨테이너 서비스에서 사용하기 위한 도커 이미지 저장소입니다.


ECR에 등록하기 위해서는 최초에는 AWS 콘솔에서 ECR을 검색한 후 repository를 작성합니다.


다음 구성화면에서 repository 이름을 작성하는데 콘솔에서 보여주는 것과 같이 네임스페이스/서비스 형식의 이름으로 작성할 수 있으며 대문자는 사용 불가능 합니다.


위의 AWS 콘솔에서는 "fargagedemo/helloapp"으로 repository를 작성하였고 aws cli 명령어는 다음과 같습니다.

(venv) user:~/hello_app$ aws ecr create-repository --repository-name fargatedemo/helloapp

{

    "repository": {

        "repositoryArn": "arn:aws:ecr:ap-northeast-2:111111111111:repository/fargatedemo/helloapp",

        "registryId": "111111111111",

        "repositoryName": "fargatedemo/helloapp",

        "repositoryUri": "111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp",

        "createdAt": 1547993101.0

    }

}

(venv) user:~/hello_app$ 


 - ECR에 repository에 Docker Image 올리기

repository 생성 후에 ECR 메인 페이지에서 해당 repository이름을 클릭하면 다음과 같이 repository에 포함된 이미지 리스트가 표시되며 최초 이미지 등록시 푸쉬 명력 보기를 통해 손쉽게 도커 이미지를 ECR에 올릴 수 있습니다.


푸쉬 명령은 다음과 같으며 AWS CLI를 통해 직접 명령어를 입력시 오탈자등으로 인해 잘못 입력되기 쉬운데 친절하게 붙여준 텍스트를 단계별로 수행만 하면 이미지가 저장됩니다.


Command 입력 결과는 다음과 같습니다. 로그인 수행 시 최초 명령의 결과값을 그대로 복사하여 다시 입력하면 로그인이 되고 그 이후에 순서대로 2. 빌드 -> 3. 태깅 -> 4. 푸쉬를 진행 합니다.

푸쉬는 모든 이미지가 Pushed가 되면 종료 된 것입니다.

(venv) user:~/hello_app$ (aws ecr get-login --no-include-email --region ap-northeast-2)

docker login -u AWS -p eyJwYXlsb2FkIjoiY1VkeE1sc3d2M1FLbEU0dHVtZzA3aVh0K0F1SWoySzFQZG1OYy9GYjYvYy9MYnR1bnVJNll1b2I1bX

...(중략)...

9uIjoiMiIsInR5cGUiOiJEQVRBX0tFWSIsImV4cGlyYXRpb24iOjE1NDgwMzcyNDh9 https://111111111111.dkr.ecr.ap-northeast-2.amazonaws.com

## 위 명력을 그대로 입력 ##

(venv) user:~/hello_app$ 

(venv) user:~/hello_app$ docker login -u AWS -p eyJwYXlsb2FkIjoiY1VkeE1sc3d2M1FLbEU0dHVtZzA3aVh0K0F1SWoySzFQZG1OYy9GYjYvYy9MYnR1bnVJNll1b2I1bX

...(중략)...

9uIjoiMiIsInR5cGUiOiJEQVRBX0tFWSIsImV4cGlyYXRpb24iOjE1NDgwMzcyNDh9 https://111111111111.dkr.ecr.ap-northeast-2.amazonaws.com


Login Succeeded

(venv) user:~/hello_app$ docker build -t fargatedemo/helloapp .

Sending build context to Docker daemon  17.34MB

Step 1/8 : FROM python:alpine

 ---> 1a8edcb29ce4

Step 2/8 : LABEL Name=flaskapp Version=0.0.1

 ---> Using cache

 ---> 840ae2afa937

...(중략)...

Successfully built 74b72d5f1369

Successfully tagged fargatedemo/helloapp:latest

(venv) user:~/hello_app$  

(venv) user:~/hello_app$ docker tag fargatedemo/helloapp:latest 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:latest
(venv) user:~/hello_app$
(venv) user:~/hello_app$ docker push 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:latest
The push refers to repository [111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp]
55e63f5d5562: Pushed 
642a791f9fd2: Pushed 
76e39cec4c1f: Pushed 
7158e09cb118: Pushed 
8643e4accddc: Pushed 
43e8a7decf15: Pushed 
7484166a246c: Pushed 
1c862c0e1a30: Pushed 
7bff100f35cb: Pushed 
latest: digest: sha256:1b0130a147ac48795d9f14831cea3028ea7872b497ce64fb6bcebcd22c01256f size: 2200
(venv) user:~/hello_app$


3. 작업 정의

등록한 이미지를 바탕으로 작업을 정의 합니다. 작업(Task)은 같이 실행되는 한개 이상의 컨테이너의 집합체를 말합니다. 작업정의를 통해 하나 이상의 컨테이너 실행될때 컨테이너의 사용할 도커 이미지 사용할 CPU, 메모리, 네트워크 등을 설정할 수 있습니다.


 - 작업 정의 생성

작업 정의를 생성 하기 위해 작업 정의를 선택 후 새 작업 정의 생성을 눌러 작업 정의를 생성합니다.

다음으로 EC2 자원을 정의하지 않는 Fargate를 선택 후 다음단계로 진행합니다.


2단계에서 상단의 항목에서 필수 입력할 항목은 작업이름입니다.

그 외에 작업 역할은 해당 작업이 다른 AWS 서비스를 API를 통해 호출하여 사용할 경우 지정합니다. 예를 들면 RDS에 table을 수정한다면 RDS write권한을 가진 Role을 선택해 줍니다. 해당 예제에서는 없음을 선택하였습니다.

호환성 요구 사항 및 네트워크 모드는 1단계에서 FARGATE 선택시 선택 할 수 없는 옵션이 없이 Default값을 사용합니다.






하단 항목에서는 첫째로 작업이 실행되는 ECS 및 ECR 관련 권한을 가진 IAM Role을 선택하는데 안내와 같이 기본으로 제공되는 ecsTaskExecutionRole을 생성하여 사용합니다.

둘째로 작업 크기는 FARGATE에서만 필수 항목으로 EC2 유형을 선택한 경우는 Instance에 대해 제어하며 관리하기 vCPU 및 메모리에 관하여 이미 Instance에 할당된 자원 내에서 사용하겠지만 Instance를 관리하지 않는 FARGATE는 작업에 사용될 자원만 지정하여 지정된 자원만큼에 대해 비용을 지불하는 방식이기 때문입니다.

세번째는 컨테이너 추가를 클릭하여 도커 이미지를 통해 실제 작업에서 사용할 컨테이너를 구성합니다.

테이너는 1개 이상이 등록가능하지만 AWS에서는 기본적으론 개별적인 컨테이너 프로비저닝, 스캐일링을 할 수 있도록 개별적으로 작업 정의를 사용하길 권하고 있습니다. 그 예외의 경우는 다음과 같습니다.

 - 컨테이너가 공통 수명 주기를 공유하는 경우(즉 함께 시작하고 종료되어야 함).

 - 컨테이너가 동일한 기본 호스트에서 실행되어야 하는 경우(즉 로컬호스트 포트에서 한 컨테이너가 다른 컨테이너를 참조함)

 - 컨테이너가 리소스를 공유하길 원하는 경우.

 - 컨테이너가 데이터 볼륨을 공유하는 경우



 - 작업 정의에 컨테이너 추가

컨테이너 추가를 클릭하여 나타난 다음의 정보를 입력하고 추가를 클릭하면 컨테이너가 등록됩니다.

사용할 이미지는 사용할 이미지의 URL을 입력하는데 아래 첨부된 스샷과 같이 ECR에서 간단하게 복사하여 사용하면 됩니다.

프라이빗 레지스트리 인증은 개별적으로 사용중인 Docker Repository를 사용하는 경우 인증관련 옵션을 설정하는 항목으로 본 예제에서는 사용하지 않습니다.

포트 매핑은 컨테이너가 사용할 포트를 지정하는 것으로 따로 웹으로 별도의 서비스와 연동하지 않는 단순 작업은 지정하지 않아도 되며 본 예제의 코드에서는 80포트를 사용하기 때문에 80으로 지정합니다.




ECR에서 작업에 사용할 Repository 복사



컨테이너를 등록 후 등록된 컨테이너를 확인 후 생성을 클릭하여 작업정의를 생성합니다.


4. 클러스터 및 서비스 생성

ECR을 통해 도커 이미지를 등록했고 ECS에서 작업정의를 통해 작업정의를 작성했다면 다음은 실제로 작업들을 수행하기 위해 클러스터를 구성하고 서비스를 작성하는 단계입니다.
클러스터는 일반적으로 비슷한 역할 또는 기능을 수행하는 집단, 장치등을 묶어서 하나의 집단 장치처럼 작용하게 하는 것으로 IT에서는 주로 컴퓨팅 자원을 묶어서 사용하는데 많이 사용되어 집니다.
ECS에서의 클러스터 또한 리전별로 고유한 서비스 또는 작업들의 논리적인 묶음으로 다수의 서비스 및 작업들을 포함할 수 있습니다.

 - 클러스터 생성

클러스터를 생성하기 위해 클러스터 항목으로 이동하여 클러스터 생성을 클릭합니다.


EC2 자원을 사용하지 않기 때문에 네트워킹 전용을 선택 후 다음단계로 진행합니다.


클러스터 이름을 입력한 후 생성을 클릭합니다.

네트워킹에서 VPC 생성 옵션은 클러스터에서 사용할 신규 VPC를 생성할 때 사용하는 옵션으로 이미 VPC가 구성되어 있고 해당 VPC에서 어플리케이션을 서비스 할 경우 생략 하고 진행하면 되겠습니다.


 - 서비스 생성

클러스터를 생성 확인을 한 후 해당 클러스터를 클릭하면 해당 클러스터에 서비스를 작성 할 수 있습니다.

AWS ECS에서 서비스는 작업 정의에서 정의된 작업들을 실제로 운용 하는 말그대로 서비스 단위 라고 할 수 있습니다. 모놀리식 서비스라면 전체 어플리케이션의 서비스를 뜻하겠고 마이크로서비스 라면 각각의 모듈서비스 들이 될 수 있습니다..

클러스터 내에서는 각각의 서비스들은 작업 정의에서 정해진 작업들을 기반으로 네트워크 설정, 가용성 설정등을 하여 실제 서비스를 구현합니다.


서비스 생성을 위해서 클러스터 상세페이지에서 서비스 탭의 생성 버튼을 클릭합니다.


서비스 생성에서 1단계는 서비스 구성으로 다음과 같은 항목을 입력합니다.

시작 유형은 FARGATE를 선택, 작업 정의는 사용할 작업과 Revision을 선택합니다. Revision(개정)은 작업 정의에서 해당 작업에서 새로운 버전 업데이트 또는 작업의 설정이 변경할 경우 새로운 버전을 뜻합니다.

플랫폼 버전은 ECS에서 FARGATE를 선택한 경우 FARGATE의 플랫폼 버전을 뜻하며 최신으로 선택하였습니다.

클러스터는 기존에 구성한 클러스터중 포함될 클러스터를 선택합니다.

작업 개수 및 최소 정상 상태 백분율, 최대 백분율은 배포랑 가용성과 연관된 항목으로 자세한 내용은 다음 글에서 기재하도록 하고 현재는 작업 개수를 2개 적용하고 다음 단계를 눌러 단계 2로 넘어갑니다.





서비스 생성 2단계는 네트워크 구성입니다.

기존에 사용중인 VPC 및 서브넷을 입력해 줍니다. 가용성을 위해 서브넷은 2개 이상의 가용 영역을 선택하며 보안그룹은 적당히 inbound에 80을 열어주면 되겠습니다. 추가로 보안을 위해 서브넷은 Private 망을 선택하였으며 퍼블릭 IP는 할당하지 않게 설정하였습니다.



아래로 스크롤을 내리면 ELB 설정을 할 수 있습니다. 상태 검사 유예 기간은 ELB에서 상태 검사를 진행시 유예 기간을 설정하는 것으로 너무 수치가 낮을 경우 작업이 시작시간이 다소 걸리는 경우 장애로 판정을 하고 이로 인해 계속 작업이 재시작 되는 경우가 있을 수 있습니다. 

Load Balancing은 타겟 그룹은 설정되지 않은 미리 작성된 Application Load Balancing을 사용하였습니다.

Route 53을 통한 DNS 설정은 해당 글에서는 다루지 않을 것이기 때문에 체크를 해제한 후 다음단계로 진행합니다.





3단계에서는 오토 스케일링 설정을 합니다. 실제 서비스를 구성할 경우 가용성 및 확장성을 위해 활성화를 시켜주시면 되고 현재는 데모용이기 때문에 비활성으로 진행합니다. Default는 비활성입니다.

3단계에서 다음단계를 선택 후 4단계는 검토를 한 후 하단의 서비스 생성을 클릭하면 서비스가 생성 됩니다.



 - 서비스 확인

서비스가 완성되면 다음과 같이 서비스 상태가 PROVISIOING -> Pending -> RUNNING의 순서로 바뀌며 실행중인 개수와 대기중인 개수도 변동하게 됩니다. 또한 FARGATE는 로드 밸런스의 컨트롤 하에 사용자가 설정한 원하는 개수에 맞춰 정상 작업을 유지시켜 줍니다.  



미리 작성 했었던 Application Load Balancing의 DNS의 주소를 브라우저에 입력하면 다음과 같이 Hello World! 가 출력됩니다.




지금까지 AWS ECS fargate를 사용하여 Appilication을 최초로 배포 하였습니다. 다음글에서는 도커 이미지 또는 작업이 업데이트 되는 경우와 기타 옵션들에 대해 좀 더 자세히 확인하는 내용이 될 예정입니다.


+ Recent posts