将 docker 镜像推送到亚马逊 ecs 存储库
Posted
技术标签:
【中文标题】将 docker 镜像推送到亚马逊 ecs 存储库【英文标题】:Push docker image to amazon ecs repository 【发布时间】:2016-09-29 04:25:05 【问题描述】:我是 AWS 新手。我想在 AWS ECS 容器实例上设置一个私有 docker 存储库。我创建了一个名为 name
的存储库。 AWS 显示的示例推送命令正在运行。
aws ecr get-login --region us-west-2
docker build -t name .
docker tag name:latest ############.dkr.ecr.us-west-2.amazonaws.com/name:latest
docker push ############.dkr.ecr.us-west-2.amazonaws.com/name:latest
但是通过这些命令,我构建并推送了一个名为 name
的映像,并且我想构建一个名为 foo
的映像。所以我将命令更改为:
docker build -t foo .
docker tag foo ###########.dkr.ecr.us-west-2.amazonaws.com/name/foo
docker push ###########.dkr.ecr.us-west-2.amazonaws.com/name/foo
这应该有效,但它没有。经过一段时间的重试后,我得到了错误:
The push refers to a repository [###########.dkr.ecr.us-west-2.amazonaws.com/name/foo]
8cc63cf4528f: Retrying in 1 second
...
name unknown: The repository with name 'name/foo' does not exist in the registry with id '############'
AWS 是否真的需要为我要推送的每张图片使用一个专用存储库?
【问题讨论】:
【参考方案1】:EC2 Container Registry 需要为您要发布到注册表的每个图像“名称”或“名称空间/名称”设置一个 image Repository。
您可以在每个存储库中发布您想要的任何:tags
(默认限制为 100 个标签)。
我在 AWS 文档中没有看到任何具体说明存储库的地方 -> 映像名称映射,但 Creating a Repository - Section 6d in the ECR User Guide 暗示了这一点
Docker Image spec 包括它对存储库的定义
存储库
在一个公共前缀(
:
之前的名称组件)下分组的标签集合。例如,在带有名称标记的图像中my-app:3.1.4
,my-app 是名称的 Repository 组件。一种 存储库名称由斜杠分隔的名称组成, 可选地以 DNS 主机名作为前缀。主机名必须符合 标准 DNS 规则,但不得包含_
字符。如果主机名是 存在,它可以可选地后跟一个端口号,格式为:8080
。名称组件可能包含小写字符、数字和 分隔符。分隔符定义为句点,一个或两个 下划线或一个或多个破折号。名称组件可能无法启动或 以分隔符结尾。
【讨论】:
是否有任何文档明确说明每个注册表一个图像? 是的,抱歉,我的意思是每个存储库一个图像名称。 啊.. 我不认为 AWS 明确声明他们的 ECR 存储库概念与单个 Docker 映像name
或 namespace/name
相关。第一次我花了几次尝试才弄明白。 docs.aws.amazon.com/AmazonECR/latest/userguide/… 上的第 6d 节暗示了一个名称/多标签存储库设置,其映像构建标签为 repository:latest
@Matt 我希望他们 (aws) 能够确定这一点并使其成为一个铁的事实。我不喜欢松散的解释,因为他们的文档是写的。
supersedes 是 Docker 营销部门希望您接受的一个强有力的术语。 hub 不会去任何地方,甚至可以成为“免费”商店图片的来源。【参考方案2】:
您需要为每个图像名称创建一个存储库,但图像名称的格式可以是“mycompanyname/helloworld”。所以你创建mycompanyname/app1
、mycompanyname/app2
等
aws ecr create-repository --repository-name mycompanyname/helloworld
aws ecr create-repository --repository-name mycompanyname/app1
aws ecr create-repository --repository-name mycompanyname/app2
docker tag helloworld:latest xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/helloworld:latest
docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/helloworld:latest
docker tag app1:latest xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/app1:latest
docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/app1:latest
【讨论】:
那行得通,顺便说一句,ACR 不需要先手动创建代表。 另外,如果不同的“sub rep”,似乎需要推送图像【参考方案3】:我尝试了以下步骤并确认为我工作:
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com
aws ecr create-repository --repository-name 测试
docker build -t 测试。
docker 标签测试:最新 xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/test:latest
docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/test:latest
【讨论】:
【参考方案4】:除了上面的答案,我今天在这里遇到,因为登录命令更改为aws-cli v2
,作为答案发布可能对其他人有所帮助。
因为aws-cli v1
login 命令不再起作用。
V1
$(aws ecr get-login --no-include-email)
要使用 aws-cli v2 将图像推送到 ECR,您需要
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-west-2.amazonaws.com
那么你就可以构建和推送了
docker build -t myrepo .
docker tag myrepo:latest 123456789.dkr.ecr.us-west-2.amazonaws.com/myrepo
docker push 123456789.dkr.ecr.us-west-2.amazonaws.com/myrepot
通常每个注册表一个映像是一种干净的方法,这就是为什么 AWS increase image per repository and repository per region 从 1000 到 10,000。
【讨论】:
【参考方案5】:为此,我自动化了脚本,该脚本可以从 csv 文件中读取您的公共图像并拉取它们。之后它将尝试在 ECR 中创建存储库并推送到注册表。
-
准备CSV文件
ecr-images.csv
docker.io/amazon/aws-for-fluent-bit,2.13.0
docker.io/couchdb,3.1
docker.io/bitnami/elasticsearch,7.13.1-debian-10-r0
k8s.gcr.io/kube-state-metrics/kube-state-metrics,v2.0.0
k8s.gcr.io/metrics-server-amd64,v0.3.6
--------------------KEEP THIS LINE AT END-------------------------
-
自动脚本
ecr.sh
将图像复制到 ecr
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$BASH_SOURCE[0]")" && pwd)"
assert_value()
if [ -z "$1" ]; then
echo "No args: $2"
exit 1
fi
repository_uri=$1
assert_value "$repository_uri" "repository_uri"
create_repo()
## try to create & failure will ignored by <|| true>
aws ecr create-repository --repository-name "$1" --output text || true
## Copy Docker Images to ECR
COUNTER=0
while IFS=, read -r dockerImage tag; do
outputImage=$(echo "$dockerImage" | sed -E 's/(\w+?\.)+\w+?\///')
outputImageUri="$repository_uri/$outputImage"
# shellcheck disable=SC2219
let COUNTER=COUNTER+1
echo "--------------------------------------------------------------------------"
echo "$COUNTER => $dockerImage:$tag pushing to $outputImageUri:$tag"
echo "--------------------------------------------------------------------------"
docker pull "$dockerImage:$tag"
docker tag "$dockerImage:$tag" "$outputImageUri:$tag"
create_repo "$outputImage"
docker push "$outputImageUri:$tag"
done <"$SCRIPT_DIR/ecr-images.csv"
-
运行
repository_uri=<ecr_account_id>.dkr.ecr.<ecr_region>.amazonaws.com
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin $repository_uri
./ecr.sh $repository_uri
【讨论】:
【参考方案6】:为每个应用创建一个 repo:
aws ecr create-repository --repository-name worker --region us-east-1
aws ecr create-repository --repository-name gateway --region us-east-1
登录注册表
AWS usr 名称对于所有注册表登录都是固定的
aws ecr get-login-password \
--region us-east-1 \
| docker login \
--username AWS \
--password-stdin <aws_12_digit_account_number>.dkr.ecr.us-east-1.amazonaws.com
推送图片
docker build -f Dockerfile -t <123456789012>.dkr.ecr.us-east-1.amazonaws.com/worker:v1.0.0
docker push <123456789012>.dkr.ecr.us-east-1.amazonaws.com/worker:v1.0.0
【讨论】:
是的,但是使用标签来区分你的图像是很糟糕的做事方式。 糟糕的解决方案,标签是我们版本图像的方式 正如上面的 cmets 所暗示的,这是一种反模式。如果在较大的开发团队中使用,很容易证明容易出错。您最好编写解决方案的脚本。比如:gist.github.com/jmervine/b1835fa3bfcea9eaa9bf2521291f0615 @jmervine “更好”,而不是“更好”。 这在某些情况下似乎完全合理。例如,许多流行的 docker 存储库使用这种方法来区分图像的“风味”,例如nginx:alpine
与 nginx:perl
以上是关于将 docker 镜像推送到亚马逊 ecs 存储库的主要内容,如果未能解决你的问题,请参考以下文章
sh 构建Docker镜像,将其推送到AWS EC2 Container Registry,然后将其部署到AWS Elastic Beanstalk
尝试使用 AWS CLI 运行 ECS 任务时出现资源:内存错误