推送 Docker 镜像到 Amazon ECR 仓库

Docker 镜像在未指定仓库时默认是从  Docker Hub 拉取的。如果需向 Docker Hub 推送镜像的话还可用 docker login 在交互中完成登陆 Docker Hub 的操作。docker login 的命令格式是

docker login [OPTIONS] [SERVER]

所以我们可以连接到任何的 Docker 镜像仓库,也可以是本机,但我们这里所要介绍的是如何推送镜像到 AWS 给我们提供的 Docker 镜像仓库(Amazon ECR - Amazon Elastic Container Registry)。每个帐号下都有自己独立的仓库,镜像推送到了  Amazon ECR 后我们能够很方便的在 ECS, Batch 服务中使用它,也可以从 ECR 拉取镜像到本地来。

首先我们来做一个运行 Spring Boot Web 的简单的 Docker 镜像,假定已用 mvc pacakge 生成了一个可独立运行的 jar 包 java-webapp-0.0.1-SNAPSHOT.jar 。该应用开启一个 Web 服务,访问 http://localhost:8080 显示一行字符串 Hello World!

创建一个目录 aws-docker, 并把 java-webapp-0.0.1-SNAPSHOT.jar 移入该目录,在其下创建 Dockerfile 文件,文件目录结构如下:

aws-docker
  ├── Dockerfile
  └── java-webapp-0.0.1-SNAPSHOT.jar

Dockerfile 的内容是

 然后是确保本地安装了 docker 和 aws-cli. 本人在本地已生成了 ~/.aws/credentials 文件用于 aws 命令的用户验证,为简单起见,profile 是 default

有了以上的前提之后,正式步入创建 Docker 镜像,登陆 Amazon ECR, 推送镜像到 ECR,从 ECR 拉取 Docker 的操作。

创建镜像和 Tag

基于前面的 Dockerfile 创建一个  Docker 镜像,如果要把该镜像推送到 ECR 必须有一符合规格的 Tag 名称。命令行中来到与 aws-docker 平行的目录,我们可以执行下面任意一组命令

docker build -t java-webapp:latest ./aws-docker
docker tag java-webapp:latest aws_account_id.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest

docker build -t aws_account_id.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest

aws_account_id 是当前登陆帐号的 ID, 可以在网页登陆 AWS 后的  Account Settings 中找到,也可以在 ~/.aws/credentials 文件(如果有的话)中找到,也可以在后面介绍的 aws ecr get-login 命令中看到。

总之,待推送的镜像必须符合 aws_account_id.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest 规则, 即 RepositoryURI:tag, 其中的 java-webapp 是仓库名,接下来用 docker push 才知道往哪儿推。

登陆 Amazon ECR

在推送镜像到 ECR 之前类似于登陆 Docker Hub 一样,也必须事先登陆到 Amazon ECR,命令 aws ecr get-login --no-include-email 为我们生成一个完整的 docker login 命令,大致如下:

docker login -u AWS -p eyJwYXlsb2FkIjoi.......== https://aws_account_id.dkr.ecr.us-east-1.amazonaws.com

执行上面的 docker login 命令将完成登陆 ECR 的过程,生成的令牌在 12 小时有效。

借助于 Shell 的管道,可以用一条简短的命令完成以上两步,即

aws ecr get-login --no-include-email | sh

注:对于 Docker 17.06 或更高的版本,需要 --no-include-email 参数

创建 Amazon ECR 仓库

莫急,在执行 docker push 之前还需要提前创建好 java-webapp 仓库,否则在推送的时候会出现找不到 repository 的错误

name unkown: The repository with name 'java-webapp' does not exist in the registry with id 'xxxxxxxxxxxx'

根据每个人的所好,在 Web 控制台或是命令行下创建仓库都可以,我这里就不妨命令行一路到底,用  aws 命令

aws ecr create-repository --repository-name java-webapp

注意:仓库名必须要保持一致

推送 Docker 镜像到 ECR

现在可是万事俱备,什么风也不歉了。只要像推送镜像到  Docker Hub 那样操作就行了

docker push aws_account_id.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest

➜ / docker push xxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest
The push refers to repository [xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/java-webapp]
ee923fd81c63: Layer already exists
bca5421261df: Layer already exists
473adefcdec2: Layer already exists
7f877179d500: Layer already exists
9c0da68f893b: Layer already exists
e01103f88b34: Layer already exists
2ec5c0a4cb57: Layer already exists
latest: digest: sha256:bb95bc9f6ca4f54b4ef23ae6b3b6b1793d04397c5066bc3ce3891d8d2dc86ec0 size: 1787

从 ECR 拉取镜像到本地运行

一个镜像就这么上传到了 Amazon ECR  了,我们能够在 ECS 或 Batch 服务中使用它了。既然能从本地 push 到 ECR, 也就无法阻挡从 ECR 拉取镜像到本地运行。假设已用 docker rmi <image_id> 删除了本地的 java-webapp 镜像。

反正前面用 aws ecr get-login | sh 之后,docker 就是知道根据镜像名找到匹配的仓库(Docker Hub 或 Amazon ECR) 去下载。

测试:

➜ / curl http://localhost:8080
Hello World!

终极图片

在 Amazon ECR 的控制台 https://console.aws.amazon.com/ecs/home?region=us-east-1#/repositories, 选择到刚刚 Push 上去的  java-webapp,点击 View Push Commands 按钮可以看到前面所有

  1. aws ecr get-login
  2. docker build
  3. docker tag
  4. docker push

命令,见图:

注意:前面的命令都假定了使用 ~/.aws/credentials 或 ~/.aws/config 中配置的默认区域 us-east-1, 如果要切换到其他的区域请在命令行参数中指定,此时仓库的 URI 也会有所变化。

类别: AWS. 标签: , . 阅读(316). 订阅评论. TrackBack.

Leave a Reply

avatar