🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

AWS ECR 레포지토리 생성 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 19. · 5 Views

AWS ECR 레포지토리 생성 완벽 가이드

Docker 이미지를 안전하게 저장하고 관리하는 ECR 레포지토리 생성부터 권한 설정까지, 초급 개발자를 위한 실무 중심 가이드입니다. 프라이빗과 퍼블릭의 차이, 이미지 태그 전략, 수명 주기 정책까지 모두 다룹니다.


목차

  1. ECR이란_무엇인가
  2. 레포지토리_생성
  3. 프라이빗_vs_퍼블릭
  4. 이미지_태그_전략
  5. 수명_주기_정책
  6. ECR_권한_설정

1. ECR이란 무엇인가

어느 날 김개발 씨는 처음으로 Docker 이미지를 배포해야 하는 업무를 맡았습니다. "이미지를 어디에 저장해야 하죠?" 선배 박시니어 씨가 웃으며 답했습니다.

"ECR을 사용하면 됩니다!"

**ECR(Elastic Container Registry)**은 AWS에서 제공하는 완전 관리형 Docker 컨테이너 이미지 저장소입니다. 마치 GitHub가 코드를 저장하는 것처럼, ECR은 Docker 이미지를 안전하게 저장하고 관리합니다.

AWS의 다른 서비스들과 완벽하게 통합되어 있어 배포 파이프라인을 쉽게 구축할 수 있습니다.

다음 코드를 살펴봅시다.

// AWS CLI를 사용한 ECR 레포지토리 생성 예제
// 먼저 AWS CLI가 설치되어 있어야 합니다

// 1. ECR 레포지토리 생성
aws ecr create-repository \
  --repository-name my-app \
  --region ap-northeast-2 \
  --image-scanning-configuration scanOnPush=true \
  --encryption-configuration encryptionType=AES256

// 2. 레포지토리 목록 확인
aws ecr describe-repositories --region ap-northeast-2

// 3. 레포지토리 URI 확인 (이미지 푸시할 때 필요)
// 출력 예: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app

김개발 씨는 입사 2개월 차 주니어 개발자입니다. 오늘 팀장님으로부터 첫 배포 업무를 맡았습니다.

"우리 서비스를 Docker 컨테이너로 배포해야 하는데, 이미지를 어디에 저장하면 좋을까요?" 선배 박시니어 씨가 친절하게 설명해줍니다. "Docker Hub도 있지만, 우리는 AWS 인프라를 사용하니까 ECR을 쓰는 게 좋아요." 그렇다면 ECR이란 정확히 무엇일까요?

쉽게 비유하자면, ECR은 마치 사진을 저장하는 클라우드 앨범과 같습니다. 스마트폰으로 찍은 사진을 구글 포토나 iCloud에 저장하듯이, 개발자들이 만든 Docker 이미지를 ECR에 저장하는 것입니다.

다만 일반 사진이 아니라 서비스를 실행할 수 있는 완전한 패키지를 저장한다는 점이 다릅니다. ECR이 없던 시절에는 어땠을까요?

개발자들은 Docker Hub 같은 퍼블릭 저장소를 사용하거나, 직접 프라이빗 레지스트리 서버를 구축해야 했습니다. 퍼블릭 저장소는 누구나 볼 수 있다는 보안 문제가 있었고, 프라이빗 서버는 직접 관리해야 하는 부담이 있었습니다.

더 큰 문제는 AWS의 다른 서비스들과 연동하기 위해 복잡한 설정이 필요했다는 점입니다. 바로 이런 문제를 해결하기 위해 ECR이 등장했습니다.

ECR을 사용하면 완전 관리형 서비스의 이점을 누릴 수 있습니다. 서버를 직접 관리할 필요가 없고, AWS가 알아서 확장성과 가용성을 보장해줍니다.

또한 AWS IAM과의 완벽한 통합으로 세밀한 권한 제어가 가능합니다. 무엇보다 ECS, EKS, Lambda와의 원활한 연동이라는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 create-repository 명령어로 새로운 레포지토리를 생성합니다.

repository-name은 여러분의 애플리케이션 이름을 지정하면 됩니다. scanOnPush 옵션은 이미지를 푸시할 때마다 자동으로 보안 취약점을 검사해주는 기능입니다.

암호화 설정을 통해 저장된 이미지를 안전하게 보호할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 전자상거래 서비스를 개발한다고 가정해봅시다. 프론트엔드, 백엔드, 결제 시스템이 각각 다른 Docker 이미지로 관리됩니다.

ECR에 각 서비스별로 레포지토리를 만들어두면, 버전 관리가 명확해지고 롤백도 쉬워집니다. 쿠팡, 배달의민족 같은 대형 서비스들도 이런 패턴을 적극적으로 사용하고 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 레포지토리 이름을 너무 복잡하게 짓는 것입니다.

나중에 관리하기 어려워질 수 있습니다. 따라서 팀 내에서 명명 규칙을 정하고, 간결하면서도 명확한 이름을 사용해야 합니다.

