AWS ECR私有镜像仓库的Docker Image上传和下载

注意:按下述文档流程,1)先创建仓库,再上传。否则直接上传就报错。2)不支持子目录,仓库叫什么,push时候就写什么名字,不支持写/子目录的格式

针对EKS 1.30、以及Graviton处理器的ARM架构容器构建的场景,系统采用 Amazon Linux 2(兼容CentOS7)或者 Amazon Linux 2023(兼容CentOS9),于2024年7月在AWS海外区域(新加坡)测试通过

本文的构建Docker的环境是一台位于云端的Amazon Linux EC2虚拟机,因为已经位于云端,上传下载软件包的速度更快。开发者也可以使用Ubuntu Linux,或者MacOS完成本文的工作。本文将创建一个hello world的php docker程序,并且发布到AWS ECR镜像仓库。

一、开发机的环境准备和常见Docker操作命令介绍

1、配置Docker准备环境

创建一台EC2节点,使用Amazon Linux 2(兼容CentOS7)或者Amazon Linux 2023(兼容CentOS9)操作系统,选择较小规格如 t3.medium 机型(2vCPU/4GB)即可,建议内存不低于4GB。根据要构建的Docker的复杂度,酌情提升配置。此外,为了构建ARM架构的容器集群,可选择采用Graviton2处理器的 t4g.medium 机型(2vCPU/4GB)进行容器构建。

2、安装docker,以root身份执行如下命令:

在Amazon Linux 2(兼容CentOS7)上执行如下命令:

yum update -y
amazon-linux-extras install docker
service docker start
usermod -a -G docker ec2-user

在Amazon Linux 2023(兼容CentOS9)上执行如下命令:

yum update -y
yum install docker -y
service docker start
usermod -a -G docker ec2-user

3、构建应用程序

首先安装git程序,并下载对应的演示代码。

yum install -y git
git clone https://github.com/awslabs/ecs-demo-php-simple-app

下载后进入目录,可以看到里边包含一系列源文件。找到其中的 Dockerfile文件(无扩展名),使用文本编辑器修改之,加入下边内容:

FROM amazonlinux:2

# Install dependencies
RUN yum install -y \
    curl \
    httpd \
    php \
 && ln -s /usr/sbin/httpd /usr/sbin/apache2

