ArgoCD로 로컬 Minikube 클러스터에 앱이 배포되도록 구성해 두었고, 여기까지는 Docker Hub의 public 이미지를 받아 쓰고 있었다. 이미지를 AWS ECR로 옮기자 Pod가 뜨지 않았다.
no basic auth credentials, 인증 정보가 없다는 말이다. public 이미지는 인증 없이 받을 수 있지만 ECR은 private 레지스트리라서 받는 쪽이 자격증명을 들고 가야 한다. 이 글에서는 그 자격증명을 누가 들고 있어야 했는지, 처음 시도는 왜 소용없었는지 정리한다.
공식 문서의 docker login으로는 바뀌지 않았다
AWS 공식 문서가 안내하는 ECR 로그인 명령은 이렇다.
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin {AWS Account ID}.dkr.ecr.ap-northeast-2.amazonaws.com
이 명령을 써도 에러 내용은 그대로였다. 처음 찾은 방법은 이 명령으로 ~/.docker/config.json에 자격증명이 기록되니, 그 파일로 Kubernetes Secret을 만들라는 것이었다. 파일에는 새로 기록된 내용 자체가 없었다.
돌아보면 두 가지를 섞어 보고 있었다. docker login은 내 터미널의 Docker에 로그인하는 것이지 Minikube에 로그인하는 것이 아니다. 이미지를 받는 주체는 Minikube 노드 안의 컨테이너 런타임이고, 그쪽은 로컬 터미널의 로그인 상태를 모른다. Kubernetes에서 private 레지스트리 자격증명은 docker-registry 타입 Secret으로 클러스터 안에 넣고 Pod가 그 Secret을 참조하게 해야 한다.
graph LR A[로컬 터미널 docker login] -.->|전달되지 않음| C[Minikube 노드] S[Secret ecr-registry] -->|imagePullSecrets| C B[ArgoCD] -->|Deployment 적용| C C -->|이미지 pull| E[AWS ECR]
파일에 내용이 비어 있던 이유는 확인하지 못했다. Docker Desktop처럼 자격증명을 config.json 대신 OS 키체인에 넣는 credential store를 쓰면 파일에는 인증 정보가 남지 않는데, 그 경우였을 수 있다.
docker-registry Secret을 직접 만들었다
두 번째로 찾은 방법도 Secret을 만드는 것은 같지만, 파일을 거치지 않고 바로 만든다.
kubectl create secret docker-registry ecr-registry \
--docker-server=https://{AWS Account ID}.dkr.ecr.ap-northeast-2.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password) \
--docker-email={Email정보}
# 시크릿 생성 확인
kubectl get secret
# Deployment 재시작
kubectl create secret docker-registry: 레지스트리 자격증명을 Kubernetes Secret으로 만든다.--docker-server: ECR 레지스트리의 베이스 URL만 넣는다. 개별 이미지 이름이나 레포지토리 경로(/saas같은)는 붙이지 않는다.--docker-username=AWS: ECR 토큰 인증의 사용자 이름은 항상AWS다.--docker-password=$(aws ecr get-login-password): 서브쉘로 ECR 로그인 패스워드를 받아 바로 넘긴다. 파일에 기록될 필요가 없어서 앞의 문제를 피해 간다.--docker-email: 사용자 이메일 주소. Secret 생성에 꼭 필요하지는 않지만 오류를 피하려고 넣을 수 있다.
Secret을 만든 뒤 Deployment를 재시작하자 이미지를 받아 왔다.
이 Secret은 12시간 뒤에 만료된다
aws ecr get-login-password가 돌려주는 토큰은 12시간 동안만 유효하다. Secret 안의 비밀번호도 그 토큰이라서, 시간이 지나 Pod가 다시 이미지를 받아야 할 때 같은 에러가 다시 날 수 있다. 로컬 실습이라면 그때 Secret을 다시 만들면 되지만, 오래 두는 클러스터라면 토큰 갱신을 자동화할 방법을 따로 찾아야 한다. 이건 다음에 다시 봐야겠다.