Github 로 Fargate 배포

NOLEM·2020년 8월 26일
1

클라우드&플랫폼

목록 보기
2/2
post-thumbnail

리전별 저장소 배포 문제

글로벌 서비스에서 개인정보등의 여러 이유로 멀티 리전에 서비스를 배포하고 있다. AWS는 리전별로 서비스들이 상당히 독립적이어서 codecommit을 통해 배포하는데 상당히 어려움이 있다. 특히 각 리전별로 분리된 codecommit은 자동 동기화를 하는 옵션이 없어서 별도의 서비스(lambda 등)를 이용하지 않는 이상은 수동 관리하는데 한계가 있다. 이를 해결하기 위해 배포파이프라인은 각 리전별 codepipeline을 유지하고 형상관리 서비스만 github로 이관하기로 한다.

CodePipeline의 build, deploy 단계에 region을 선택하는 기능이 2018-11-12에 추가되었다.

Github 준비

개인 서비스가 아닌 경우, 가급적 관리 및 이관을 위해 organization 을 별도로 생성한다. Free Tier 로도 충분히 사용할 만 하다.

관련 AWS 서비스

codeDeploy

github에서 배포할 파일을 가져와서 EC2 에 배포할 때 주로 사용된다. CI가 안되므로 직접 CommitID 를 기입하여 배포한다. 빌드과정이 없는 단순 파일 전송이라고 이해하면 편하다.

codePipeline

lambda 체이닝으로 지속적 배포를 하기 위한 도구이다. 이벤트 방식으로 동작하기 때문에 코드없이 체인을 연결하여 조작하기 편하게 되어 있다. 여전히 기능은 부족한 편이지만 lambda 를 활용하기 따라서 거의 제한은 없는 편이다.

codecommit

git 호스팅 서비스 중 하나이다. 기본적인 기능만 제공할 뿐, region간 동기화 지원이나 git-fork, git flow 에 대한 지원이 전혀 없어서 아쉬운 서비스이다.

ECR, Fargate 설정

IAM 계정 생성

root 계정을 그대로 사용하여 작업하면 많은 위험이 따른다. 그래서 별도의 권한을 가진 계정을 생성하여 사용하는 것이 일반적이다. 실제 USER가 아닌 자동화에 사용되는 계정이라도 별도로 생성하는 것이 일반적이다.

용도에 맞게 선택한다.

권한은 나중에 조정해야겠지만, 아래 2가지를 넣어준다.

  • AmazonEC2ContainerRegistryFullAccess
  • AmazonEC2ContainerServiceFullAccess

각각 ECR과 ECS를 위한 권한이 부여된다.

ROOT 계정과 IAM 보안 관련하여 아래 사항을 확인한다.

  • 루트 사용자의 액세스 키 삭제
  • 루트 사용자의 MFA 활성화
  • 개별 IAM 사용자 생성
  • 그룹을 사용하여 권한 할당
  • IAM 비밀번호 정책 적용

Aws Cli 설치

docker를 이용하는게 더 낫지만, WSL1에서 사용에 제약이 있으므로 스크립트 방식으로 설치한다.

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

aws --version
aws configure # IAM에서 받은 정보를 넣는다.

Dockerfile

fargate는 container로 배포하는 방식이어서 docker image 를 구성하고 aws 의 컨테이너 스토리지인 ECR에 배포를 한다.

# multi-stage build dockerfile

FROM node:10 as builder

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn install

ADD public ./public
ADD src ./src
ADD config-overrides.js ./

RUN yarn build

FROM nginx:1.17-alpine

ADD config/nginx.conf /etc/nginx/nginx.conf

COPY --from=builder /app/build/ /var/www/html

EXPOSE 80

Docker build (WSL1)

Dockerfile 을 작성했으면 image를 생성해야 한다. 하지만 WSL2와 달리 WSL1에서는 Docker를 공식적으로 지원하지 않는다.

회사에서는 아직 2004 (WSL2 지원) 업데이트를 막아놓은 상태다 ㅠㅠ (2020-08-20)

알다시피, Docker는 Client와 Server로 이루어져 있다. 그 말은, Window에 Docker를 설치하고 WSL에 Client만 설치하여 연결하는게 가능하다는 거다.

  1. 먼저, Docker Desktop 에서 외부 포트를 허용한다.

  1. Docker CLI만을 사용하기 위해 바이너리로 설치한다.