또 다른 실수는 리전을 잘못 선택하는 것입니다. ECR 레포지토리는 특정 리전에 생성되므로, ECS나 EKS를 사용할 리전과 동일하게 설정해야 네트워크 비용을 절감할 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그래서 ECR을 쓰는 거군요!" ECR을 제대로 이해하면 더 안전하고 효율적인 컨테이너 배포 파이프라인을 구축할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 레포지토리 이름은 서비스명과 동일하게 설정하여 관리를 쉽게 하세요

  • 이미지 스캔 기능을 활성화하여 보안 취약점을 사전에 발견하세요
  • 서울 리전(ap-northeast-2)을 사용하면 국내 서비스의 응답 속도가 빨라집니다

2. 레포지토리 생성

김개발 씨는 이제 실제로 ECR 레포지토리를 만들어보기로 했습니다. "CLI로 해야 하나요, 아니면 콘솔에서도 되나요?" 박시니어 씨가 답했습니다.

"두 가지 방법 모두 알아두면 좋아요!"

ECR 레포지토리는 AWS 콘솔, AWS CLI, Terraform 등 다양한 방법으로 생성할 수 있습니다. 각 방법마다 장단점이 있으며, 실무에서는 자동화를 위해 CLI나 IaC 도구를 주로 사용합니다.

레포지토리를 생성할 때는 이름, 태그 변경 가능 여부, 이미지 스캔 설정 등을 고려해야 합니다.

다음 코드를 살펴봅시다.

// Node.js AWS SDK를 사용한 ECR 레포지토리 생성
const { ECRClient, CreateRepositoryCommand } = require('@aws-sdk/client-ecr');

// ECR 클라이언트 초기화
const client = new ECRClient({ region: 'ap-northeast-2' });

// 레포지토리 생성 함수
async function createECRRepository(repositoryName) {
  const command = new CreateRepositoryCommand({
    repositoryName: repositoryName,
    // 이미지 푸시 시 자동 스캔
    imageScanningConfiguration: { scanOnPush: true },
    // 태그 변경 불가 설정 (운영 환경 권장)
    imageTagMutability: 'IMMUTABLE',
    // 암호화 설정
    encryptionConfiguration: { encryptionType: 'AES256' }
  });

  try {
    const response = await client.send(command);
    console.log('레포지토리 생성 완료:', response.repository.repositoryUri);
    return response.repository;
  } catch (error) {
    console.error('생성 실패:', error.message);
    throw error;
  }
}

// 사용 예제
createECRRepository('my-nodejs-app');

김개발 씨는 처음에는 AWS 콘솔에서 클릭 몇 번으로 레포지토리를 만들었습니다. 간단하고 직관적이었죠.

하지만 매번 수동으로 만들다 보니 실수도 생기고, 설정이 일관되지 않았습니다. 박시니어 씨가 조언합니다.

"개발 환경에서는 콘솔로 테스트해봐도 괜찮지만, 운영 환경에서는 코드로 관리하는 게 좋아요." 그렇다면 어떤 방법들이 있을까요? 가장 간단한 방법은 AWS 콘솔을 이용하는 것입니다.

마치 웹사이트에서 회원가입하듯이, 폼에 정보를 입력하고 버튼을 클릭하면 됩니다. 시각적으로 확인하면서 작업할 수 있어 초보자에게 좋습니다.

하지만 매번 수동으로 해야 한다는 단점이 있습니다. 두 번째는 AWS CLI를 사용하는 방법입니다.

터미널에서 명령어 한 줄로 레포지토리를 생성할 수 있습니다. 스크립트로 만들어두면 반복 작업을 자동화할 수 있습니다.

DevOps 엔지니어들이 선호하는 방식입니다. 세 번째는 AWS SDK를 활용하는 방법입니다.

Node.js, Python, Java 등 여러분이 사용하는 프로그래밍 언어로 ECR을 제어할 수 있습니다. 애플리케이션 코드에 통합하거나, 배포 자동화 시스템을 구축할 때 유용합니다.

위의 코드를 자세히 살펴보겠습니다. 먼저 AWS SDK의 ECR 클라이언트를 초기화합니다.

리전은 서울(ap-northeast-2)로 설정했습니다. CreateRepositoryCommand 객체를 만들 때 여러 옵션을 지정할 수 있는데, 각각의 의미를 알아봅시다.

imageScanningConfiguration은 보안 스캔 설정입니다. scanOnPush를 true로 하면 이미지를 푸시할 때마다 자동으로 취약점을 검사합니다.

이미지에 오래된 라이브러리나 알려진 보안 문제가 있으면 알려줍니다. imageTagMutability는 태그 변경 가능 여부입니다.

IMMUTABLE로 설정하면 한 번 푸시한 태그를 덮어쓸 수 없습니다. 예를 들어 v1.0.0 태그로 이미지를 푸시했다면, 같은 태그로 다른 이미지를 푸시할 수 없습니다.

운영 환경에서는 이 설정을 권장합니다. encryptionConfiguration은 암호화 설정입니다.

AES256 방식으로 저장된 이미지를 암호화합니다. 민감한 정보가 포함된 이미지라면 반드시 활성화해야 합니다.

