LabHub
学习 学习路径 课程

Docker 基础

把第一个容器跑起来

在 LabHub 中继续学习

本实验在真正的 VM 中运行

这个环境不是 Pod,而是由 KubeVirt 启动的虚拟机。Linux 内核独立运行,systemd 真正管理服务,docker 也不是模拟工具,而是真正的 Docker 引擎。通过 docker run 启动的容器会成为实际进程,docker execdocker logs 也都能照常工作。

过去,这个实验在 Pod 中运行。由于该环境放弃了所有内核权限,启动容器的步骤无法进行,因此只能学习直接解开镜像归档的变通方法。现在不再需要绕路了。

有两点需要了解。

目标

亲手操作镜像和容器,实际确认标签不会复制镜像,以及容器内外看到的是不同的文件树。

为什么重要

刚开始接触容器时,大多数人会试图背诵命令。但实际工作中造成阻碍的不是命令,而是模型。“镜像已经删除,容器却还活着”“改了标签,容量却没有减少”“容器里有文件,主机上却没有”——这些现象都可以用一句话解释:镜像是一叠只读层,而容器是其上的可写层 + 进程。所以本实验不是为了记住命令,而是亲眼验证这句话。

步骤

  1. 创建 /root/dk1 目录,将这个环境中可用的镜像列表保存到 /root/dk1/images.txt。必须同时显示仓库和标签。 docker images 在这个环境中无法运行。请改为读取 /opt/images/*.tarindex.json.manifests[0].annotations["org.opencontainers.image.ref.name"],即可原样得到 docker.io/library/alpine:3.20 这样的名称:标签——这相当于深入一层,观察 docker images 的 Repository、Tag 两列来自哪里。
  2. 使用 alpine:3.20 镜像创建名为 dk-hello 的容器,让它输出 hello-labhub,并在退出后保留该容器。
  3. nginx:1.27-alpinedk-web 为名在后台运行。
  4. 读取 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 并导致失败——这种差异正是挂载命名空间的作用。
  5. 查出 dk-web 的容器 IP 地址,并在 /root/dk1/web-ip.txt 中只保存一行 IPv4 地址。
  6. alpine:3.20 额外添加名称 labhub/base:v1
  7. 删除 dk-hello 容器,保留 dk-web
  8. /root/dk1/report.txt 中用实际值填写以下三行。
image=<dk-web 이 쓰는 이미지 이름:태그>
container=dk-web
state=<dk-web 의 현재 상태>

参考

保存镜像列表

创建 /root/dk1 目录,将这个环境中可用的镜像列表保存到 /root/dk1/images.txt。必须同时显示仓库和标签。 docker images 在这个环境中无法运行。请改为读取 /opt/images/*.tarindex.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-alpinedk-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 值核对。不要猜测,请填写通过命令确认的值。