흑우마스터의 마법의 공간

.NET으로 만든 AWS ECR Docker Image를 리눅스에 배포하고 자동 업데이트(WatchTower)와 함께 실행하기 본문

프로그래밍/Docker

.NET으로 만든 AWS ECR Docker Image를 리눅스에 배포하고 자동 업데이트(WatchTower)와 함께 실행하기

흑우마스터 2023. 8. 18. 17:40

 

 

Visual Studio 2022+에서 AWS Toolkit을 활용하여 AWS ECR Registry에 소스 코드 배포하기

AWS Toolkit for Visual Studio 2022을 사용하여 비주얼스튜디오에 AWS에 쉽게 코드를 배포하거나 도커, 서비스를 배포할 수 있다. 도커 배포를 활용해서 리눅스에도 쉽게 배포는 가능했지만 공개 된 이미

blackcowmaster.tistory.com

 

지난 게시물에서 .NET Core 서비스를 도커 형태로 AWS ECR 저장소에 배포해보았다. 이제 배포 된 것을 리눅스 계열에 배포할 수 있어야 되는데 백엔드 포지션을 가지고 있지 않고서는 도커와 리눅스를 접하기가 쉽지 않다.  그리고 CI/CD라는 말을 들었겠지만 사실 이 것 역시 젠킨스나 깃헙 액션을 잘 안 썼다면 ECR에 올라간 내 코드를 가지고 무언가 작업을 한다는 건 쉽지 않다.

 

우선 올리는데까지는 성공했는데 이 게시물에서는 도커 실행자동 업데이트에 포커스를 맞춰 보고 싶다. ECR에 올렸기 때문에 Fargate형태로 클러스터를 만들어 순차 업데이트 전략까지 한방에 해결할 수도 있겠지만 EC2에 배포할 수도 있고 별도의 리눅스 서버를 운용했을 때를 가정해서 딱 저 두가지만 맞춰서 이야기 해보자.

 

테스트 환경은 AWS Lightsail로 잡고 진행한다. 이미 리눅스 서버가 있다면 아래 과정을 일부 스킵 해도 상관 없다.

 

어떤 형태던 좋다. AWS를 쓴다면 Lightsail로 시작해도 좋고 염가 VPS(iwinv, conoha, vultr, linode etc) 를 써도 좋다. 리눅스를 일단 설치하자.  업체에 따라 docker가 포함 된 버전을 인스턴스로도 만들 수 있는 옵션이 존재한다.

 

다만 나는 AWS Lightsail을 추천한다. 무료로 쓸 수 있는 조건이 존재하기 때문에 충분히 테스트 할 수 있기 때문이다.

 

 

Ubuntu 인스턴스를 만들었다면 다음과 같은 화면을 만날 수 있으며 로컬 환경이라면 putty나 다른 클라이언트 화면일 수 있다

 

sudo apt-get update
sudo apt install docker.io
sudo apt install docker-compose

 

sudo apt install docker.io 명령어가 되지 않는다면 apt-get update를 통해 사전에 업데이트를 해야 커맨드를 먹히고 순차로 다음 패키지들을 설치한다.  그럼 Ubuntu에서 도커 이미지를 받거나 실행할 수 있는 환경이 갖춰지고 Docker-Compose는 도커를 구동하기 전에 사전 설치 파일 스크립트 같은 느낌으로 이해하면 된다.  환경설정, 받을 이미지, 열어야 되는 포트 등 다양한 정보를 담고 있으며 개별 실행하지 않고 단순 명령어를 통해서 일괄 실행하거나 종료 할 수 있다.

 

sudo apt install awscli

#설치가잘되었다면
aws --version

 

이제 Ubuntu 환경에서 aws 제어를 할 수 있는 상황이 갖춰져 있으며 CLI로 제어를 하기 위해 IAM 설정을 해야 된다. 

 

 

사용자에 들어와서 사용자를 추가 하면 된다. 이 전 게시물에서 Visual Studio 2022에 AWS Toolkit을 연결했다면 이미 계정이 있겠지만 IAM 설정에 거의 Admin에 준하는 권한을 부여하지 않았다면 권한을 추가를 해야 된다.

(사용자를 추가할 때 나오는 엑세스키와 시크릿키를 가지고 있자! Visual Studio 2022에만 필요한게 아니라 이 게시물에서도 써야 된다)

 

AmazonEC2ContainerRegistryFullAccess 혹은 Read 를 부여해야 최소한 이미지를 가져와서 뭘 해볼 수 있으며 권한을 추가했다면 다시 터미널로 복귀해서 작업을 이어 갈 수 있다. 터미널에 다음과 같이 입력하자

 

aws configure

 

순차적으로 엑세스 키와 함께 관련 정보를 입력하게 되는데 대부분 리전을 서울(ap-northeast-2)로 선택했을테지만 다르다면 리전명을 다르게 입력하자

 

mkdir watchtower
cd watchtower

 

이제 watchtower라는 폴더를 임의로 만들고 그 안으로 들어갔다.  게시물 위에서 언급했던 것을 떠올려보면 docker-compose 라는 녀석이 셋업 스크립트 같은 걸 한다고 말한걸 기억하는가?  docker-compose 을 동작하기 위해서는 docker-compose.yml 이라는 파일이 필요하다. 하지만 우린 폴더를 만들고 아무것도 없으니 docker-compose.yml 파일을 만들어야 된다.

 

