AWS Batch는 배치 컴퓨팅 작업을 효율적으로 실행할 수 있게 도와줍니다. 배치 작업량과 리소스 요청을 기반으로 최적의 리소스 수량 및 인스턴스 유형을 동적으로 프로비져닝합니다. AWS Batch에서는 별도의 관리가 필요 없기 때문에 문제 해결에 집중할 수 있습니다. 별도의 추가 비용은 없습니다. 배치 작업을 저장 또는 실행할 목적으로 생성된 AWS 리소스(인스턴스 등)에 대해서만 비용을 지불하면 됩니다. 이번 포스팅에서는 간단한 튜토리얼로 AWS Batch 사용 방법을 크게 11개의 Step으로 알아보겠습니다.
AWS Batch helpers페이지에 접속합니다.
2. /fetch-and-run/에서 Dockerfile, fetchandrun.sh, myjob.sh 다운로드합니다.
Dockerfile을 이용해서 Docker 이미지를 빌드합니다.
잠시 Dockerfile의 내용을 살펴보겠습니다.
FROM amazonlinux:latest
Docker 공식 Repository에 있는 amazonlinux 의 lastest 버젼으로 빌드
RUN yum -y install which unzip aws-cli
RUN을 통해 이미지 빌드 시에 yum -y install which unzip aws-cli를 실행
ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.sh
ADD를 통해 Dockerfile과 같은 디렉토리에 있는 fetch_and_run.sh를 /usr/local/bin/fetch_and_run.sh에 복사
WORKDIR /tmp
컨테이너가 동작할 때 /tmp를 기본 디렉토리로 설정
USER nobody
컨테이너 실행 시 기본 유저 설정
ENTRYPOINT [“/usr/local/bin/fetch_and_run.sh”]
컨테이너 실행 시 /usr/local/bin/fetch_and_run.sh를 call
shell에 docker 명령을 통해 이미지 생성
shell : docker build -t fetch_and_run .
실행하면 아래와 같은 결과가 출력됩니다.
[ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker build -t fetch_and_run . Sending build context to Docker daemon 8.192kB Step 1/6 : FROM amazonlinux:latest latest: Pulling from library/amazonlinux 4b92325dc37b: Pull complete Digest: sha256:9ee13e494b762db41b9db92a200f6784b78da5ac3b0f974fb1c38feb7f636474 Status: Downloaded newer image for amazonlinux:latest ---> 81bb3e78db3d Step 2/6 : RUN yum -y install which unzip aws-cli ---> Running in 1f5293a2294d Loaded plugins: ovl, priorities Resolving Dependencies --> Running transaction check ---> Package aws-cli.noarch 0:1.14.9-1.48.amzn1 will be installed --> Processing Dependency: python27-jmespath = 0.9.2 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-botocore = 1.8.13 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-rsa >= 3.1.2-4.7 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-futures >= 2.2.0 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-docutils >= 0.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-colorama >= 0.2.5 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-PyYAML >= 3.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: groff for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: /etc/mime.types for package: aws-cli-1.14.9-1.48.amzn1.noarch ---> Package unzip.x86_64 0:6.0-4.10.amzn1 will be installed ---> Package which.x86_64 0:2.19-6.10.amzn1 will be installed --> Running transaction check ---> Package groff.x86_64 0:1.22.2-8.11.amzn1 will be installed --> Processing Dependency: groff-base = 1.22.2-8.11.amzn1 for package: groff-1.22.2-8.11.amzn1.x86_64 ---> Package mailcap.noarch 0:2.1.31-2.7.amzn1 will be installed ---> Package python27-PyYAML.x86_64 0:3.10-3.10.amzn1 will be installed --> Processing Dependency: libyaml-0.so.2()(64bit) for package: python27-PyYAML-3.10-3.10.amzn1.x86_64 ---> Package python27-botocore.noarch 0:1.8.13-1.66.amzn1 will be installed --> Processing Dependency: python27-dateutil >= 2.1 for package: python27-botocore-1.8.13-1.66.amzn1.noarch ---> Package python27-colorama.noarch 0:0.2.5-1.7.amzn1 will be installed ---> Package python27-docutils.noarch 0:0.11-1.15.amzn1 will be installed --> Processing Dependency: python27-imaging for package: python27-docutils-0.11-1.15.amzn1.noarch ---> Package python27-futures.noarch 0:3.0.3-1.3.amzn1 will be installed ---> Package python27-jmespath.noarch 0:0.9.2-1.12.amzn1 will be installed --> Processing Dependency: python27-ply >= 3.4 for package: python27-jmespath-0.9.2-1.12.amzn1.noarch ---> Package python27-rsa.noarch 0:3.4.1-1.8.amzn1 will be installed --> Processing Dependency: python27-pyasn1 >= 0.1.3 for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Processing Dependency: python27-setuptools for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Running transaction check ---> Package groff-base.x86_64 0:1.22.2-8.11.amzn1 will be installed ---> Package libyaml.x86_64 0:0.1.6-6.7.amzn1 will be installed ---> Package python27-dateutil.noarch 0:2.1-1.3.amzn1 will be installed --> Processing Dependency: python27-six for package: python27-dateutil-2.1-1.3.amzn1.noarch ---> Package python27-imaging.x86_64 0:1.1.6-19.9.amzn1 will be installed --> Processing Dependency: libjpeg.so.62(LIBJPEG_6.2)(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libjpeg.so.62()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libfreetype.so.6()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 ---> Package python27-ply.noarch 0:3.4-3.12.amzn1 will be installed ---> Package python27-pyasn1.noarch 0:0.1.7-2.9.amzn1 will be installed ---> Package python27-setuptools.noarch 0:36.2.7-1.33.amzn1 will be installed --> Processing Dependency: python27-backports-ssl_match_hostname for package: python27-setuptools-36.2.7-1.33.amzn1.noarch --> Running transaction check ---> Package freetype.x86_64 0:2.3.11-15.14.amzn1 will be installed ---> Package libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1 will be installed ---> Package python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1 will be installed --> Processing Dependency: python27-backports for package: python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1.noarch ---> Package python27-six.noarch 0:1.8.0-1.23.amzn1 will be installed --> Running transaction check ---> Package python27-backports.x86_64 0:1.0-3.14.amzn1 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================
Package Arch Version Repository Size ================================================================================
Installing:
aws-cli noarch 1.14.9-1.48.amzn1 amzn-main 1.2 M
unzip x86_64 6.0-4.10.amzn1 amzn-main 201 k
which x86_64 2.19-6.10.amzn1 amzn-main 41 k
Installing for dependencies:
freetype x86_64 2.3.11-15.14.amzn1 amzn-main 398 k
groff x86_64 1.22.2-8.11.amzn1 amzn-main 1.3 M
groff-base x86_64 1.22.2-8.11.amzn1 amzn-main 1.1 M
libjpeg-turbo x86_64 1.2.90-5.14.amzn1 amzn-main 144 k
libyaml x86_64 0.1.6-6.7.amzn1 amzn-main 59 k
mailcap noarch 2.1.31-2.7.amzn1 amzn-main 27 k
python27-PyYAML x86_64 3.10-3.10.amzn1 amzn-main 186 k
python27-backports x86_64 1.0-3.14.amzn1 amzn-main 5.0 k
python27-backports-ssl_match_hostname
noarch 3.4.0.2-1.12.amzn1 amzn-main 12 k
python27-botocore noarch 1.8.13-1.66.amzn1 amzn-main 4.1 M
python27-colorama noarch 0.2.5-1.7.amzn1 amzn-main 23 k
python27-dateutil noarch 2.1-1.3.amzn1 amzn-main 92 k
python27-docutils noarch 0.11-1.15.amzn1 amzn-main 1.9 M
python27-futures noarch 3.0.3-1.3.amzn1 amzn-main 30 k
python27-imaging x86_64 1.1.6-19.9.amzn1 amzn-main 428 k
python27-jmespath noarch 0.9.2-1.12.amzn1 amzn-main 46 k
python27-ply noarch 3.4-3.12.amzn1 amzn-main 158 k
python27-pyasn1 noarch 0.1.7-2.9.amzn1 amzn-main 112 k
python27-rsa noarch 3.4.1-1.8.amzn1 amzn-main 80 k
python27-setuptools noarch 36.2.7-1.33.amzn1 amzn-main 672 k
python27-six noarch 1.8.0-1.23.amzn1 amzn-main 31 k Transaction Summary ================================================================================ Install 3 Packages (+21 Dependent packages) Total download size: 12 M Installed size: 51 M Downloading packages: -------------------------------------------------------------------------------- Total 1.0 MB/s | 12 MB 00:12 Running transaction check Running transaction test Transaction test succeeded
Running transaction
Installing : python27-backports-1.0-3.14.amzn1.x86_64 1/24
Installing : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1 2/24
Installing : python27-setuptools-36.2.7-1.33.amzn1.noarch 3/24
Installing : python27-colorama-0.2.5-1.7.amzn1.noarch 4/24
Installing : freetype-2.3.11-15.14.amzn1.x86_64 5/24
Installing : libyaml-0.1.6-6.7.amzn1.x86_64 6/24
Installing : python27-PyYAML-3.10-3.10.amzn1.x86_64 7/24
Installing : mailcap-2.1.31-2.7.amzn1.noarch 8/24
Installing : python27-ply-3.4-3.12.amzn1.noarch 9/24
Installing : python27-jmespath-0.9.2-1.12.amzn1.noarch 10/24
Installing : python27-futures-3.0.3-1.3.amzn1.noarch 11/24
Installing : python27-six-1.8.0-1.23.amzn1.noarch 12/24
Installing : python27-dateutil-2.1-1.3.amzn1.noarch 13/24
Installing : groff-base-1.22.2-8.11.amzn1.x86_64 14/24
Installing : groff-1.22.2-8.11.amzn1.x86_64 15/24
Installing : python27-pyasn1-0.1.7-2.9.amzn1.noarch 16/24
Installing : python27-rsa-3.4.1-1.8.amzn1.noarch 17/24
Installing : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64 18/24
Installing : python27-imaging-1.1.6-19.9.amzn1.x86_64 19/24
Installing : python27-docutils-0.11-1.15.amzn1.noarch 20/24
Installing : python27-botocore-1.8.13-1.66.amzn1.noarch 21/24
Installing : aws-cli-1.14.9-1.48.amzn1.noarch 22/24
Installing : which-2.19-6.10.amzn1.x86_64 23/24
Installing : unzip-6.0-4.10.amzn1.x86_64 24/24
Verifying : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64 1/24
Verifying : groff-1.22.2-8.11.amzn1.x86_64 2/24
Verifying : unzip-6.0-4.10.amzn1.x86_64 3/24
Verifying : python27-pyasn1-0.1.7-2.9.amzn1.noarch 4/24
Verifying : groff-base-1.22.2-8.11.amzn1.x86_64 5/24
Verifying : aws-cli-1.14.9-1.48.amzn1.noarch 6/24
Verifying : python27-six-1.8.0-1.23.amzn1.noarch 7/24
Verifying : python27-dateutil-2.1-1.3.amzn1.noarch 8/24
Verifying : python27-docutils-0.11-1.15.amzn1.noarch 9/24
Verifying : python27-PyYAML-3.10-3.10.amzn1.x86_64 10/24
Verifying : python27-botocore-1.8.13-1.66.amzn1.noarch 11/24
Verifying : python27-futures-3.0.3-1.3.amzn1.noarch 12/24
Verifying : python27-ply-3.4-3.12.amzn1.noarch 13/24
Verifying : python27-jmespath-0.9.2-1.12.amzn1.noarch 14/24
Verifying : mailcap-2.1.31-2.7.amzn1.noarch 15/24
Verifying : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1 16/2
4
Verifying : libyaml-0.1.6-6.7.amzn1.x86_64 17/24
Verifying : python27-rsa-3.4.1-1.8.amzn1.noarch 18/24
Verifying : freetype-2.3.11-15.14.amzn1.x86_64 19/24
Verifying : python27-colorama-0.2.5-1.7.amzn1.noarch 20/24
Verifying : python27-setuptools-36.2.7-1.33.amzn1.noarch 21/24
Verifying : which-2.19-6.10.amzn1.x86_64 22/24
Verifying : python27-imaging-1.1.6-19.9.amzn1.x86_64 23/24
Verifying : python27-backports-1.0-3.14.amzn1.x86_64 24/24
Installed:
aws-cli.noarch 0:1.14.9-1.48.amzn1 unzip.x86_64 0:6.0-4.10.amzn1
which.x86_64 0:2.19-6.10.amzn1
Dependency Installed:
freetype.x86_64 0:2.3.11-15.14.amzn1
groff.x86_64 0:1.22.2-8.11.amzn1
groff-base.x86_64 0:1.22.2-8.11.amzn1
libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1
libyaml.x86_64 0:0.1.6-6.7.amzn1
mailcap.noarch 0:2.1.31-2.7.amzn1
python27-PyYAML.x86_64 0:3.10-3.10.amzn1
python27-backports.x86_64 0:1.0-3.14.amzn1
python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1
python27-botocore.noarch 0:1.8.13-1.66.amzn1
python27-colorama.noarch 0:0.2.5-1.7.amzn1
python27-dateutil.noarch 0:2.1-1.3.amzn1
python27-docutils.noarch 0:0.11-1.15.amzn1
python27-futures.noarch 0:3.0.3-1.3.amzn1
python27-imaging.x86_64 0:1.1.6-19.9.amzn1
python27-jmespath.noarch 0:0.9.2-1.12.amzn1
python27-ply.noarch 0:3.4-3.12.amzn1
python27-pyasn1.noarch 0:0.1.7-2.9.amzn1
python27-rsa.noarch 0:3.4.1-1.8.amzn1
python27-setuptools.noarch 0:36.2.7-1.33.amzn1
python27-six.noarch 0:1.8.0-1.23.amzn1
Complete!
Removing intermediate container 1f5293a2294d
---> 5502efa481ce Step 3/6 : ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.sh
---> 1b69173e586f Step 4/6 : WORKDIR /tmp Removing intermediate container a69678c65ee7
---> 8a560dd25401 Step 5/6 : USER nobody
---> Running in e063ac6e6fdb Removing intermediate container e063ac6e6fdb
---> e5872fd44234 Step 6/6 : ENTRYPOINT ["/usr/local/bin/fetch_and_run.sh"]
---> Running in e25af9aa5fdc Removing intermediate container e25af9aa5fdc
---> dfca872de0be Successfully built dfca872de0be
Successfully tagged awsbatch-fetch_and_run:latest
docker images 명령으로 새로운 로컬 repository를 확인할 수 있습니다.
shell : docker images
[ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE fetch_and_run latest dfca872de0be 2 minutes ago 253MB
amazonlinux latest 81bb3e78db3d 2 weeks ago 165MB
아래는 ECR 초기 화면입니다.
fetch_and_run이란 이름으로 Repository 생성합니다.
3. Repository 생성이 완료되었습니다.
shell : aws ecr get-login --no-include-email --region ap-northeast-2
shell : docker tag fetch_and_run:latest 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:latest
shell: docker push 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_rrun:latest
#!/bin/bash
date
echo "Args: $@"
env
echo "This is my simple test job!."
echo "jobId: $AWS_BATCH_JOB_ID"
sleep $1
date
echo "bye bye!!"
shell : aws s3 cp myjob.sh s3:///myjob.sh
Role 등록 화면에서 Elastic Container Service 선택 후, Elastic Container Service Task를 선택합니다.
AmazonS3ReadOnlyAccess Policy를 선택합니다.
아래 이미지는 Role에 등록 하기 전 리뷰 화면입니다.
Role에 AmazonS3ReadOnlyAccess가 등록된 것을 확인합니다.
AWS Batch 콘솔에서 Compute environments를 선택하고, Create environment 선택합니다.
Compute environment type은 Managed와 Unmanaged 두 가지를 선택할 수 있습니다. Managed는 AWS에서 요구사항에 맞게 자원을 관리해주는 것이고, Unmanaged는 직접 자원을 관리해야 합니다. 여기서는 Managed를 선택하겠습니다.
Compute environment name을 입력합니다.
Service Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할 (AWSBatchServiceRole)이 생성됩니다.
Instnace Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할(ecsInstanceRole)이 생성됩니다.
EC2 key pair에서 기존 EC2 key pair를 선택합니다. 이 key pair를 사용하여 SSH로 인스턴스에 접속할 수 있지만 이번 글의 예제에서는 선택하지 않겠습니다.
Configure your compute resources Provisioning Model은 On-Demand와 Spot이 있습니다. 차이점은 Amazon EC2 스팟 인스턴스를 참고해주세요. 여기서는 On-Demand를 선택합니다.
Allowed instance types에서는 시작 인스턴스 유형을 선택합니다. optimal을 선택하면 Job queue의 요구에 맞는 인스턴스 유형을 (최신 C, M, R 인스턴스 패밀리 중) 자동으로 선택합니다. 여기서는 optimal을 선택하겠습니다.
Minimum vCPUs는 Job queue 요구와 상관없이 Compute environments에 유지할 vCPU 최소 개수입니다. 0을 입력해주세요.
Desired vCPUs는 Compute environment에서 시작할 EC2 vCPU 개수입니다. Job queue 요구가 증가하면 필요한 vCPU를 Maximum vCPUs까지 늘리고 요구가 감소하면 vCPU 수를 Minimum vCPUs까지 줄이고 인스턴스를 제거합니다. 0을 입력해주세요.
Maximum vCPUs는 Job queue 요구와 상관없이 Compute environments에서 확장할 수 있는 EC2 vCPU 최대 개수입니다. 여기서는 256을 입력합니다.
Enable user-specified Ami ID는 사용자 지정 AMI를 사용하는 옵션입니다. 여기서는 사용하지 않겠습니다.
Networking VPC Id 인스턴스를 시작할 VPC를 선택합니다.
Subnet을 선택합니다.
Security groups를 선택합니다.
그리고 EC2 tags를 지정하여 생성된 인스턴스가 이름을 가질 수 있게 합니다.
Key : Name, Value : AWS Batch Instance
Create을 클릭해 Compute environment를 생성합니다.
아래 이미지는 생성된 Compute environment입니다.
AWS Batch 콘솔에서 Job queues - Create queue를 선택합니다.
Queue name을 입력합니다.
Priority는 Job queue의 우선순위를 입력합니다. 우선순위가 1인 작업은 우선순위가 5인 작업보다 먼저 일정이 예약됩니다. 여기서는 5를 입력하겠습니다.
Enable Job queue가 체크되어 있어야 job을 등록할 수 있습니다.
Select a compute environment에서 Job queue와 연결될 Compute environment을 선택합니다. 최대 3개의 Compute environment를 선택할 수 있습니다.
생성된 Job queue, Status가 VALID면 사용 가능합니다.
AWS Batch 콘솔에서 Job definitions - Create를 선택합니다.
Job definition name을 입력하고 이전 작업에서 만들 IAM Role을 선택하세요, 그리고 ECR Repository URI를 입력합니다.
000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run
Command 필드는 비워둡시다.
vCPUs는 컨테이너를 위해 예약할 vCPU의 수, Memory(Mib)는 컨테이너에 제공할 메모리의 제한, Job attempts는 작업이 실패할 경우 다시 시도하는 최대 횟수, Execution timeout은 실행 제한 시간, Ulimits는 컨테이너에 사용할 사용자 제한 값입니다. 여기서는 vCPUs는 1, Memory(MiB)는 512, Job Attempts는 1로 설정, Execution timeout은 기본값인 100 그리고 Limits는 설정하지 않습니다.
User는 기본값인 nobody로 선택 후, Create job definition을 선택합니다.
Job definitions에 Job definition이 생성된 것을 확인할 수 있습니다.
AWS Batch 콘솔에서 Jobs를 선택합니다. Job을 실행할 Queue를 선택하고 Submit job을 선택합니다.
Job run-time
1)Job name을 입력합니다.
2)Job definition을 선택합니다.
3)실행될 Job queue를 선택합니다.
Environment Job Type을 선택하는 부분에서는 Single을 선택합니다. Array 작업에 대한 자세한 내용은 어레이 작업 페이지를 참고해주세요.
Job depends on은 선택하지 않습니다.자세한 내용은 작업 종속성 페이지를 참고해주세요.
Environment Command에서 컨테이너에 전달할 명령을 입력합니다. 여기서는 [“myjob.sh”, “30”] 를 입력해주세요. vCPUs, Memory, Job attempts와 Execution timeout은 job definition에 설정된 값을 가져옵니다. 이 Job에 대한 설정도 가능합니다.
Parameters를 통해 job을 제출할 때 기본 작업 정의 파라미터를 재정의 할 수 있습니다. Parameters에 대한 자세한 내용은 작업 정의 파라미터 페이지를 참고해주세요.
Environment variables는 job의 컨테이너에 환경 변수를 지정할 수 있습니다. 여기서 주의할 점은 Key를 AWS_BATCH로 시작하면 안 된다는 것입니다. AWS Batch에 예약된 변수입니다.
Key=BATCH_FILE_TYPE, Value=script Key=BATCH_FILE_S3_URL, Value=s3://
Submit job을 선택합니다.
Job이 Submitted 된 화면입니다.
Dashboard를 보시면 Runnable 상태로 대기 중인 것을 확인할 수 있습니다.
CloudWatch > Log Groups > /aws/batch/job에서 실행 로그를 확인할 수 있습니다.
간단한 튜토리얼로 AWS Batch를 설정하고 실행하는 방법을 알아봤습니다.(참 쉽죠?) 다음 글에서는 AWS Batch의 Array 또는 Job depends on등의 확장된 기능들을 살펴보겠습니다.
참고
1) AWS Batch – 쉽고 효율적인 배치 컴퓨팅 기능 – AWS
2) AWS Batch 시작하기 - AWS Batch
3) Amazon ECR의 도커 기본 사항 - Amazon ECR
글
윤석호 이사 | 브랜디 CTO
yunsh@brandi.co.kr
브랜디, 오직 예쁜 옷만
#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
관련 스택