NAT gateway로 Docker Hub 이미지를 호출하는 대신 AWS ECR과 VPC endpoint를 사용해보자

728x90

 

서론


지난 글에서 NAT gateway를 사용하여 private subnet에서 Docker Hub에 요청을 보내어 docker image를 가져오는 실습을 진행해봤다. 글을 마치면서 NAT gateway 단점으로 비용이 많이 발생한다는 것을 언급하였다. 실제로 서비스를 이용해보니 NAT gateway의 비용이 상당하게 부과되는 것을 경험하였다. 

아래는 글쓴이의 AWS Billing Dashboard의 청구서 페이지를 일부 캡쳐한 것이다.



NAT Gateway를 361시간 사용하고 21.3달러가 청구되었다. NAT gateway는 시간당 0.059 달러 비용이 발생하는 것이다. (리전마다 비용이 다르다.) 이는 꽤 부담스러운 가격이다. NAT gateway가 얼마나 비싼지 감이 안 온다면 아래 표도 참고해보자.



ELB(로드밸런서)의 요금이 청구된 페이지다. 글쓴이는 지금 AWS 프리티어를 제공받고 있으므로 473시간의 ELB는 무료로 제공받았다. 그 외 167시간의 ELB 사용량에 대해 3.76 달러가 청구된 것을 볼 수 있다. 시간당 0.022 달러가 청구되는 것이다. 

ELB와 비교해서 NAT gateway는 적게는 두 배에서 많게는 세 배의 시간당 요금이 청구되는 것이다. 심지어 NAT gateway는 ELB에 비해 이 프로젝트에서 하는 역할도 별로 없다. 그냥 Docker Hub 에서 이미지를 불러오는 것, 그것이 현재 NAT gateway의 역할의 전부다. 찰나의 순간에 동작할 기능을 사용하기 위해 너무 과한 요금을 지불하는 것이다. 


잠깐 image 가져오는 기능 한 번 쓰겠다고 4만원을 지불해야하다니... 뼈아프다. (4만원이면 치킨이 두 마리다.) 분명 개선해봐야 할 포인트라고 볼 수 있겠다. 다양한 기술적 검토를 통해 비용을 절약하는 것도 엔지니어에게 필요한 업무이기 때문이다. (절대 치킨이 아까워서가 아니다. 😂) 고비용의 NAT gateway를 사용하여 Docker image를 가져오는 대신 AWS ECR에 docker image를 담고 VPC Endpoint로 ECS에 불러들이는 방법을 사용하도록 하겠다.

업데이트


후술하겠지만, AWS ECR과 VPC Endpoint를 사용하는 방법은 NAT gateway를 사용하여 Docker Hub에서 이미지를 가져오는 것보다 저렴하지 않다. 오히려 비용이 더 든다. 그러므로 본 글은 NAT gateway에서 오는 비용을 절약하기 위해서가 아닌 단순히 AWS ECR이라는 대체 옵션을 선택하는 방법을 기술한 것으로 이해해주길 바란다. (이미지 저장소 사용 개수가 많다면 Docker Hub에 비해 AWS ECR이 더 저렴할 수도 있다.)

Docker Hub vs AWS ECR


AWS ECR(Elastic Container Registry)은 Docker Hub와 똑같은 기능을 제공한다. 그냥 docker image를 담고 있는 repository다. 서비스 요금은 Docker Hub와 조금 차이가 있다. 

Docker Hub 요금 체계

 

 



Docker Hub는 계정 당 하나의 private repository를 무료로 제공한다. 그 이상의 private repository를 사용하려면 계정을 유료계정으로 업그레이드 해야한다. (다만, Public repository는 무제한으로 무료로 제공된다.) image pull 횟수도 계정 레벨에 따라 한정되어있다. Pro계정을 사용하면 한달 5달러에 private repository를 무제한으로 사용할 수 있다. 

정리를 해보면 Docker Hub는 사용량에 따라 요금이 부과되는 형식이 아니라, 특정 요금 사용자에게 특정 서비스가 제공되는 요금 정액제 방식이라 볼 수 있다.

