최근 새로운 도전이라는 명목하에 병역을 해결하기 위해 새로운 회사로 이직했다.
이직 결정에 있어서 비단 병역에 대한 문제만이 아닌 여러 사항들이 작용했는데 이와 관련해서 다음에 따로 글을 작성하겠다.
현 회사에서 레거시에 대한 내용을 많이 강조했고 그와 관련해서 어느 정도의 레거시는 예상했으나, 실제로 마주한 레거시의 정도는 정말 역대라 표현할 만큼 거대했다.
가장 먼저 CI/CD 가 제대로 구현되지 못했고, 개발자들은 Remote server 에 소스를 동기화 시키는 형태로 개발하고 있었다.
따라서 본인은 비효울적인 기술 스택들을 걷어내고, AWS ECS/ECR 를 통해 CI/CD 를 새로 적용했다.
본 글은 이를 구성하며 정리한 내용을 담고있다.
위 다이어그램은 실질적 배포 프로세스를 구성하기 앞 서, 이해를 돕기위해 흐름에 대해 따로 정의한 내용이다.
배포 순서는 아래와 같다.
Pipeline 항목으로 이동하면 아래와 같이 정의한 Stage 에 대한 상태가 표기된다.
아래는 빌드 스펙이며, Node 환경에 맞추어져있다.
내용은 간단하다 프로젝트에 관련된 의존성들을 설치한 이후 Lint 와 Unit test 등을 수행하고 이후 빌드된 이미지를 ECR 에 Push 한다.
version: 0.2
phases:
install:
runtime-versions:
nodejs: 12
commands:
- echo "Install all of dependencies"
- npm install
pre_build:
commands:
- npm run lint
- npm run test
- $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
build:
commands:
- AWS_ACCOUNT_ID="$(aws sts get-caller-identity --output text --query Account)"
- IMAGE_TAG="$(date '+%Y%m%d%H%M%S')"
- echo $IMAGE_TAG
- |
docker build . \
-f Dockerfile \
--build-arg ENV=dev \
--tag $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/{repo}:$IMAGE_TAG
- docker push $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/{repo}:$IMAGE_TAG
- |
printf '[{"name":"{service name}","imageUri":"%s"}]' \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/{repo}:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
CodePipeline은 빠르고 안정적인 애플리케이션 및 인프라 업데이트를 위해 릴리즈 파이프라인을 자동화하는 데 도움이 되는 완전관리형 지속적 전달 서비스이다.
코드 변경이 발생할 때마다 사용자가 정의한 릴리즈 모델을 기반으로 릴리즈 프로세스의 빌드, 테스트 및 배포 단계를 자동화한다.
ECR 은 말 그대로 Container Registry 이다.
개발자가 Docker 컨테이너 이미지를 손쉽게 저장, 관리 및 배포할 수 있게 해주는 완전관리형 Docker 컨테이너 레지스트리이다.
쉽게 생각하면 Private Docker Hub 라고 생각하면 된다.
ECS 에 사용하기 위해서 자신이 빌드한 Docker Image 를 ECR 에 업로드 하여 ECS 를 이용해서 배포 한다.
ECS는 완전 관리형 컨테이너 오케스트레이션 서비스이다.
다양한 오케스트레이션 서비스가 있으며 ECS 의 경우는 AWS 에서 자체 개발한 서비스 이다.
ECS의 장점은 다양한 AWS 기능과 통합이 쉽고 다른 서비스에 비해서 쉽게 적용이 가능하다.
컨테이너 오케스트레이션 도구에는 Docker에서 만든 Docker Swarm, 구글의 Kubernetes, 하시코프의 Nomad등 다양한 오케스트레이션 도구가 있다.
시작 유형에 있어서 적합성에 대해 고민 된다면 아래 항목을 참고하여 자신에게 맞는 유형을 선택해보길 바란다.
아래 아키텍쳐를 참고하면 이해에 도움이 편할 것 같다.
Docker 리포지토리 및 이미지, 메모리 및 CPU 요구 사항, 공유 데이터 볼륨, 컨테이너가 서로 연결되는 방식 을 지정한 JSON 템플릿의 정의 문서이다.
서비스에 등록할 수 있는 단일 작업 정의 파일에서 원하는 만큼의 작업을 실행 할수 있다.
또한 작업 정의 파일을 사용하면 애플리케이션 사양의 버전을 관리할 수도 있다.
Dockerfile 에서 이미지 빌드를 하다보면 수 많은 Run
명령어를 사용한다. 해당 명령어는 도커에서 이미지 레이어를 생성하게 되고 이 이미지 레이어는 게임에서 세이브 포인트 역할을 한다고 이해하면 편하다.
따라서 다음 번 도커 이미지 빌드 시, 해당 이미지를 캐싱하여 사용하기에 빌드 시간을 단축 시킨다. 다만 캐싱을 사용하지 않고 수행하는 경우도 존재하는데, Remote repository 에서 소스 코드를 받아와서 사용하는 경우 캐싱된 이미지 레이어를 사용하는 경우
변경된 소스가 반영되지 않는다. 따라서 CodeBuild
에서 Artifacts
항목에 Cache type
옵션을 설정해주길 바란다. (기본 값은 No Cache 이다)
제가 이직한 회사랑 비슷한 상황인 것 같네요.. 참고 하겠습니다!