실제 현업에서는 어떻게 활용할까요? 대부분의 기업들은 Infrastructure as Code(IaC) 방식을 사용합니다.

Terraform이나 AWS CloudFormation으로 인프라를 코드로 정의하고, Git으로 버전 관리합니다. 누군가 실수로 레포지토리를 삭제해도 코드만 있으면 언제든 동일하게 복구할 수 있습니다.

또한 CI/CD 파이프라인에 통합하는 경우가 많습니다. 새로운 마이크로서비스를 추가할 때마다 자동으로 ECR 레포지토리가 생성되도록 설정할 수 있습니다.

개발자는 코드만 작성하면 되고, 인프라는 자동으로 준비됩니다. 하지만 주의할 점도 있습니다.

레포지토리 이름은 변경할 수 없습니다. 한 번 생성하면 삭제 후 재생성해야 합니다. 따라서 처음부터 명명 규칙을 잘 정해야 합니다.

많은 팀들이 "서비스명-환경-용도" 형식을 사용합니다. 예를 들어 "payment-api-prod" 같은 식입니다.

또 다른 실수는 불필요한 레포지토리를 너무 많이 만드는 것입니다. ECR 자체는 무료지만, 저장 용량과 데이터 전송에는 비용이 발생합니다.

사용하지 않는 레포지토리는 정리하는 습관을 들이세요. 다시 김개발 씨의 이야기로 돌아가 봅시다.

SDK 코드를 작성한 김개발 씨는 뿌듯해했습니다. "이제 자동화된 스크립트를 만들 수 있겠어요!" 레포지토리 생성을 코드로 관리하면 실수를 줄이고, 일관성을 유지할 수 있습니다.

여러분도 오늘 배운 내용을 팀의 DevOps 파이프라인에 적용해 보세요.

실전 팁

💡 - 레포지토리 명명 규칙을 팀 내에서 미리 정하고 문서화하세요

  • SDK를 사용할 때는 에러 처리를 반드시 포함하세요
  • 테스트 환경에서는 MUTABLE, 운영 환경에서는 IMMUTABLE 태그 설정을 권장합니다

3. 프라이빗 vs 퍼블릭

김개발 씨가 레포지토리를 만들려는데 선택지가 두 개 나왔습니다. "Private과 Public의 차이가 뭔가요?" 박시니어 씨가 중요한 표정으로 말했습니다.

"이건 보안과 직결된 문제예요."

ECR 레포지토리는 **프라이빗(Private)**과 퍼블릭(Public) 두 가지 타입이 있습니다. 프라이빗은 권한이 있는 사람만 접근할 수 있고, 퍼블릭은 누구나 이미지를 다운로드할 수 있습니다.

대부분의 기업 서비스는 보안을 위해 프라이빗을 사용하며, 오픈소스 프로젝트는 퍼블릭을 선택합니다.

다음 코드를 살펴봅시다.

// 프라이빗 레포지토리 생성 (기본값)
aws ecr create-repository \
  --repository-name my-private-app \
  --region ap-northeast-2

// 퍼블릭 레포지토리 생성 (ECR Public 사용)
aws ecr-public create-repository \
  --repository-name my-public-app \
  --region us-east-1

// 프라이빗 레포지토리 인증 후 로그인
aws ecr get-login-password --region ap-northeast-2 | \
  docker login --username AWS \
  --password-stdin 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com

// 퍼블릭 레포지토리는 인증 없이 pull 가능
docker pull public.ecr.aws/my-org/my-public-app:latest

// 하지만 push는 인증 필요
aws ecr-public get-login-password --region us-east-1 | \
  docker login --username AWS \
  --password-stdin public.ecr.aws

김개발 씨는 고민에 빠졌습니다. 개인 토이 프로젝트를 오픈소스로 공개하고 싶은데, 회사 프로젝트는 당연히 비공개여야 합니다.

어떤 타입을 선택해야 할까요? 박시니어 씨가 차분하게 설명합니다.

"용도에 따라 다르지만, 확실하지 않으면 일단 프라이빗으로 만드세요. 나중에 공개하는 건 쉽지만, 공개된 걸 되돌리는 건 어렵거든요." 프라이빗 레포지토리란 무엇일까요?

쉽게 비유하자면, 프라이빗 레포지토리는 마치 회사의 기밀 문서 보관함과 같습니다. 열쇠를 가진 사람만 열어볼 수 있습니다.

ECR에서는 AWS IAM을 통해 누가 이미지를 읽고, 쓰고, 삭제할 수 있는지 세밀하게 제어합니다. 외부인은 물론이고 같은 AWS 계정 내에서도 권한이 없으면 접근할 수 없습니다.

반대로 퍼블릭 레포지토리는 공개 도서관과 같습니다. 누구나 들어와서 책을 빌려갈 수 있습니다.

Docker Hub처럼 전 세계 누구나 여러분의 이미지를 다운로드할 수 있습니다. 단, 이미지를 추가하거나 수정하려면 여전히 권한이 필요합니다.

