注意:按下述文档流程,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
全文完。