Hanbit the Developer

AWS와 Docker를 활용한 Spring + React.JS CI/CD 구축: ECR + IAM(3) 본문

Back-end

AWS와 Docker를 활용한 Spring + React.JS CI/CD 구축: ECR + IAM(3)

hanbikan 2024. 8. 13. 21:13

ECR 도입 배경

이전 글의 과정으로 Docker로 편하게 배포를 할 수 있었습니다. 이제 마지막으로 CD까지 도입하면 git main 코드가 변경되면 아무런 절차 없이 배포를 할 수 있습니다.

다만 저는 보안성을 높이고자 Docker Hub 대신, AWS에서 제공하는 컨테이너 레지스트리인 ECR(Amazon Elastic Container)을 도입하고자 했습니다.

 

1. IAM

ECR을 사용하려면 IAM 서비스가 필요합니다. IAM(Identity and Access Management)은 AWS 리소스에 대한 접근을 안전하게 관리하는 권한 제어 서비스입니다.

User

먼저 User에 대해 알아야 합니다. IAM에서 User는 AWS 계정 내에서 특정 사용자를 나타내며, AWS 리소스에 접근할 수 있는 credentials(예: 사용자 이름, 암호, 액세스 키)을 가집니다. User에 ECR에 필요한 권한을 부여한 뒤 User의 키를 통해 로그인 하면 ECR에 이미지를 올리거나 풀 받을 수 있습니다.

User groups

추가로 AWS에서 User groups을 사용하는 것을 권장하기 때문에 저는 User groups에 제가 생성한 User를 추가해서 관리했습니다. User groups에 대해 설명하면 대략 다음과 같습니다:

  • User groups에 권한을 부여하고 이곳에 여러 유저를 추가하면 추가된 유저들이 동시에 그 권한을 갖습니다.
  • User는 여러 개의 User groups에 들어갈 수 있습니다.

예를 들어 admin-user-group을 생성한 뒤 모든 권한을 부여하여 저만 사용하는 admin-user를 추가하고, deploy-user-group을 생성한 뒤 배포에 필요한 최소한의 권한을 부여하고 deploy-user를 추가할 수 있습니다.

로그인 방법

이제 다음과 같은 과정을 통해 User의 access key id, secret access key로 로그인할 수 있습니다:

aws configure
  • access key id, secret access key 입력
  • 기본 AWS 리전(us-west-2) 입력: 저는 EC2의 리전을 입력했습니다.
  • 기본 출력 포멧 입력: json 등 출력 형식을 입력합니다. 기본값은 json입니다.

 

2. ECR

ECR(Amazon Elastic Container)은 AWS에서 제공하는 컨테이너 레지스트리입니다. Docker Hub에 비해 ECR이 나은 점은 다음과 같습니다:

  • AWS 서비스와의 통합: 저는 EC2, RDS, Route53 등 클라우드 환경이 AWS 기반이기 때문에 적절합니다.
  • 네트워크 성능: ECR은 배포 환경인 EC2와 같은 region에 호스팅되므로 속도가 빠르고 안정적입니다.
  • 보안: ECR은 AWS 리소스에 대한 접근 제어 서비스인 IAM을 통해 세밀한 권한 제어가 가능하기 때문에 보안성이 높습니다.

ECR 접근 방법

저는 ECR에서 private repository를 하나 생성하였으며, 아래와 같은 명령어로 CLI에서 ECR에 로그인할 수 있습니다:

aws ecr get-login-password --region <REGION 입력> | docker login --username AWS --password-stdin <REGISTRY or REPOSITORY URI 입력>

이때 마지막 인자로 ECR registry(예시: 123123.q1w.2e3.r4.amazonaws.com)을 입력하면 해당 레지스트리 내 모든 리포지토리에 접근할 수 있으며, ECR Repository URI(예시: 123123.q1w.2e3.r4.amazonaws.com/myrepo를))를 입력하면 해당 리포지토리에만 접근이 가능합니다.

IAM 권한 부여

이제 AWS IAM 서비스 페이지에서 ECR에 대한 IAM 권한을 부여해야 합니다.

  • User만 사용하는 경우: IAM - Access management - Users - (원하는 유저 선택) - Add permissions - Add permissions 경로로 이동한 뒤 Permissions options에서 Attach policies directly를 선택하여 권한을 추가합니다.
  • User groups를 사용하는 경우: IAM - Access management - User groups - (원하는 유저 그룹 선택) - Permissions - Add permissions - Add permissions 경로로 이동한 뒤 권한을 추가합니다.

IAM에서 ECR과 관련된 권한은 다음과 같습니다:

  • AmazonEC2ContainerRegistryFullAccess: ECR 전체 관리 권한을 제공합니다. 리포지토리를 생성, 삭제, 이미지 푸시/풀, 설정 변경 등 모든 작업을 수행할 수 있습니다.
  • AmazonEC2ContainerRegistryPowerUser: 조금 더 제한적입니다. 리포지토리를 생성하고 이미지를 Push/Pull할 수 있지만, 리포지토리 삭제와 정책 변경은 불가능합니다.
  • AmazonEC2ContainerRegistryReadOnly: 읽기 전용 권한을 제공합니다. 이미지 목록을 조회하거나 이미지를 Pull 받을 수 있습니다.

제 경우 GitHub Actions, EC2에서 주로 Push/Pull 명령어를 수행하기 때문에 AmazonEC2ContainerRegistryPowerUser를 부여했습니다.

 

이후 도커 푸시를 하고 ECR 서비스 페이지에서 확인(ECR - Repositories - (원하는 repository 선택) - Images)해보니 제가 푸시한 이미지를 확인할 수 있었습니다.

 

3. (Optional) Lifecycle Policy 적용

2024년 8월 기준, ECR 프리티어 사용 시 private repository는 월 500MB의 무료 스토리지를 받으며, 이를 초과하면 1GB당 0.10 USD가 청구됩니다.(ECR Pricing) 리포지토리의 용량을 잘 관리하여 과금되지 않도록 Lifecycle Policy를 적용했습니다.

 

ECR - Repositories - Lifecycle Policy - Create rule 경로로 이동한 뒤 정책을 설정해줍니다.

같은 태그로 이미지를 여러 번 푸시하면 가장 최신 이미지를 제외하고 모두 태그가 사라지기 때문에, 타겟 Image status를 untagged로 설정하였습니다. 또한 그런 이미지가 10개를 넘지 않도록 설정하였습니다. 즉, 최신이 아닌 이미지가 10개가 넘지 않도록 제한을 둔 것입니다.

이미지 개수가 아니라 날짜를 기준으로도 이런 규칙을 적용할 수 있습니다. 예를 들면 30일이 지난 이미지는 삭제하는 경우가 있습니다.

 

References

https://cloudonaut.io/amazon-ecr-vs-docker-hub-vs-github-container-registry/

https://stackoverflow.com/questions/61029378/which-cloud-region-could-have-the-fastest-time-for-a-docker-image-push

https://www.docker.com/pricing/

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html