언제 프라이빗을 사용해야 할까요? 상용 서비스의 컨테이너 이미지는 무조건 프라이빗이어야 합니다.

여러분의 비즈니스 로직, API 키, 데이터베이스 연결 정보 등이 포함되어 있기 때문입니다. 만약 실수로 퍼블릭으로 만들면 누구나 여러분의 코드를 볼 수 있고, 보안 취약점을 찾아낼 수 있습니다.

내부 개발 도구나 공유 라이브러리도 프라이빗으로 관리합니다. 여러 팀이 사용하는 공통 베이스 이미지가 있다면, 조직 내에서만 공유하는 것이 안전합니다.

AWS Organizations를 사용하면 여러 계정 간에 프라이빗 이미지를 안전하게 공유할 수 있습니다. 그렇다면 퍼블릭은 언제 사용할까요?

오픈소스 프로젝트를 배포할 때 퍼블릭이 유용합니다. 커뮤니티 사용자들이 쉽게 여러분의 애플리케이션을 사용할 수 있도록 이미지를 공개하는 것입니다.

Docker Hub의 대안으로 ECR Public을 사용할 수 있습니다. 공개 튜토리얼이나 샘플 애플리케이션도 퍼블릭으로 배포하면 좋습니다.

블로그 포스팅이나 기술 세미나에서 데모를 보여줄 때, 사람들이 직접 이미지를 받아서 실행해볼 수 있습니다. 위의 코드를 살펴보겠습니다.

프라이빗 레포지토리는 일반 ecr 명령어를 사용합니다. 생성 후 이미지를 푸시하거나 풀하려면 반드시 get-login-password로 인증해야 합니다.

이 명령어는 임시 토큰을 생성하고, Docker 클라이언트에 로그인합니다. 퍼블릭 레포지토리는 ecr-public 명령어를 사용하며, 리전이 us-east-1로 고정됩니다.

ECR Public은 현재 버지니아 리전에서만 운영됩니다. 이미지를 다운로드할 때는 인증이 필요 없지만, 업로드할 때는 여전히 권한이 필요합니다.

실제 현업에서는 어떻게 활용할까요? 대부분의 스타트업과 기업은 모든 레포지토리를 프라이빗으로 유지합니다.

보안 사고가 한 번 발생하면 회사의 신뢰도가 크게 떨어지기 때문입니다. 하지만 기술 브랜딩 차원에서 일부 도구나 라이브러리를 오픈소스로 공개하고, 해당 이미지만 퍼블릭으로 만드는 경우도 있습니다.

하지만 주의할 점도 있습니다. 절대 프라이빗을 퍼블릭으로 바꾸지 마세요. 한 번 공개된 이미지는 이미 다운로드되어 퍼져있을 수 있습니다.

실수로 공개했다면 즉시 삭제하고, 포함된 비밀 정보(API 키, 인증서 등)를 모두 갱신해야 합니다. 또 다른 실수는 퍼블릭 레포지토리에 민감 정보를 포함하는 것입니다.

환경 변수나 설정 파일에 하드코딩된 비밀번호가 없는지 반드시 확인하세요. 오픈소스라도 시크릿은 컨테이너 외부에서 주입해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언을 들은 김개발 씨는 명확해졌습니다.

"회사 프로젝트는 프라이빗, 개인 오픈소스는 퍼블릭으로 하겠습니다!" 프라이빗과 퍼블릭의 차이를 제대로 이해하면 보안 사고를 예방하고, 적절한 공유 전략을 수립할 수 있습니다. 여러분도 오늘 배운 내용을 토대로 올바른 선택을 하세요.

실전 팁

💡 - 확실하지 않으면 프라이빗으로 시작하세요. 나중에 공개하는 것이 안전합니다

  • 퍼블릭 이미지를 만들 때는 반드시 코드 리뷰를 거쳐 민감 정보가 없는지 확인하세요
  • ECR Public은 다운로드 대역폭이 무료이므로, 오픈소스 배포에 유리합니다

4. 이미지 태그 전략

김개발 씨가 첫 번째 이미지를 푸시하려는데, 태그를 어떻게 붙여야 할지 고민됩니다. "그냥 latest로 하면 안 되나요?" 박시니어 씨가 손사래를 쳤습니다.

"latest는 절대 운영에서 쓰면 안 돼요!"

이미지 태그 전략은 컨테이너 배포의 핵심입니다. 올바른 태그 전략을 사용하면 버전 관리가 명확해지고, 롤백이 쉬워지며, 배포 추적이 가능해집니다.

시맨틱 버저닝, Git 커밋 해시, 빌드 번호 등 다양한 방법이 있으며, 여러 태그를 동시에 사용하는 것이 일반적입니다.

다음 코드를 살펴봅시다.

// 여러 태그를 동시에 푸시하는 스크립트 예제
#!/bin/bash

# 환경 변수 설정
IMAGE_NAME="my-app"
ECR_REPO="123456789012.dkr.ecr.ap-northeast-2.amazonaws.com"
GIT_COMMIT=$(git rev-parse --short HEAD)
VERSION="1.2.3"
BUILD_NUMBER="456"

