AWS CLI v2에서 아마존 ECR 로그인 방법 변경
기존 ecr 명령어 get-login 삭제

들어가며

지난 2월 10일 아마존 웹 서비스Amazon Web Services의 공식 커맨드라인 클라이언트 AWS CLI v2가 정식 공개되었습니다.

AWS CLI v2는 여러가지 변화가 있습니다만, 오늘 소개할 부분은 아마존에서 제공하는 도커 프라이빗 레지스트리 서비스 아마존 ECRAmazon Elastic Container Registry의 로그인 방법입니다.

44BITS 소식과 클라우드 뉴스를 전해드립니다. 지금 5,000명 이상의 구독자와 함께 하고 있습니다 📮

AWS CLI v1의 아마존 ECR 로그인 방법 해설

도커에서 프라이빗 레지스트리를 사용하기 위해서는 먼저 도커 클라이언트를 사용해 로그인을 해야합니다. 아마존 ECR에서는 AWS CLI v1 기준 다음과 같은 로그인 방법을 소개해왔습니다. 도커가 설치된 서버에서 다음 명령어를 실행하면 AWS 계정의 ECR에 짠하고 로그인이 이루어집니다.*

* 물론 AWS 액세스키가 잘 셋업되어있을 경우의 이야기입니다. 이에 대한 더 자세한 내용은 아마존 웹서비스 커맨드라인 인터페이스(AWS CLI) 기초아마존 웹 서비스 IAM 사용자의 액세스 키 발급 및 관리 글을 참고해주세요.

$ aws --version
aws-cli/1.16.310 Python/3.8.1 Darwin/19.3.0 botocore/1.13.46

$ $(aws ecr get-login --no-include-email --region ap-northeast-2)

이 명령어의 비밀 레시피를 확인하려면 $()를 제거하고 명령어를 실행해보면 됩니다. $()는 괄호 사이의 명령을 실행한 다음 그 결과 문자열을 다시 실행하는 셸 문법입니다. 따라서 $()를 제거하고 실행하면 실제로 실행되는 명령어를 확인할 수 있습니다.

$ aws ecr get-login --no-include-email --region ap-northeast-2
docker login -u AWS -p <blahblah> https://<ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com

실제로는 docker login 명령어가 실행되는 것을 확인할 수 있습니다. 명령어를 실행하는 시점에 AWS CLI가 임시 패스워드를 받아와 프라이빗 도커 레지스트리(ECR)에 로그인을 수행합니다.

로그인을 한 번 해보겠습니다.

$(aws ecr get-login --no-include-email --region ap-northeast-2)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

정상적으로 로그인된 것을 확인할 수 있습니다.

AWS CLI v2의 아마존 ECR 로그인 방법

그럼 여기서부터는 AWS CLI v2를 소개합니다. 맥OSmacOS를 사용한다면 brew 명령어를 통해 AWS CLI를 설치하거나 업그레이드할 수 있습니다. 더 자세한 내용은 각 운영체제별 공식 설치 문서를 참고해주세요.

$ brew upgrade awscli 

2020년 4월 기준 최신 버전을 설치하거나 업그레이드하면 2.0.6이 설치됩니다.

$ aws --version
aws-cli/2.0.6 Python/3.8.2 Darwin/19.3.0 botocore/2.0.0dev10

먼저 get-login을 시도해보겠습니다.

$ aws ecr get-login --no-include-email --region ap-northeast-2
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:

...
tag-resource                             | untag-resource
upload-layer-part                        | get-login-password
wait                                     | help

실행 자체가 되질 않습니다. 오류 메시지를 보면 해당하는 명령operation이 존재하지 않는다는 것을 확인할 수 있습니다. 그 아래로는 실행 가능한 명령어들을 보여주는데 get-login은 안보이고, 비슷한 get-login-password가 있습니다.

문서를 확인해보면 get-login 명령어가 비추천Deprecated된 것을 확인할 수 있습니다. get-login-password는 명령어 이름에서 유추할 수 있듯이 도커 로그인 패스워드만을 반환해줍니다. AWS에서 가이드하고 있는 새로운 로그인 방법은 다음과 같습니다.

$ aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/
Login Succeeded

조금 더 까다롭네요. 셸의 파이프 문법도 사용하고 있고 ACCOUNT_ID와 레지스트리 주소도 알아야합니다. 조금 머리를 굴려보면 파이프를 사용하지 않고 AWS CLI v1과 비슷하게 모양을 만들어볼 수 있습니다.

$ docker login --username AWS -p $(aws ecr get-login-password --region ap-northeast-2) <ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

잘 동작하네요. 그런데 두 명령어의 실행 결과 사이에 중요한 차이점을 하나 확인할 수 있습니다. get-login을 사용하거나 -p(패스워드) 옵션을 직접 사용하는 경우 다음과 같은 경고 메시지가 출력됩니다.

WARNING! Using --password via the CLI is insecure. Use --password-stdin.

반면에 AWS 공식 가이드대로 파이프를 사용해서 --password-stdin 옵션을 사용해 패스워드를 넘겨받는 경우, 더 이상 이 보안 경고 문구가 나타나지 않습니다. 이는 도커 클라이언트의 경고 메시지로 셸 명령어에 패스워드를 입력할 경우, 의도치 않게 노출되거나 로그 상에 남을 수 있기 때문에 경고를 출력합니다.

AWS CLI 저장소에서도 이 문제에 대한 이슈가 꽤 오래 전부터 논의중이었던 것을 확인할 수 있습니다.

물론 get-loginget-login-password는 모두 패스워드를 노출 시킬 수 있기 때문에 직접 실행할 때는 주의가 필요합니다. 현재 get-login-password는 v1.17.10 이후 버전과 v2에서 사용 가능하니, 가능하면 get-login보다 이 명령어를 사용하는 것을 권장합니다. 그리고 앞에서 확인했듯이 v2에서는 get-login 명령어를 사용할 수 없습니다.

이제 <ACCOUNT_ID>를 직접 확인해야한다는 불편함이 남아있습니다만, aws sts get-caller-identity를 사용하면 CLI에서도 어카운트 ID를 확인할 수 있습니다. aws/aws-cli#2875 이슈 마지막 pgilad 님의 코멘트에서는 이 API를 사용해 어카운트 ID를 자동으로 가져오는 방법을 소개하고 있습니다.

$ aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.ap-northeast-2.amazonaws.com"

이미지 푸시 등을 자동화할 때 이 방법을 사용할 수 있겠네요.

그럼 get-login이 동작하지 않아도 당황하지 마시고, get-login-password를 사용해보시기 바랍니다.

참고 문서

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리

🗒 기사, 2018-12-03 - chroot는 프로세스의 루트 디렉터리를 변경하는 리눅스 시스템콜/명령어입니다. 루트를 변경함으로써 아주 기초적인 단계의 컨테이너를 구현해볼 수 있습니다. chroot는 아주 단순한 프로그램입니다만, 루트가 달라지면 프로세스의 동작 방식 달라져 실제로는 사용하기가 까다로운 편입니다. 이 글에서는 chroot의 기본적인 원리와 사용법에 대해서 소개합니다.

패커(Packer)를 사용한 도커 이미지와 AMI 만들기(feat. Ansible)

🗒 기사, 2015-09-30 - 패커는 하시코프에서 만든 범용 가상머신, 컨테이니 이미지 생성 도구입니다. 패커는 시스템의 특정 상태를 저장하는 대신 복원 가능한 방식으로 이미지 생성을 자동화할 수 있게 도와줍니다. 이 글에서는 패커를 사용해 도커 이미지와 AMI 이미지를 빌드하는 방법을 소개합니다.

Write the Docs 서울 밋업 준비 기록

🗒 기사, 2019-05-03 - 2019년 3월에 열린 Write The Docs 서울의 밋업을 준비하면서, 디자이너 없이 꾸역꾸역 대표 이미지와 스티커, 현수막, 배너를 직접 제작한 경험을 정리해보았습니다.