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 的内容是
1 2 3 4 5 6 |
FROM openjdk:8-jre-slim ADD java-webapp-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT [ "java", "-jar", "/app.jar" ] |
然后是确保本地安装了 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 镜像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
➜ / docker run -p 8080:8080 xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/java-webapp Unable to find image 'xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest' locally latest: Pulling from java-webapp e7bb522d92ff: Already exists acf3a7df1b51: Already exists c1c98005fcff: Already exists 39dcc90226db: Already exists 693e7ee43844: Already exists cb083d9c54cf: Already exists 46f48bdb2c6e: Already exists Digest: sha256:bb95bc9f6ca4f54b4ef23ae6b3b6b1793d04397c5066bc3ce3891d8d2dc86ec0 Status: Downloaded newer image for xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/java-webapp:latest . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.9.RELEASE) |
反正前面用 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
按钮可以看到前面所有
- aws ecr get-login
- docker build
- docker tag
- docker push
命令,见图:
注意:前面的命令都假定了使用 ~/.aws/credentials
或 ~/.aws/config
中配置的默认区域 us-east-1
, 如果要切换到其他的区域请在命令行参数中指定,此时仓库的 URI 也会有所变化。
[…] 推送 Docker 镜像到 Amazon ECR 仓库 中的方式,以下几步推送 python-web:latest 到 ECR 中,假设这里创建的 ECR 的 URI […]