https://download.docker.com/linux/static/stable/x86_64/

curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz
sudo tar xzvf docker-19.03.9.tgz --strip 1 -C /usr/local/bin docker/docker
rm docker-19.03.9.tgz

docker version
  1. Docker Desktop 과 연결

앞에서 설치한 Client 에서 Docker Desktop 을 바라보도록 설정한다.

export DOCKER_HOST=tcp://0.0.0.0:2375 # .zshrc에 포함시키자
docker version

docker run -dp 80:80 docker/getting-started # 테스트

잘 연결되었다 😁

ECR에 PUSH

ECR은 dockerhub 의 private 버전이라고 보면 된다. AWS의 다른 서비스들과 저렴한 네트워크 비용으로 연계를 쉽게 할 수 있다. 먼저 저장소 역할을 하는 ECR을 생성한다.

aws ecr create-repository --repository-name {{namespace}}/{{service-name}}

각 저장소에서 image PUSH하는 가이드를 확인할 수 있다

docker private login > docker build > docker tag > docker push

Fargate 작업 정의

ECS에서 최소 배포 단위를 Task라고 하며, 하나 이상의 컨테이너로 구성된다. 이러한 Task를 실행하기 위한 환경설정을 매번 넣을 수도 있지만, 반복된 작업을 줄이기 위해 미리 설정값들을 모아 놓은 것을 작업 정의 라고 한다.

작업 정의에서 AWS 다른 서비스들과의 연계(RDS 등)가 필요하다면 작업 역할을 필수값으로 추가한다.

사용할 리소스를 선택하고(최소 0.5gb, 0.25vcpu), 컨테이너에 사용할 이미지 URL을 입력하는데 외부 저장소를 사용하는 게 아니라면 ECR에서 복사해서 넣으면 된다. 포트는 서비스에서 사용하는 접속 포트를 지정해야 한다.

최초에 생성시에 ECS 에 부여되는 역할(ecsTaskExecutionRole) 을 생성해야 하므로 계정에 iam:createRole 권한이 부여되어 있어야 한다. 해당 역할이 이후 Fargate생성시마다 부여되게 된다.

클러스터 생성

EC2를 사용하지 않으므로, Fargate 전용으로 생성한다.

서비스 생성

클러스터를 생성 후, 서비스를 생성할 수 있다. 실제로 운영하는 서비스의 단위를 뜻한다고 보면 된다. 플랫폼 버전 및 대상 Task, 활성 복제본 수를 지정한다. 그 다음으로 VPC, SUBNET, 보안 정책 등을 설정한다. 테스트의 편의를 위해 ELB를 사용하지 않으므로 Public IP 할당에 체크한다. Public IP는 각 Task마다 할당되는 것에 주의한다.

이후에 최소 갯수로 줄어들게 된다
여기까지 하면 수동으로 ECR - Fargate를 통한 배포는 성공이다😎

CodePipeline을 통한 배포설정

codeCommit을 통한 배포 구조

github와 codepipeline의 cross-region 사용

CodeBuild

CodeBuild 에 빌드 과정을 전달하기 위해 root path에 buildspec.yaml을 작성한다.

# 기본 buildSpec yaml 파일

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG      
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

codePipeline 생성

파이프라인 역할 및 이름 설정

github 연동 및 대상 브랜치 설정

codebuild 구성할 때 특정 buildspec.yml 파일 지정이 가능

배포스테이지 설정은 이미 등록된 클러스터 및 서비스를 사용

codebuild 역할에 ECR권한 추가

pipeline 을 구동하면 아래처럼 에러가 발생한다.

컨테이너 빌드시에 ECR에서 이미 캐싱된 이미지를 가져와야 하기 때문에 해당 build 의 서비스 역할을 클릭하여 권한을 추가한다.

AmazonEC2ContainerRegistryPowerUser 가 ECR R/W를 가지므로 적절한 거 같다.

권한 준 이후, 깔끔하게 성공
Deploy는 로드밸런서를 만들지 않아서 실패하게 됨

참고

https://senticoding.tistory.com/91?category=790444
https://neo-blog.tistory.com/42?category=767817
https://blog.aliencube.org/ko/2018/04/11/running-docker-and-azure-cli-from-wsl/
https://docs.aws.amazon.com/ko_kr/codebuild/latest/userguide/sample-docker.html

0개의 댓글