# Docker 이미지 빌드
docker build -t ${IMAGE_NAME}:${VERSION} .

# 여러 태그 추가
docker tag ${IMAGE_NAME}:${VERSION} ${ECR_REPO}/${IMAGE_NAME}:${VERSION}
docker tag ${IMAGE_NAME}:${VERSION} ${ECR_REPO}/${IMAGE_NAME}:${GIT_COMMIT}
docker tag ${IMAGE_NAME}:${VERSION} ${ECR_REPO}/${IMAGE_NAME}:build-${BUILD_NUMBER}
docker tag ${IMAGE_NAME}:${VERSION} ${ECR_REPO}/${IMAGE_NAME}:latest

# ECR에 푸시 (모든 태그)
docker push ${ECR_REPO}/${IMAGE_NAME}:${VERSION}
docker push ${ECR_REPO}/${IMAGE_NAME}:${GIT_COMMIT}
docker push ${ECR_REPO}/${IMAGE_NAME}:build-${BUILD_NUMBER}
docker push ${ECR_REPO}/${IMAGE_NAME}:latest

김개발 씨는 처음에 모든 이미지를 latest로 푸시했습니다. 간단하고 편했죠.

하지만 일주일 뒤, 운영 서버에 문제가 생겨서 이전 버전으로 돌아가려고 했는데 어떤 버전이었는지 알 수 없었습니다. 박시니어 씨가 찾아와 말했습니다.

"latest는 '가장 최근'이라는 의미일 뿐, 버전 정보가 전혀 없어요. 운영 환경에서는 반드시 명확한 버전 태그를 사용해야 합니다." 그렇다면 올바른 태그 전략은 무엇일까요?

쉽게 비유하자면, 이미지 태그는 마치 책의 에디션 번호와 같습니다. "Harry Potter"라는 제목만으로는 초판인지 개정판인지 알 수 없습니다.

"Harry Potter 1st Edition, 2nd Print, 1998"처럼 구체적으로 명시해야 정확히 어떤 책인지 알 수 있습니다. 컨테이너 이미지도 마찬가지입니다.

가장 널리 사용되는 방법은 **시맨틱 버저닝(Semantic Versioning)**입니다. 버전을 major.minor.patch 형식으로 표현합니다.

예를 들어 1.2.3이라면, 1은 메이저 버전, 2는 마이너 버전, 3은 패치 버전입니다. API를 변경하면 메이저를 올리고, 새 기능을 추가하면 마이너를 올리고, 버그만 고치면 패치를 올립니다.

명확한 규칙이 있어 다른 개발자들도 쉽게 이해할 수 있습니다. 두 번째로 많이 사용하는 것은 Git 커밋 해시입니다.

git rev-parse --short HEAD 명령어로 얻은 짧은 해시를 태그로 사용합니다. 예를 들어 a3f7b2e 같은 형태입니다.

이렇게 하면 이미지가 정확히 어떤 코드 상태에서 빌드되었는지 추적할 수 있습니다. 문제가 생기면 해당 커밋으로 돌아가 코드를 확인할 수 있습니다.

세 번째는 빌드 번호를 사용하는 방법입니다. Jenkins, GitHub Actions, GitLab CI 같은 CI/CD 도구들은 각 빌드마다 고유한 번호를 부여합니다.

build-456처럼 빌드 번호를 태그로 사용하면 CI/CD 로그와 이미지를 연결할 수 있습니다. 어떤 빌드에서 문제가 생겼는지 즉시 파악할 수 있습니다.

위의 코드를 자세히 살펴보겠습니다. 먼저 Git 커밋 해시를 자동으로 추출합니다.

git rev-parse --short HEAD는 현재 커밋의 짧은 해시를 반환합니다. 이미지를 빌드한 후, docker tag 명령어로 하나의 이미지에 여러 태그를 추가합니다.

중요한 점은 같은 이미지에 여러 태그를 동시에 부여한다는 것입니다. 1.2.3이라는 명확한 버전 태그도 있고, a3f7b2e라는 Git 해시 태그도 있고, build-456이라는 빌드 번호 태그도 있습니다.

각각의 태그가 서로 다른 용도로 사용됩니다. 실제 현업에서는 어떻게 활용할까요?

네이버, 카카오 같은 대형 IT 기업들은 복합적인 태그 전략을 사용합니다. 시맨틱 버전으로 메이저 릴리스를 표시하고, Git 해시로 정확한 코드 상태를 추적하고, 빌드 번호로 CI/CD 파이프라인과 연결합니다.

또한 환경별로 dev, staging, prod 같은 접두사를 붙이기도 합니다. Kubernetes 환경에서는 롤링 업데이트 시 태그가 매우 중요합니다.

imagePullPolicy가 Always로 설정되어 있어도, 태그가 같으면 새 이미지를 받아오지 않을 수 있습니다. 따라서 매 배포마다 고유한 태그를 사용해야 합니다.

