Amazon ECR 은 이미지 하나에 리포지토리 하나를 만드는 구조가 아니다. 하나의 리포지토리가 여러 태그를 담으므로 애플리케이션(또는 컴포넌트) 단위로 리포지토리를 만들고 버전은 태그로 구분하는 것이 일반적이다. 리포지토리 이름에는 / 를 넣을 수 있어 viya4/fluent 같은 계층형 이름도 그대로 만들 수 있다. 다만 이것은 이름에 포함된 문자일 뿐 실제 디렉터리 구조가 아니므로, viya4/fluent 리포지토리는 viya4 와 별개로 따로 만들어야 한다.
같은 애플리케이션의 버전은 한 리포지토리 안에서 태그로 관리한다. 수명주기 정책(lifecycle policy)이 리포지토리 단위로 걸리므로, 보존 기간이 다른 이미지끼리는 리포지토리를 나눠야 정책을 따로 줄 수 있다. 권한도 리포지토리 정책 단위이므로 팀별로 접근을 가르려면 그 경계에 맞춘다.
aws ecr create-repository --repository-name viya4/fluent --region ap-northeast-2
aws ecr describe-repositories --query 'repositories[].repositoryName'
ECR 은 push 시점에 리포지토리를 자동으로 만들지 않는다. 없는 리포지토리로 push 하면 failed to start upload, unexpected status: 404 Not Found 로 끝난다. 이름이 완전히 일치하는 리포지토리가 있는지부터 본다. Helm 차트를 OCI 로 올릴 때도 같다 — 차트 이름과 같은 리포지토리가 미리 있어야 한다.
helm registry login --username AWS \
--password "$(aws ecr get-login-password --region ap-northeast-2)" \
<account>.dkr.ecr.ap-northeast-2.amazonaws.com
aws ecr create-repository --repository-name charts/myapp
helm push myapp-1.0.0.tgz oci://<account>.dkr.ecr.ap-northeast-2.amazonaws.com/charts
helm push 는 대상 경로 뒤에 차트 이름을 자동으로 붙인다. 위 예에서 실제 대상은 charts/myapp 이므로 그 이름으로 리포지토리를 만들어 둔다.
IAM 권한 문제다. is not authorized to perform: ecr:CreateRepository 처럼 부족한 액션이 메시지에 그대로 나오므로 그 액션을 정책에 추가한다. push 에 필요한 최소 액션은 다음과 같다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ecr:GetAuthorizationToken"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": "arn:aws:ecr:ap-northeast-2:<account>:repository/*"
}
]
}
ecr:GetAuthorizationToken 만 리소스를 한정할 수 없어 * 로 둔다. 리포지토리를 CLI 로 만들어야 하면 ecr:CreateRepository 를 추가한다. 리포지토리 정책(리소스 기반)이 따로 걸려 있으면 IAM 정책이 허용해도 막히므로 양쪽을 모두 본다.
aws ecr get-login-password 로 얻는 토큰은 12시간 동안만 유효하다. 장시간 도는 파이프라인에서 push 직전에 다시 로그인하지 않으면 중간에 401/403 이 난다.
프라이빗 서브넷에서 NAT 없이 ECR 을 쓰려면 VPC 엔드포인트가 세 개 필요하다 — com.amazonaws.<region>.ecr.api, com.amazonaws.<region>.ecr.dkr, 그리고 레이어 실체가 저장되는 S3 게이트웨이 엔드포인트다. S3 엔드포인트를 빼면 인증과 매니페스트는 되는데 레이어 전송에서 멈춘다.
IAM 정책을 방금 바꿨는데 반영되지 않는 것처럼 보이면 임시 자격증명(STS) 세션이 옛 권한을 들고 있는 경우다. 자격증명을 새로 받아 다시 시도한다.