基于阿里云ECS与ACR的容器镜像管理(基于Windows 11)
基本要求
- 理解并掌握云服务器ECS、容器、镜像、镜像仓库等核心概念
- 理解并掌握Docker基本原理与常用指令
- 理解并掌握Dockerfile的撰写与容器镜像的构建
- 了解并掌握创建与管理阿里云ECS服务器的基本操作
- 了解并掌握基于阿里云容器镜像服务ACR创建与应用镜像仓库的基本操作
实验过程
环境搭建
准备云服务器ECS
访问云服务器ECS产品首页,选择相关配置后购买。其中操作系统选择Ubuntu,安全组配置默认应仅允许开启SSH(22),HTTP(80)与HTTPS(443)端口。
在ECS安装Docker引擎
访问Docker官网(docs.docker.com),根据提示在阿里云服务器ECS上安装Docker。
应该指出的是,国内现在已经无法正常访问Docker官网了。因此我们可以使用阿里云源安装Docker:
- 检查是否已安装Docker
docker --version
- 更新系统包索引
sudo apt-get update
- 安装依赖
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
- 添加 Docker GPG 密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 设置 Docker 仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 更新包索引并安装 Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
- 启动并验证 Docker
启动Docker服务并确保已经启动:
sudo systemctl start docker
sudo systemctl enable docker
验证Docker是否正确安装:
docker --version
基于阿里云容器镜像服务ACR配置镜像仓库
访问阿里云容器镜像服务ACR产品首页(容器镜像服务_镜像构建_镜像授权_镜像托管-阿里云),点击“管理控制台”进入实例列表,创建一个个人实例:
- 设置访问密码
- 创建命名空间
- 创建镜像仓库
使用名称npu
,默认设置仓库为私有,代码源选择本地仓库。
练习ECS基础操作
云服务器新手上路
完成阿里云云起实验室项目“ECS云服务器新手上路”(ECS云服务器新手上路 - 云起实验室),开展控制台管理实践。
创建配置普通用户
- 在本地系统基于SSH访问ECS公网地址,使用root账号登录
首先需要开启Windows系统自带的SSH服务。
随后本地打开cmd,基于SSH远程访问ECS(root账号登录):
ssh <username>@<ECS公网ip> -p 22
执行useradd
命令,添加普通用户,使用passwd
命令设置/重置用户密码:
sudo useradd -m -s /usr/bin/bash whim1 //-m 创建用户主目录;-s 设定Shell
passwd whim1 //设置登录密码
sudo usermod -aG sudo whim1 //编辑/etc/group,将指定用户加入sudo组,提供sudo权限
sudo usermod -G docker whim1 编辑/etc/group,将指定用户加入docker组,提供docker权限
[!CAUTION]
sudo usermod -aG sudo whim1
是正确的,而不是-G
使用新建用户进行SSH登录验证,且确认sudo su
命令可以正常切换到root用户:
禁止root远程登录
编辑文件/etc/ssh/sshd_config
,添加配置PermitRootLogin no
vim /etc/ssh/sshd_config
重启SSH服务
sudo service sshd restart
//或者执行sudo systemctl restart sshd
完成上述配置后,使用root用户进行SSH登录验证,确认配置生效:
练习Docker常用命令
以高性能HTTP&反向代理Web服务器Nginx1.24.0为例,练习Docker常用命令。
拉取容器镜像
- 使用命令
docker search
在Docker Hub查询镜像:
docker search nginx
由于国内无法拉取Docker镜像了,因而需要配置镜像源加速:
vim /etc/docker/daemon.json
添加以下内容
{
"registry-mirrors": ["https://docker.1panel.live"]
}
保存后重启docker:
systemctl restart docker
[!CAUTION]
也可以使用AtomHub 可信镜像仓库平台 · OpenAtom Foundation,搜索需要的镜像名称,进行pull拉取,如:
docker pull atomhub.openatom.cn/amd64/redis:7.0.13
- 使用
docker pull
从Docker Hub拉取容器镜像Nginx的最新版本:
- 拉取完成后,使用
docker images
命令查看本地镜像:
基于镜像创建并运行容器
- 简单创建运行
使用命令docker run
进行简单创建与运行:
docker run -d --name nginx -p 80:80 nginx
# -d, --detach:在后台运行该docker容器,并在启动后打印容器ID
# --name:指定启动后的容器名称,本例设置容器实例名称为“nginx”
# -p,--publish list:端口发布(映射),<宿主端口>:<容器端口>
# 最后的“nginx”为镜像名,此处省略了冒号与紧跟其后的tag,默认tag为latest
使用命令docker ps
可查看正在运行的容器信息:
docker ps
此时使用浏览器访问ECS服务器公网IP,可见如下页面:
- 挂载宿主目录
实际应用时,对于容器中部署的服务,通常需把其所依赖的配置文件、数据文件进行持久化存储。否则一旦容器被销毁,这些文件也将随之销毁。
要满足此类需求,需要在容器创建运行时,将宿主系统中用于存储配置文件、代码文件、数据文件的目录甚至具体文件映射到容器中的对应目录或文件,即,让容器在创建启动时,从宿主系统中指定的目录文件加载配置文件,在生成数据时则写入宿主系统中指定的目录文件。
下面将为nginx服务的配置文件、日志文件以及Web服务的根目录分别建立持久化映射。nginx容器中的三个固有目录与宿主系统的目录映射关系定义为:
持久化内容 | 容器目录 | 宿主目录 |
---|---|---|
总体配置 | /etc/nginx/nginx.conf | /opt/docker/nginx/nginx.conf |
服务配置 | /etc/nginx/conf.d | /opt/data/nginx/conf.d |
日志文件 | /var/log/nginx | /opt/log/nginx |
Web服务 | /usr/share/nginx/html | /opt/share/nginx/html |
首先在ECS上创建三个宿主目录:
mkdir -p /opt/docker/nginx/conf.d
mkdir -p /opt/docker/nginx/logs
mkdir -p /opt/docker/nginx/html
# -p, --parents:如果路径中任一级父目录不存在,则创建
然后从先前启动的nginx容器中将配置文件复制到宿主(否则目录挂载后,若容器找不到配置文件,服务不能正常运行)
docker cp nginx:/etc/nginx/nginx.conf /opt/docker/nginx/
docker cp nginx:/etc/nginx/conf.d /opt/docker/nginx/
docker cp nginx:/usr/share/nginx/html /opt/docker/nginx/
为重新运行挂载在宿主目录的nginx容器,必须停止并删除当前nginx容器。
首先停止运行当前nginx容器。
docker stop nginx
#除容器名称,也可使用容器id标识容器
此时docker ps
已查询不到已停止运行的nginx容器,但是应用参数-a
,即可查看全部正在运行与停止运行的容器。停止的容器状态被标注为Exited
,同时端口没有发布(映射)记录。
docker ps -a
随后删除停止运行的nginx
容器。删除后通过docker ps -a
查看,确认已删除。
docker rm nginx
nginx
docker ps -a
#观察
重新设置执行docker run
,完成相关文件与目录的挂载。
# -v, --volume list:挂载(绑定)目录,<宿主目录>:<容器目录>
docker run -d --restart=always \
--name nginx \
-p 80:80 \
-v /opt/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /opt/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /opt/docker/nginx/html:/usr/share/nginx/html \
-v /opt/docker/nginx/logs:/var/log/nginx \
nginx
停止,启动,进出容器
关闭刚创建的挂载了宿主目录的nginx容器,随后使用docker start
命令启动该容器。
docker stop nginx
nginx
docker start nginx
nginx
启动后,换命令行方式快速在ECS进行Nginx服务验证。
curl 127.0.0.1:80
#使用curl访问ECS本地服务端口,输出Nginx默认HTML页面
重启容器nginx后,使用docker exec
命令进入容器。该命令本身定义为在容器内部运行一条指定命令,通过指定命令为Shell程序,如/bin/bash
,配合应用参数-it
,可实现进入容器进行命令行交互式操作。
docker exec -it nginx /bin/bash
# -i --interactive,保持交互模式
# -t --tty,分配一个伪终端(模拟终端)
# nginx,容器名称
# /bin/bash,待执行的命令。进入bash shell
进入容器后,可执行容器本身所支持的命令操作。此时尝试进入/usr/share/nginx/html
目录,创建一个test.html
文件。
因为该容器不支持编辑命令vim
,所以使用echo
命令创建Web文件test.html
,浏览器访问该文件时,将展示h1大小的Hello,world
。
完成容器内的文件创建后,使用exit
命令退出容器,查看宿主目录ls /opt/docker/nginx/html
,可见在容器内创建的test.html
文件,已成功持久化存储到宿主系统。此时使用curl
访问ECS本地URL127.0.0.1:80/test.html
,可成功输出test.html
文件内容。
下面以(nginx)$
作为容器内命令行提示符:
(nginx)$ cd /usr/share/nginx/html
(nginx)$ echo "<h1>Hello,world</h1>" > test.html
(nginx)$ exit
ls /opt/docker/nginx/html
50x.html index.html test.html
curl 127.0.0.1:80/test.html
完成以上步骤后,用浏览器访问http://<ECS公网地址>/test.html
,观察h1
大小的Hello,world
。
查看容器日志
使用docker logs
命令查看容器的日志输出。
docker logs nginx
删除容器镜像
docker rmi nginx
# rmi: remove images;也可使用docker image rm nginx
因为尚有基于该镜像创建的容器存在,所以无法删除该镜像,需首先停止、删除容器实例后再行删除容器镜像。
docker stop nginx
nginx
docker rm nginx
nginx
docker rmi nginx
docker images
# 自行观察
构建Docker容器镜像
以Ubuntu镜像作为基础镜像,拟制作一个包含Python基础环境以及Nginx服务器的新镜像。整个制作过程包含两大步骤,一是撰写Dockerfile文件,二是使用docker build
命令基于Dockerfile创建新镜像。
编写Dockerfile文件
Dockerfile是制作Docker容器镜像的基础。一般而言,Dockerfile文件指令逻辑应按照以下模式建立:选择合适的基础镜像、安装基础工具与依赖、添加其他应用、清理缓存、声明镜像端口暴露情况、设置默认启动命令。
- 编写命令
vim 文件名
- 选择基础镜像Ubuntu并添加文件维护者信息
# 使用Ubuntu作为基础镜像
FROM ubuntu:22.04
# 维护者信息
LABEL maintainer="<维护者邮箱>"
- 设置工作目录
WORKDIR /app
- 安装Nginx&Python
# 安装nginx&Python
RUN apt-get update && apt-get install -y \
nginx \
python3 \
python3-distutils
- 清理apt软件包缓存
RUN rm -rf /var/lib/apt/lists/*
- 声明暴露端口
EXPOSE 80
- 设置启动命令
CMD ["nginx","-g","daemon off;"]
- Dockerfile完整逻辑:
FROM ubuntu:22.04
LABEL maintainer="<维护者邮箱>"
WORKDIR /app
RUN apt-get update && apt-get install -y \
nginx \
python3 \
python3-distutils
RUN rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
输入完之后,敲下esc,然后:wq
保存并退出。
基于Dockerfile创建容器镜像
基于Dockerfile,使用docker build
命令创建容器镜像。创建完成后,通过docker images
观察新建镜像的大小。
docker build -f dockerfile-npu -t npu .
docker images
运行该镜像,访问80
端口,检测Nginx服务。随后进入容器,检测Python解析能力。
docker run -d --name npu -p 80:80 npu
curl 127.0.0.1
# 等价于127.0.0.1:80,或者http://127.0.0.1:80
docker exec -it npu /bin/bash
(nginx)$ python3
(nginx)$ exit()
(nginx)$ exit
ACR镜像管理与应用
实际应用时,开发者通常需要配置持续集成与持续部署流水线,在“构建镜像”阶段,将代码打包到基础镜像后,推送至特定镜像仓库,而在“服务部署”阶段则从镜像仓库拉取该镜像并部署于特定ECS服务器或集群。
下面练习基于阿里云容器镜像服务与命令行Docker指令的镜像推送与拉取。
推送容器镜像至ACR
重新标记刚创建的镜像npu
,以满足推送该镜像至ACR的要求。镜像名包括“镜像仓库”与“标记”两部分。此时要推送的仓库是阿里云容器镜像服务ACR中所创仓库。
访问之前在阿里云ACR控制台创建的镜像仓库npu
,查询镜像仓库URL,并使用仓库地址重新标记镜像npu
。
docker tag npu crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/whim111/npu

登录阿里云ACR,使用命令docker push
推送镜像至ACR镜像仓库npu
。
docker login --username=沙里院的雪 crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com
docker push crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/whim111/npu
镜像上传成功。此时查看阿里云ACR控制台,在镜像仓库npu
的“镜像版本”页面,可见刚提交的镜像记录。
拉取容器镜像至ECS
为测试从阿里云ACR拉取到ECS的容器镜像是否能正常工作,首先需要删除ECS本地相关的容器以及镜像,以免干扰测试。
docker stop npu
docker rm npu
docker rmi npu
docker rmi crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/whim111/npu
docker images
此时在ECS上执行拉取镜像操作,随后创建运行容器并测试服务效果。
docker pull crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/whim111/npu
docker run -d --name npu -p 80:80 crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/whim111/npu
curl 127.0.0.1
# 自行观察,确认从阿里云ACR拉取的镜像无误,可创建容器通过服务测试。