AWS ECR 요금 체계


AWS ECR은 Docker와는 다르게 사용량에 따라 요금이 부과된다. 

 

저장 용량에 대한 요금



public repository는 월 50GB가 무료로 제공된다. (도커 허브에서 public 저장소는 무제한으로 무료로 제공되는 것과는 다르다.) private repository는 신규 고객에 한해 1년 동안 월 500MB가 무료로 제공된다. 그 이상은 용량에 따라 요금이 청구된다.

 



프라이빗이든 퍼블릭이든 무료 사용 제공량을 초과한 사용량에 대해서는 GB당 0.1 달러가 부과된다. (이 사용량은 매달 초기화되므로 무료 제공량에 대해 초과한 용량은 매달 요금을 내야한다.)


데이터 전송에 대한 요금


Docker Hub와는 다르게 AWS는 pull에 대해서 사용량에 따라 요금이 부과된다. (image push는 docker hub와 마찬가지로 무료) private 저장소와 public 저장소의 전송 요금은 조금 다르다.

 

 



image push의 경우 그냥 퍼블릭, 프라이빗 둘 다 무료다.

퍼블릭 저장소에서 image pull하면 AWS 계정을 사용하면 월 5TB까지는 전송요금이 부과되지 않는다.

프라이빗 저장소에서 image pull하면 약 10TB까지는 GB당 0.126 달러가 부과된다. 그 이상 사용하면 요금이 단계별로 저렴해진다. 많이 쓸 수록 할인해주는 구조랄까? 10GB정도 pull하면 1.26달러가 청구될 것이다. 

 

AWS ECR + VPC Endpoint 요금 계산



전반적으로 AWS 서비스를 사용하지 않는다면, Docker Hub를 사용하는 것이 비용적으로 유리할 것이다. Docker Hub는 public 저장소는 완전 무료에다가, 무료로 제공되는 private 저장소는 용량 제한도 없고, image push, pull을 무료로 제공하기 때문이다.

하지만 본 글쓴이는 AWS를 인프라로 사용하고 있고, 본 글을 작성하게 된 계기도 AWS NAT gateway에서 발생하는 요금을 절약하기 위해서다. 따라서 ECR 사용에 따른 요금을 대략적으로 계산해볼 필요가 있다.

AWS ECR 요금

저장 용량 요금


현재 프로젝트에는 3가지 이미지를 사용하고 있다. 하나의 이미지에 200MB 정도 되니 총 용량은 600MB. 차후 기능이 추가되면 용량이 늘어날 것을 대비하여 총 용량을 1GB로 잡는다.


프라이빗 리포지를 사용한다면 무료 사용 제공량 500MB를 초과하는 500MB에 대해서 요금을 지불해야한다. 저장에 필요한 비용은 월 0.05 달러 발생한다.


이 마저도 public 리포지토리를 사용하면 무료 제공량 50GB 내에 해결되므로 저장에는 요금이 거의 발생되지 않는다. 지금도 Docker Hub에서 public repository를 이용하고 있으므로 AWS ECR의 public repository를 사용해도 무방하다.

데이터 전송 요금


AWS에서는 Pull에 요금이 발생한다. 지난 15일간 5.6GB 사용했으므로 대략 한달에 10GB 정도 pull이 일어날 것이라 예상된다. 

AWS public repository를 사용하면 AWS 계정을 사용하는 경우 5TB까지 무료로 pull할 수 있으므로 데이터 전송 요금도 부과되지 않는다.

 



결론적으로 Public Repository를 사용한다면 AWS ECR을 사용하는 데에는 요금이 발생하지 않을 것이다.

20230422 업데이트 


퍼블릭 리포지토리를 사용하면 VPC endpoint를 사용할 수 없다. 현재 AWS는 프라이빗 리포지토리에 한해 VPC endpoint를 연결할 수 있으므로 프라이빗 리포지토리를 사용하는 것이 강제된다. 그러므로 프라이빗 리포지토리 사용에 따른 비용도 고려해야한다.