이제 여기서 리눅스를 모르는 사용자라면 패닉에 빠진다. 편집기? git에서 받아와야 되나? ftp? 끌어다 놓을 수 있나? 하고 말이다. 이때는 간단하게 다음과 같이 입력한다

 

sudo nano docker-compose.yml

 

nano는 리눅스에서 제공하는 명령줄 편집기로 윈도우로치면 그냥 메모장 같은 애다. 파라미터로 파일명을 추가로 던질 수 있고 이미 존재한다면 그 파일을 열어주기도 한다. 이제 여기서부터 중요하다

 

version: '3.7'
services:
  my-service:
	image: [ECR에 있던 프라이빗 리파짓토리의 이미지 경로]
	ports:
 	  - "80:80"
 	  - "443:443"

  watchtower:
	command: --interval 30 --cleanup
	environment:
		AWS_ACCESS_KEY_ID: [엑세스키]
		AWS_SECRET_ACCESS_KEY: [시크릿키]
	image: elephantventures/watchtower-ecr:latest
	volumes:
 		- /var/run/docker.sock:/var/run/docker.sock

 

포트가 없다면 삭제해도 무방하며 이 내용을 긁어서 붙여넣기하고 리포지토리에서 적용하고자 하는 녀석의 경로를 바꿔치기 한 후 엑세스 키와 시크릿 키를 넣으면 된다.

 

 

여기서 중요한 점은 서비스가 2개라는 점이다 하나는 my-service 라는 것과 watchtower이다. my-service른 동작하고자 하는 서비스의 이름이다.  그리고 나머지 하나는 watchtower이다. watchtower는 이미 동작 중인 도커 컨테이너의 이미지의 경로를 추적해 일정 주기마다 변경점이 발생되면 새로운 버전으로 업데이트 하는 도커 이미지다.

 

https://hub.docker.com/r/containrrr/watchtower

 

Docker

 

hub.docker.com

 

원래는 위 도커 이미지가 가장 알려져 있지만 amazon-ecr-credential-helper 가 포함되어 있지 않는 말그대로 범용 이미지이다. 이걸 받아서 수동으로 적용할 수는 있지만 docker hub까지는 어떻게 할 수 있어도 ECR에 있는 이미지를 가져오려고 하면 Basic 인증을 하지 못해서 못 받아왔다는 로그를 만나 볼 수 있으니 아래 이미지를 쓰는 것이다.

 

https://hub.docker.com/r/elephantventures/watchtower-ecr

 

Docker

 

hub.docker.com

 

docker-Compose.yml이 알아서 이미지도 서버에서 받아서 세팅까지 다 해줄테니 일단 이해만 하고 저장하도록 하자. 근데 저장은 어떻게 할까? 바로 Ctrl+O를 해서 작성을 종료하고 Ctrl+X를 해서 종료 하면 된다. 이제 watchtower가 ecr을 가져올 수 있도록 작업을 하나 더 해줘야 된다.

 

aws ecr get-login-password --region [리전 코드] | 
sudo docker login --username AWS --password-stdin [ECR 도커 이미지 경로]

#아래는 예시입니다
aws ecr get-login-password --region ap-northeast-2 | 
sudo docker login --username AWS --password-stdin 12321fef1242.dkr.ecr.ap-northeast-2.amaz
onaws.com

 

위 코드를 동작하면 ECR 도커 이미지에 대한 도커 로그인에 성공했다.  이제 Docker-Compose를 해보자

 

#실행
sudo docker-compose up -d

#종료
sudo docker-compose stop

#실행중인지 체크
sudo docker ps

실행 키워드로 동작을 하게 되면 바쁘게 ECR 리포지토리에서 도커 이미지를 다운 받는 모습을 볼 수 있다. 그리고 서비스를 생성하면 다음 메시지를 드디어 만나 볼 수 있다

 

실행 중인지 sudo docker ps로 보게 되면 동작  중인 컨테이너와 활성화 된 포트를 같이 확인할 수 있다

(나는 80과 443을 열었지만 때에 따라 다르게 주거나 포트 부분을 날려도 무방하다)

 

 

일반적인 도커 이미지를 컨테이너로 만들어서 열고 또 docker-compose를 통해서 여는 것과 조금 다를 순 있지만 이 방법을 따라하면 AWS ECR에 비주얼스튜디오에서 작업한 코드를 도커 형태로 배포할 수 있고 배포가 진행 될 때마다 watchtower에서 일정 주기에 따라 감시하고 있다가 자동으로 업데이트를 하게 된다.

 

단점으로는 이 방법은 무중단 서비스가 되지 않기 때문에 별도의 cron 방식을 통해서 스케쥴링을 하던지 아니면 treafik을 활용하는 방법도 있을테고 가장 확실한 도커 스웜이나 쿠버네티스 같은 오케스트레이션을 써서 할 수도 있겠지만 사실 그걸 다 잘 사용한다면 이 글을 보고 있진 않을 것 같다. 

 

다음 포스트는 AWS를 전적으로 사용한다는 전제하에 .NET 서비스를 AWS Fargate 형태로 클러스터를 구성해서 로드밸런스까지 한번에 하는 방식을 Toolkit에서 제공하기 때문에 이 것을 다뤄보고자 한다. 

(AWS에서 서비스를 한다면 이 방식을 추천하고 도커도 모르고 리눅스도 모르고 AWS도 모르는 닷넷개발자라면 이게 맞다)

 

쓰다보니 전 과정을 다 쓴 것 같아 서글프다. 이 삽질이 누군가에게 도움은 되겠지..?