하지만 주의할 점도 있습니다. latest 태그는 개발 환경에서만 사용하세요. "latest가 최신 버전이니까 편하지 않나요?"라고 생각할 수 있지만, 문제가 생겼을 때 어떤 버전으로 돌아가야 할지 알 수 없습니다.

또한 여러 서버에서 동시에 배포하면 각 서버가 서로 다른 "latest"를 받을 수 있습니다. 또 다른 실수는 태그를 덮어쓰는 것입니다.

1.2.3 태그로 이미 푸시한 이미지가 있는데, 코드를 수정하고 다시 같은 태그로 푸시하면 혼란이 생깁니다. ECR에서는 imageTagMutability를 IMMUTABLE로 설정하여 이를 방지할 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언대로 태그 전략을 수립한 김개발 씨는 이제 자신 있게 배포할 수 있게 되었습니다.

"버전 관리가 이렇게 중요한 줄 몰랐어요!" 올바른 이미지 태그 전략을 사용하면 배포 히스토리를 명확하게 추적하고, 문제 발생 시 빠르게 롤백할 수 있습니다. 여러분도 오늘 배운 내용을 팀의 배포 프로세스에 적용해 보세요.

실전 팁

💡 - 시맨틱 버전, Git 해시, 빌드 번호를 모두 태그로 추가하여 다각도로 추적하세요

  • 운영 환경에서는 절대 latest를 사용하지 마세요. 명확한 버전을 지정하세요
  • ECR의 imageTagMutability를 IMMUTABLE로 설정하여 태그 덮어쓰기를 방지하세요

5. 수명 주기 정책

김개발 씨는 몇 달 동안 열심히 배포했더니 ECR에 이미지가 수백 개 쌓여있었습니다. "이거 다 지워야 하나요?

비용이 걱정되는데..." 박시니어 씨가 웃으며 말했습니다. "수명 주기 정책으로 자동화하면 돼요!"

**수명 주기 정책(Lifecycle Policy)**은 오래되거나 불필요한 이미지를 자동으로 삭제하는 기능입니다. 이미지 개수, 나이, 태그 상태 등을 기준으로 규칙을 만들 수 있습니다.

적절한 정책을 설정하면 스토리지 비용을 절감하고, 레포지토리를 깔끔하게 유지할 수 있습니다.

다음 코드를 살펴봅시다.

