『速记』使用AWS ECR作为私有Docker Image镜像仓库
想要解决的问题
我想有一个私有的Docker Image仓库。最近接触 AWS 相关服务比较多,而 AWS 的容器镜像存储服务(ECR),又是按使用量计费,比较符合自己的需要。
Storage is $0.10 per GB / month for data stored in private or public repositories.
AWS的ECR只是一个附属的AWS服务,所以配置上,相对专门的容器仓库,会稍微多一些额外的配置,特地记录和整理下,供以后自己参考。
解决问题的思路概要
flowchart TD
create-aws-ecr-user[①创建只有 ECR 权限的 IAM 账户]
--> get-ecr-key[②创建用于 ECR 权限验证的 ACCESS_KEY]
--> login-in-docker-client[③在Docker客户端中,登录 AWS ECR]
--> push-sample[④尝试往AWS ECR Push image]
--> pull-sample[⑤尝试从 AWS ECR Pull image]
;
具体步骤与细节
①创建只有 ECR 权限的 IAM 账户
- 【AmazonEC2ContainerRegistryPowerUser】有 Push + Pull权限,但是不允许删除镜像。
- 如果准备用到仅需要拉取镜像的环境中,【AmazonEC2ContainerRegistryReadOnly】可能会更适合。
- 不同权限组的差异,详见: AWS managed policies for Amazon Elastic Container Registry
②创建用于 ECR 权限验证的 ACCESS_KEY
- 【SECRET ACCESS KEY】需要妥善保管,后续将没有机会再看到。
- 使用ACCESS_KEY进行鉴权,被AWS标记为【不推荐】。所以,请结合自己的使用场景,适当考虑下其他 【AWS推荐】的鉴权方式。详见: Authentication and access credentials for the AWS CLI
③讨论:为什么我这次倾向于使用 【ACCESS_KEY】的方式来进行 AWS鉴权?
- 因为后续想把容器镜像管理集成进 CI 系统里。
- 短期授权,当然更好;但是授权过期后,需要手动二次授权。。。我不可能大半夜爬起来去给 CI重新跑授权步骤。
- “权衡”与“平衡”。一个权限授权的专用【ACCESS_KEY】,至少目前所带来的风险,是可控的。
- 如果 CI 本身跑在 EC2 里,可以借助 EC2 本身的 IAM Role授权,这样其实是可以不需要【ACCESS_KEY】的。
- 我不想依赖EC2,打包和编译,也需要一个较高配置的电脑。
- 总而言之,基于【ACCESS_KEY】授权,风险可控,收益客观。当然,还是看场景,看需要。
④在Docker客户端中,登录 AWS ECR
- 首先,如果是使用的 Docker Desktop,建议先把 【Use containerd for pulling and storing images】配置给关闭掉。否则,默认会产生 OCI 格式的 docker 镜像。
- 基于环境变量,配置 AWS 授权信息。考虑优先使用 【环境变量】来配置,主要是方便后续改造成 CI 工具。其他配置方式,参见: Configuring settings for the AWS CLI
【ap-northeast-1】需要替换你自己的 ECR 仓库所在的地区。
# Linux / macOS
export AWS_ACCESS_KEY_ID=YOUR-AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR-AWS_SECRET_ACCESS_KEY
export AWS_DEFAULT_REGION=ap-northeast-1
# windows-cmd
set AWS_ACCESS_KEY_ID=YOUR-AWS_ACCESS_KEY_ID
set AWS_SECRET_ACCESS_KEY=YOUR-AWS_SECRET_ACCESS_KEY
set AWS_DEFAULT_REGION=ap-northeast-1
# windows-PowverShell
$Env:AWS_ACCESS_KEY_ID="YOUR-AWS_ACCESS_KEY_ID"
$Env:AWS_SECRET_ACCESS_KEY="YOUR-AWS_SECRET_ACCESS_KEY"
$Env:AWS_DEFAULT_REGION="ap-northeast-1"
- 在Docker client中登录 AWS ECR。
【389041481283】需要替换成你自己的 AWS Account ID。
aws ecr get-login-password | docker login --username AWS --password-stdin 389041481283.dkr.ecr.ap-northeast-1.amazonaws.com
④尝试往AWS ECR Push image
- 首先,需要先创建一个对应的镜像仓库。
【Image tag settings】建议选 【Immutable】,避免不必要的镜像版本管理混乱。
- build and push image:
【389041481283】需要替换成你自己的 AWS Account ID。
# 编译命令,可能要根据项目配置,动态修改。
docker build --no-cache --platform=linux/amd64 -t 389041481283.dkr.ecr.ap-northeast-1.amazonaws.com/kyo520/helloworld:0.0.1 .
docker push 389041481283.dkr.ecr.ap-northeast-1.amazonaws.com/kyo520/helloworld:0.0.1
- 注意:在非Linux平台编译镜像时,最好指定下目标平台的参数,如 –platform=linux/amd6. 否则实际部署时,有可能遇到错误:
exec /usr/local/bin/docker-entrypoint.sh: exec format error
⑤尝试从 AWS ECR Pull image
- 完成AWS鉴权之后,直接使用 docker 自己的镜像拉取命令即可。
docker pull 389041481283.dkr.ecr.ap-northeast-1.amazonaws.com/kyo520/helloworld:0.0.1