# Install app
RUN rm -rf /var/www/html/* && mkdir -p /var/www/html
ADD src /var/www/html

# Configure apache
RUN chown -R apache:apache /var/www
ENV APACHE_RUN_USER apache
ENV APACHE_RUN_GROUP apache
ENV APACHE_LOG_DIR /var/log/apache2

EXPOSE 80

CMD ["/usr/sbin/apache2", "-D",  "FOREGROUND"]

在中国区做测试时候,需要注意AWS中国区域没有ICP备案的环境无法暴露80、443、8080等端口,另外5800、5900等端口也是被屏蔽。因此在测试中建议docker内发布80端口,通过ALB负载均衡器映射将80端口映射为50001等特殊端口。测试即可通过。

4、在开发机构建Docker Image并保存在本机

上传到AWS的ECR之前,需要在本地先创建并编译docker生成image。执行如下命令。

docker build -t phpdocker .

操作完成后,执行docker images可以看到刚才创建的image。

构建完成后,可执行如下命令查询本地的Docker Image。

docker image ls

5、在本机启动Docker并登录到容器内测试

作为开发过程的一部分,构建容器镜像后需要验证功能是否正常。可执行如下命令在开发机本地启动:

docker run -d <docker名称:标签>

执行如下命令查看当前已经在运行的Docker:

docker ps

执行如下命令命令登录到Docker中。注意<Running ID>来自于上一步查询结果。

docker exec -it <Running ID> /bin/bash

6、其他Docker常用命令

如果希望在本地查看刚才下载的镜像信息,可执行如下命令:

docker inspect 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:latest

执行如下命令停止不需要的Docker。注意<Running ID>来自于上一步docker ps命令查询结果。

docker stop <Running ID>

可执行如下命令删除不需要的Docker。注意Image ID来自于前文使用 docker image ls命令的查询结果。

docker image rmi <Image ID>

以上测试全部通过,即可开始上传容器镜像到ECR上。

二、创建ECR私有镜像仓库

1、如何选择公有和私有仓库

公有仓库(public类型)是指public.ecr.aws域名开头的、对所有互联网匿名可访问的镜像仓库。一般用于开源发布。

私有仓库(private类型)指仅本AWS账号专有的、必须经过本AWS账号授权的IAM User、Access Key/Secret Key密钥认证后才能访问的仓库。在AWS上使用EKS服务或者ECS容器服务,要上传(push)和调用(pull)的仓库都是指私有仓库。

私有仓库创建时候什么选项都不需要额外提供,默认就是私有的,也就是需要通过身份认证才能访问的。

本文后续所有镜像仓库都指私有仓库。

2、创建私有镜像仓库

请注意,无论是创建公有Public的仓库或者私有Private的仓库,都需要遵照如下流程,先创建容器仓库,然后才能push镜像。这一步可以通过CLI操作,也可以通过AWS Console图形界面操作。

点击右上角的Create repository按钮,即可完成创建。创建后是一个空的镜像仓库,就获得了如下URI地址,下一步推送镜像将会使用。如下截图。

操作完成后,复制下来仓库地址,即上图中红色部分。

三、从开发机登录到ECR服务

对ECR镜像仓库发起上传和下载操作之前,需要实现使用AWSCLI登录进行身份认证

1、通过AWS CLI完成对ECR镜像仓库的身份验证

这里需要在本机上安装AWS CLI并配置好access key,同时具有操作ECR的权限。

(1)AWS中国区操作命令

在刚才编辑Dockerfile的机器上,执行如下命令。注意请包含 $( ) 符号,这将表示括号内的命令输出结果会执行在当前shell上执行。

$(aws ecr get-login --no-include-email --region cn-northwest-1)

操作成功后应显示登陆成功,如下图。

(2)AWS海外区域操作命令

如果用的是海外区,则login命令有所不同,操作如下:

aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin 133129065110.dkr.ecr.ap-southeast-1.amazonaws.com

即可完成登录。

2、对开发机上要上传到ECR的镜像打tag

执行如下命令查找本机上现有已经构建好的Docker Image。

docker image ls

执行如下命令。其中的的URI需要替换为前文的ECR镜像仓库的地址。

docker tag phpdocker:latest 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:latest

3、将image push到ECR上

注意:不支持/格式的子目录,必须使用镜像仓库名称加tag的格式。

执行如下命令。 其中的的URI需要替换为前文的ECR镜像仓库的地址。

docker push 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:latest

上传成功可以看到提示。

在Console界面上,查看ECR就已经可以看到image了。

4、从ECR上下载镜像到本地(可选)

如果希望在别的开发环境上,从ECR上下载镜像,那么需要先配置好AWSCLI并完成前文的身份认证,然后执行如下命令,即可从ECR容器镜像仓库下载到开发机本地。

docker pull 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:latest

四、根据镜像安全扫描结果升级镜像内的软件版本以提升容器安全

1、检查镜像的安全隐患

在上传镜像完成后,可以在容器镜像仓库里边看到,镜像存在安全缺陷。如下图。

点击详情进入后,发现安全漏洞是因为组件不是最新版本造成的。如下截图。

为此需要更新镜像到最新版本。

2、修改镜像Dockerfile进行升级

登录到刚才build docker的EC2上,编辑上文用到的Dockerfile文件,找到“Install dependencies”一段,在开头加入如下一行:

RUN yum update -y

保存退出。

执行如下命令重新build镜像。

docker build -t phpdocker:2 .

这里的命令比第一次build时候增加了 :2 ,表示第二个版本tag。build成功后如下图。

执行docker images命令,可以看到当前EC2环境上,镜像已经新版本已经编译完成。

3、上传新版本到AWS ECR 容器镜像仓库

与前文介绍过的顺序一样,分别执行登录、打tag的操作,最后是push。执行如下命令:

$(aws ecr get-login --no-include-email --region cn-northwest-1)
docker tag phpdocker:2 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:2
docker push 420029960748.dkr.ecr.cn-northwest-1.amazonaws.com.cn/phpdocker:2

注意以上命令的版本tag需要替换为 :2 。执行后效果如下。

此时从控制台上,访问ECR,查看镜像仓库,可以看到新上传的版本已经被识别出来,且通过了安全扫描,没有漏洞。

五、参考资料

https://docs.aws.amazon.com/zh_cn/AmazonECR/latest/userguide/registry_auth.html

全文完。