把第一个容器跑起来
本实验在真正的 VM 中运行
这个环境不是 Pod,而是由 KubeVirt 启动的虚拟机。Linux 内核独立运行,systemd 真正管理服务,docker 也不是模拟工具,而是真正的 Docker 引擎。通过 docker run 启动的容器会成为实际进程,docker exec 和 docker logs 也都能照常工作。
过去,这个实验在 Pod 中运行。由于该环境放弃了所有内核权限,启动容器的步骤无法进行,因此只能学习直接解开镜像归档的变通方法。现在不再需要绕路了。
有两点需要了解。
- **首次启动大约需要 1 分钟。**因为 VM 需要启动并安装 Docker,比 Pod 实验(通常 40 秒)更慢。
- **没有浏览器预览。**进入 VM 的连接只开放评分端口。如果启动了 Web 服务器,请在 VM 内使用
curl检查。
目标
亲手操作镜像和容器,实际确认标签不会复制镜像,以及容器内外看到的是不同的文件树。
为什么重要
刚开始接触容器时,大多数人会试图背诵命令。但实际工作中造成阻碍的不是命令,而是模型。“镜像已经删除,容器却还活着”“改了标签,容量却没有减少”“容器里有文件,主机上却没有”——这些现象都可以用一句话解释:镜像是一叠只读层,而容器是其上的可写层 + 进程。所以本实验不是为了记住命令,而是亲眼验证这句话。
步骤
- 创建
/root/dk1目录,将这个环境中可用的镜像列表保存到/root/dk1/images.txt。必须同时显示仓库和标签。docker images在这个环境中无法运行。请改为读取/opt/images/*.tar内index.json的.manifests[0].annotations["org.opencontainers.image.ref.name"],即可原样得到docker.io/library/alpine:3.20这样的名称:标签——这相当于深入一层,观察docker images的 Repository、Tag 两列来自哪里。 - 使用
alpine:3.20镜像创建名为dk-hello的容器,让它输出hello-labhub,并在退出后保留该容器。 - 将
nginx:1.27-alpine以dk-web为名在后台运行。 - 读取
nginx:1.27-alpine容器所看到的/etc/os-release,保存到/root/dk1/web-os.txt。 使用docker exec dk-web cat /etc/os-release读取。如果直接读取这台 VM 的/etc/os-release,会得到 Ubuntu 并导致失败——这种差异正是挂载命名空间的作用。 - 查出
dk-web的容器 IP 地址,并在/root/dk1/web-ip.txt中只保存一行 IPv4 地址。 - 为
alpine:3.20额外添加名称labhub/base:v1。 - 删除
dk-hello容器,保留dk-web。 - 在
/root/dk1/report.txt中用实际值填写以下三行。
image=<dk-web 이 쓰는 이미지 이름:태그>
container=dk-web
state=<dk-web 의 현재 상태>
参考
- 使用
docker images --format '{{.Repository}}:{{.Tag}}'可以只提取所需的列。 - 像
docker inspect <이름> | jq -r '.[0].State.Status'这样直接深入查看 JSON 更可靠。 - 常见错误 1:如果在第 2 步添加
--rm,容器会立即消失,没有可供评分的对象。 - 常见错误 2:如果在第 4 步读取主机的
/etc/os-release,会得到 Ubuntu。必须在容器内部读取。
保存镜像列表
创建 /root/dk1 目录,将这个环境中可用的镜像列表保存到 /root/dk1/images.txt。必须同时显示仓库和标签。
docker images 在这个环境中无法运行。请改为读取 /opt/images/*.tar 内 index.json 的 .manifests[0].annotations["org.opencontainers.image.ref.name"],即可原样得到 docker.io/library/alpine:3.20 这样的名称:标签——这相当于深入一层,观察 docker images 的 Repository、Tag 两列来自哪里。
有一个用于显示镜像列表的子命令。不要只在屏幕上查看输出,请通过重定向将其保存到文件中。除了仓库名称,也必须保留标签列。
运行一次后结束的容器
使用 alpine:3.20 镜像创建名为 dk-hello 的容器,让它输出 hello-labhub,并在退出后保留该容器。
指定名称后,稍后会更容易找到它。请注意,如果添加 --rm,容器结束后会立即被删除,评分对象也会消失。
在后台持续运行的容器
将 nginx:1.27-alpine 以 dk-web 为名在后台运行。
如果在前台启动,终端会被占用。有一个标志可以让容器分离运行。nginx 不退出并持续运行是正常现象。
在运行中的容器内执行命令
读取 nginx:1.27-alpine 容器所看到的 /etc/os-release,保存到 /root/dk1/web-os.txt。
使用 docker exec dk-web cat /etc/os-release 读取。如果直接读取这台 VM 的 /etc/os-release,会得到 Ubuntu 并导致失败——这种差异正是挂载命名空间的作用。
在主机上读取 /etc/os-release 会得到 Ubuntu。必须在容器的挂载命名空间内读取,才能得到 Alpine。
查出容器的 IP
查出 dk-web 的容器 IP 地址,并在 /root/dk1/web-ip.txt 中只保存一行 IPv4 地址。
inspect 的输出是 JSON。请使用 jq 深入查看,或使用 --format 模板。文件中只能留下 IP 地址。
给镜像添加另一个名称
为 alpine:3.20 额外添加名称 labhub/base:v1。
标签不会复制镜像。添加新名称后,请比较两个名称的镜像 ID。
只清理已结束的容器
删除 dk-hello 容器,保留 dk-web。
已结束的容器仍会占用可写层。应保留正在运行的容器,只删除已结束的容器。
将当前状态写成报告
在 /root/dk1/report.txt 中用实际值填写以下三行。
三行都要与实际的 inspect 值核对。不要猜测,请填写通过命令确认的值。