AWS VPC Endpoint 


현재 프로젝트는 다음과 같이 구성되어있다. 서비스 어플리케이션은 VPC의 Private subnet에서만 구동된다. ~~그래서 외부 인터넷과의 접속은 차단되어있다. Docker hub에서 image를 가져오기 위해 NAT gateway 사용했지만 비용 때문에 VPC Endpoint point를 고려해보기로 한다.~~ NAT gateway 대신 AWS ECR에 VPC endpoint를 연결하여 이미지를 가져오기로 한다.



VPC Endpoint를 통해 외부 AWS와 연결한 것을 Private Link라고 부른다. 다음은 AWS 공문서에 있는 private link (VPC Endpoint) 개념을 설명한 다이어그램이다.

 


이처럼 VPC Endpoint를 사용하면 NAT Gateway를 사용하여 공용 인터넷 네트워크로 접근하지 않아도 AWS 리소스(여기서는 ECR)에 접근할 수 있다. 


Docker hub와는 다르게 ECR은 AWS에서 제공하는 서비스이므로 VPC Endpoint로 접근 할 수 있다. VPC Endpoint에는 크게 게이트웨이 엔드포인트와 인터페이스 엔드포인트가 있다.

- Interface Endpoint : Private IP를 만들어서 서비스로 연결해줌 (SQS, SNS, Kinesis, Sagemaker 등 많은 서비스를 지원)

- Gateway Endpoint : 라우팅 테이블에서 경로의 대상으로 지정하여 사용(S3, DynamoDB 일부만 지원)

 


위는 AWS 공문서에서 VPC Gateway Endpoint와 Interface Endpoint를 비교한 것이다. Gateway Endpoint는 무료지만 private link 가 아니기 때문에 public 영역에서 라우팅을 통해 접근할 수 있고, DynamoDB와 S3에만 접근할 수 있다. 우리는 Private한 용도로 link를 사용하여 ECR에 접근하고 싶기 때문에 Interface Endpoint를 사용할 것이다. 



인터페이스 엔드포인트는 시간당 0.013달러 비용이 발생한다. ~~시간당 0.059달러 소모되던 NAT gateway에 비해 78% 저렴하다. (가격이 4.5배 차이) 대략적인 계산으로 인터페이스 엔드포인트를 사용했다면 4만원이 아니라 8천원 정도가 소비되었을 것이다. 치킨 두마리가 아니라 국밥 한 그릇 가격으로 똑같은 서비스를 운용할 수 있었던 것이다.. 😂~~

20230422 업데이트: 오히려 요금이 더 비쌈



AWS ECR과 VPC Endpoint를 사용하여 도커 이미지를 불러오는 것은 NAT gateway에 비해 전혀 저렴하지 않다. 그 이유는 AWS ECR에서 ECS로 이미지를 불러오는 과정에서 필요한 인터페이스 엔드포인트가 5개가 필요하기 때문이다. 

 



즉, 아래처럼 6개의 엔드포인트가 필요하며, 비용이 발생하지 않는 게이트웨이 엔드포인트를 제외하면 5개의 인터페이스 엔드포인트가 필요하다. 5개의 인터페이스 엔드포인트가 온전히 있어야 ECR에서 이미지를 가지고 와서 ECS에서 정상적으로 구동할 수 있다. 

 

 


그러므로 요금은 VPC 엔드포인트 당 요금 0.013달러 X 5개를 하여 총 시간당 0.065 달러의 비용이 발생하게 된다. 이는 시간당 0.059 달러의 비용이 발생하는 NAT gateway 보다 더 비싸다. 

 

 

 


결국 비용적인 부분을 이유로 AWS NAT gateway + Docker Hub -> AWS VPC Endpoint + AWS ECR 로 바꿀 이유가 없는 것이다. 

추가적으로 AWS VPC Endpoint를 사용하여 ECR에서 ECS로 이미지를 가져오려고 해도 NAT gateway를 어쨌든 한 번은 사용해야한다. 아래 AWS 공문서를 참고해보자.

 