// ECR 수명 주기 정책 JSON 예제
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "최근 10개의 이미지만 유지",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["v"],
        "countType": "imageCountMoreThan",
        "countNumber": 10
      },
      "action": {
        "type": "expire"
      }
    },
    {
      "rulePriority": 2,
      "description": "태그 없는 이미지는 7일 후 삭제",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 7
      },
      "action": {
        "type": "expire"
      }
    },
    {
      "rulePriority": 3,
      "description": "개발 이미지는 30일 후 삭제",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["dev-", "test-"],
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 30
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

김개발 씨는 어느 날 AWS 비용 알림을 받았습니다. ECR 스토리지 비용이 예상보다 많이 나온 것입니다.

레포지토리를 확인해보니 6개월 동안 배포한 이미지가 무려 300개나 쌓여있었습니다. 박시니어 씨가 화면을 보며 말했습니다.

"대부분 테스트용이나 오래된 버전이네요. 이런 걸 일일이 지우는 건 비효율적이에요.

수명 주기 정책을 설정해두면 자동으로 정리됩니다." 수명 주기 정책이란 정확히 무엇일까요? 쉽게 비유하자면, 수명 주기 정책은 마치 냉장고의 자동 관리 시스템과 같습니다.

유통기한이 지난 음식은 자동으로 폐기하고, 오래된 반찬은 우선적으로 소비하도록 알려줍니다. ECR도 마찬가지로 오래된 이미지를 자동으로 삭제하고, 중요한 최신 이미지만 보관합니다.

왜 수명 주기 정책이 필요할까요? 스토리지 비용 절감이 가장 큰 이유입니다.

ECR은 저장 용량에 따라 비용이 청구됩니다. 사용하지 않는 오래된 이미지가 수백 개 쌓이면 매달 불필요한 비용을 지불하게 됩니다.

정책을 설정하면 자동으로 공간을 확보할 수 있습니다. 또한 레포지토리 관리의 편의성도 중요합니다.

이미지가 수백 개 쌓이면 원하는 버전을 찾기 어렵습니다. 최근 몇 개의 의미 있는 버전만 남겨두면 훨씬 관리하기 쉽습니다.

위의 정책을 자세히 살펴보겠습니다. 첫 번째 규칙은 태그가 있는 이미지 중 최근 10개만 유지합니다.

tagPrefixList에 "v"를 지정했으므로, v1.0.0, v1.1.0 같은 버전 태그만 해당됩니다. 11번째로 오래된 이미지부터 자동으로 삭제됩니다.

두 번째 규칙은 태그가 없는 이미지를 7일 후 삭제합니다. Docker 빌드 중간 레이어나 실패한 푸시로 생긴 이미지들은 보통 태그가 없습니다.

이런 불필요한 이미지들을 주기적으로 정리합니다. 세 번째 규칙은 개발 환경 이미지를 30일 후 삭제합니다.

dev-, test- 접두사가 붙은 태그는 일시적인 테스트용이므로, 오래 보관할 필요가 없습니다. 운영 이미지는 이 규칙에 해당하지 않으므로 안전하게 보관됩니다.

중요한 점은 rulePriority입니다. 숫자가 낮을수록 우선순위가 높습니다.

하나의 이미지가 여러 규칙에 해당하면, 우선순위가 높은 규칙이 적용됩니다. 따라서 가장 중요한 규칙을 1번으로 설정하세요.

실제 현업에서는 어떻게 활용할까요? 많은 기업들이 환경별로 다른 정책을 사용합니다.

개발 환경은 최근 5개, 스테이징은 10개, 운영 환경은 20개를 유지하는 식입니다. 운영 환경일수록 롤백 가능성을 고려하여 더 많은 버전을 보관합니다.

또한 정기적으로 정책을 리뷰합니다. 처음에는 10개로 설정했다가, 배포 빈도가 높아지면 20개로 늘리기도 합니다.

반대로 배포가 안정화되면 개수를 줄여 비용을 절감합니다. 하지만 주의할 점도 있습니다.

너무 공격적인 정책은 위험합니다. 예를 들어 "최근 3개만 유지"로 설정했는데, 갑자기 3개 버전 모두 문제가 있다면 롤백할 버전이 없습니다. 안전을 위해 최소 10개 정도는 유지하는 것이 좋습니다.

또 다른 실수는 운영 이미지에 너무 짧은 기간을 설정하는 것입니다. 30일 후 삭제하도록 했는데, 한 달 뒤에 문제가 발견되면 해당 이미지가 이미 삭제되어 있을 수 있습니다.

운영 환경은 최소 90일 이상 보관하는 것을 권장합니다. 정책을 적용하기 전에는 반드시 미리 보기 기능을 사용하세요.

AWS 콘솔에서 정책을 테스트하면 어떤 이미지가 삭제될지 미리 확인할 수 있습니다. 실수로 중요한 이미지를 삭제하는 것을 방지할 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 수명 주기 정책을 설정한 김개발 씨는 다음 달 청구서를 확인하고 놀랐습니다.

"와, 비용이 절반으로 줄었어요!" 올바른 수명 주기 정책을 사용하면 자동으로 레포지토리를 깔끔하게 유지하고, 불필요한 비용을 절감할 수 있습니다. 여러분도 오늘 배운 내용을 토대로 팀의 정책을 수립해 보세요.

실전 팁

💡 - 정책 적용 전 미리 보기로 어떤 이미지가 삭제될지 확인하세요

  • 개발 환경은 짧게(5-10개), 운영 환경은 넉넉하게(20개 이상) 설정하세요
  • 태그 없는 이미지는 7일 이내로 삭제하여 불필요한 공간을 확보하세요

6. ECR 권한 설정

김개발 씨의 팀에 새로운 주니어 개발자가 합류했습니다. "이분도 ECR에 접근할 수 있게 해주세요." 하지만 모든 권한을 주기는 불안했습니다.

박시니어 씨가 조언했습니다. "필요한 권한만 주는 게 중요해요."

ECR 권한 설정은 AWS IAM을 통해 누가 이미지를 읽고, 쓰고, 삭제할 수 있는지 제어합니다. 레포지토리 정책, IAM 사용자 정책, 역할 기반 접근 등 다양한 방법이 있습니다.

최소 권한 원칙을 따라 각 사용자와 서비스에 꼭 필요한 권한만 부여해야 안전합니다.

다음 코드를 살펴봅시다.

// ECR 읽기 전용 IAM 정책 (개발자용)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ecr:DescribeRepositories",
        "ecr:ListImages"
      ],
      "Resource": "arn:aws:ecr:ap-northeast-2:123456789012:repository/my-app"
    }
  ]
}

// ECR 전체 권한 IAM 정책 (DevOps용)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:*"
      ],
      "Resource": "arn:aws:ecr:ap-northeast-2:123456789012:repository/my-app"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken"
      ],
      "Resource": "*"
    }
  ]
}

// ECS 태스크가 ECR 이미지를 가져올 수 있는 역할
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }
  ]
}

김개발 씨는 처음에 모든 팀원에게 동일한 관리자 권한을 줬습니다. 편하긴 했지만, 누군가 실수로 운영 이미지를 삭제할까 봐 불안했습니다.

실제로 한 번은 주니어 개발자가 잘못된 명령어를 실행해 테스트 이미지를 모두 삭제한 적도 있었습니다. 박시니어 씨가 팀 회의에서 말했습니다.

"이제 우리도 권한을 제대로 나눠야 할 때가 됐어요. 각자 역할에 맞는 권한만 갖도록 합시다." ECR 권한은 어떻게 관리할까요?

쉽게 비유하자면, ECR 권한은 마치 회사의 출입 카드 시스템과 같습니다. 모든 직원이 CEO 사무실에 들어갈 수 있으면 안 되겠죠.

일반 직원은 자기 층만, 팀장은 팀 구역만, 임원은 모든 층에 접근할 수 있도록 권한을 나눕니다. ECR도 마찬가지로 역할에 따라 다른 권한을 부여합니다.

ECR 권한의 핵심 액션은 무엇일까요? GetAuthorizationToken은 Docker 로그인에 필요한 토큰을 받는 권한입니다.

이미지를 푸시하거나 풀하려면 반드시 있어야 합니다. 모든 사용자에게 필요한 기본 권한입니다.

BatchGetImageGetDownloadUrlForLayer는 이미지를 다운로드하는 권한입니다. 개발자가 로컬에서 이미지를 받아 테스트하거나, ECS/EKS가 이미지를 가져올 때 필요합니다.

읽기 전용 권한으로 충분한 경우 이것만 부여합니다. PutImage는 이미지를 업로드하는 권한입니다.

CI/CD 파이프라인이나 DevOps 엔지니어에게 필요합니다. 일반 개발자는 직접 푸시할 필요가 없으므로 제한하는 것이 안전합니다.

DeleteRepositoryDeleteLifecyclePolicy는 삭제 권한입니다. 매우 위험한 권한이므로 소수의 관리자에게만 부여해야 합니다.

실수로 운영 레포지토리를 삭제하면 서비스 장애로 이어질 수 있습니다. 위의 정책을 자세히 살펴보겠습니다.

첫 번째 정책은 일반 개발자용 읽기 전용 권한입니다. 이미지를 다운로드하고, 목록을 확인할 수 있지만 새로운 이미지를 푸시하거나 삭제할 수는 없습니다.

로컬 개발 환경에서 테스트하기에 충분합니다. 두 번째 정책은 DevOps 엔지니어용 전체 권한입니다.

ecr:*는 ECR의 모든 액션을 허용합니다. 레포지토리 생성, 이미지 푸시/삭제, 정책 변경 등 모든 작업이 가능합니다.

하지만 특정 레포지토리로 제한했으므로, 다른 팀의 레포지토리는 건드릴 수 없습니다. 세 번째 정책은 ECS 태스크용 역할입니다.

ECS가 ECR에서 이미지를 가져와 컨테이너를 실행할 때 필요합니다. 사람이 아니라 서비스가 사용하는 권한이므로, 읽기 전용으로 제한합니다.

실제 현업에서는 어떻게 활용할까요? 대부분의 기업은 **역할 기반 접근 제어(RBAC)**를 사용합니다.

주니어 개발자는 읽기 전용, 시니어 개발자는 특정 레포지토리에 쓰기 권한, DevOps 팀은 전체 관리 권한을 갖는 식입니다. 이렇게 하면 실수를 최소화하고, 누가 무엇을 했는지 추적할 수 있습니다.

또한 CI/CD 파이프라인 전용 IAM 역할을 만듭니다. GitHub Actions, Jenkins, GitLab CI가 사용하는 역할은 이미지 푸시 권한만 갖도록 제한합니다.

사람의 계정과 분리하여 보안 감사가 쉬워집니다. 교차 계정 접근도 중요합니다.

여러 AWS 계정을 사용하는 대기업에서는 레포지토리 정책을 사용하여 다른 계정의 ECS가 이미지를 가져갈 수 있도록 허용합니다. 하지만 반드시 필요한 계정만 명시적으로 허용해야 합니다.

하지만 주의할 점도 있습니다. 와일드카드(*)를 남발하지 마세요. "Resource": "*"는 모든 리소스에 권한을 주는 것입니다.

특정 레포지토리 ARN을 명시하여 범위를 제한하는 것이 안전합니다. GetAuthorizationToken처럼 리소스를 지정할 수 없는 경우만 * 를 사용하세요.

또 다른 실수는 IAM 사용자에게 직접 권한을 부여하는 것입니다. 가능하면 IAM 그룹을 만들고, 그룹에 정책을 연결한 뒤, 사용자를 그룹에 추가하세요.

이렇게 하면 권한 관리가 훨씬 쉬워집니다. 정기적으로 권한을 리뷰하는 것도 중요합니다.

퇴사한 직원의 계정은 즉시 삭제하고, 팀을 옮긴 직원의 권한은 조정하세요. AWS IAM Access Analyzer를 사용하면 과도한 권한을 자동으로 탐지할 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 역할별로 권한을 나눈 김개발 씨의 팀은 훨씬 안전하게 ECR을 사용할 수 있게 되었습니다.

"이제 실수로 운영 이미지를 지울 일은 없겠어요!" 올바른 ECR 권한 설정을 사용하면 보안을 강화하고, 실수를 방지하며, 감사 추적을 쉽게 할 수 있습니다. 여러분도 오늘 배운 내용을 토대로 팀의 권한 체계를 정비해 보세요.

실전 팁

💡 - 최소 권한 원칙을 따라 꼭 필요한 권한만 부여하세요

  • IAM 그룹을 활용하여 역할별로 권한을 관리하면 유지보수가 쉽습니다
  • CloudTrail로 ECR 액션을 로깅하여 보안 감사를 수행하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#ECR#Docker#DevOps#Container

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.