후속 이미지 풀에는 NAT gateway가 필요없다곤 하지만, 코드를 수정하여 새 이미지를 push하면 ECS 서비스를 업데이트하여 다시 이미지 초기 pull이 필요하므로 NAT gateway가 필요한 것이다. 그러므로 NAT gateway를 사용하여 Docker Hub를 가져오는 것에 비해 ECR과 VPC endpoint를 사용하는 것은 인터페이스 편의성 측면에서도 딱히 이점이 없다. 어쨌든 모든 경우에 NAT gateway는 사용해야 하고 비용도 발생할 것이다. 이 글은 비용 적 이점을 고려했다기 보다는 그냥 ECR을 사용하는 옵션을 고려한 것으로 이해하길 바란다.

AWS ECR 생성하여 docker image 업로드하기



AWS ECS 서비스에 들어가서 ECR의 리포지토리를 생성해보자. ~~본 작업을 하기 위해서는 ecr-public: CreateRepository 가 사용자의 IAM 권한에 있어야 한다. (프라이빗 리포지토리를 생성하려면 프리이빗만의 별도 권한이 필요하다.)~~

~~이름을 넣고 퍼블릭 리포지토리를 생성한다.~~

주의사항 (업데이트)


VPC endpoint를 사용해서 이미지를 가져오려면 해당 리포지토리는 프라이빗 리포지토리를 선택해야한다. AWS는 현재 ECR 퍼블릭 리포지토리에서 VPC 엔드포인트를 지원하지 않는다. 다음 AWS 공문서를 참고해보자.



글쓴이는 이 주의사항을 알지 못하고, 퍼블릭 리포지토리를 생성해서 VPC endpoint를 만들었다가 ECS 컨테이너가 계속해서 생성되지 못하는 오류를 맞이했다. 해당 오류는 CloudWatch 상에서도 알 수 없으므로 AWS 공문서를 통해서 내용을 확인해야한다. 본 글을 읽는 분들은 같은 실수를 반복하지 않으시길 바란다. (그리고 AWS 공문서를 꼼꼼히 확인하자.)

ECR 프라이빗 리포지토리 생성



리포지토리에 들어가서 우측을 확인하면 푸시 명령 보기가 있다. 클릭하여 확인한다. 

 




이처럼 docker image를 AWS ECR에 푸시하는 방법이 친절하게 설명되어있다. 설명을 따라 커맨드를 입력하여 image를 리포지토리에 푸시한다.




 1번 명령어를 그대로 복사 붙여넣기 해서 터미널에서 동작시키면 docker 클라이언트가 인증된다.

주의사항

AWS CLI를 사용하여 AWS 환경에 로그인 되어있어야 한다. 이 로그인에는 사용자의 액세스키와 액세스 비밀키가 사용된다.  AWS CLI에 입력된 액세스키와 액세스보안키가 ECR 접근 권한이 있는 계정의 액세스키와 액세스 보안키가 아니라면 아래처럼 에러가 발생하면서 정상적으로 동작하지 않을 수 있다. 



혹은 사용자 계정에 MFA가 할당되어있어도 AWS 액세스가 정상적으로 동작하지 않을 수도 있다. 그 외 도커 config 관련 문제 때문에 실행되지 않을 수 있다. Docker 클라이언트 인증과 관련되어 문제가 발생한다면 아래 링크를 참고하자.

/////////링크///////

도커 이미지 ECR에 푸쉬


그 외에는 정말 별 것 없다. AWS 설명에 나와있는 그대로 복사 붙여넣기해서 이미지 파일을 생성하고 저장소에 푸쉬하면 된다.


 

 



이와 같이 이미지가 ECR에 성공적으로 올라가게 된다.

 

 

 

다음 포스팅에 계속


글이 지나치게 길어질 우려가 있으므로 ECS에서 VPC Endpoint를 통해 ECR 이미지를 가져오는 것은 다음 포스팅에서 진행해보도록 한다.