声明一个栈,再去核对
本实验在真正的 VM 中运行
这个环境不是 Pod,而是由 KubeVirt 启动的虚拟机。Linux 内核独立运行,systemd 真正管理服务,docker 也不是模拟工具,而是真正的 Docker 引擎。通过 docker run 启动的容器会成为实际进程,docker exec 和 docker logs 也都能照常工作。
过去,这个实验在 Pod 中运行。由于该环境放弃了所有内核权限,启动容器的步骤无法进行,因此只能学习直接解开镜像归档的变通方法。现在不再需要绕路了。
有两点需要了解。
- **首次启动大约需要 1 分钟。**因为 VM 需要启动并安装 Docker,比 Pod 实验(通常 40 秒)更慢。
- **没有浏览器预览。**进入 VM 的连接只开放评分端口。如果启动了 Web 服务器,请在 VM 内使用
curl检查。
目标
使用 Compose 文件声明一个由两个服务组成的技术栈,再手动启动相同的技术栈,并对照声明值与实际值是否完全一致。
为什么重要
如果只把 Compose 理解成“一次启动多个容器的工具”,就只掌握了一半。它真正的价值在于,技术栈的形态写在文件里并保留在仓库中。而且,只有文件与现实一致时,这种价值才成立。一旦有人手动修改容器,文件就不再是文档,而成了谎言;直到下次部署前,都不会有人发现这个谎言。因此,本实验的最后一步不是创建新功能,而是进行对照。这里体现了使用声明式工具的团队必须养成的习惯。
步骤
按照以下结构编写 /root/ops3/compose.yaml。缩进为 2 个空格,顶层键(services:、volumes:、networks:)必须从行首开始。
- 在顶层放置
services:,在其下方用 2 个空格缩进声明web:和cache:两个服务。 - 将
web的image设为nginx:1.27-alpine,将cache的image设为alpine:3.20,并为cache同时填写使其持续运行的command。 - 在顶层放置
networks:,在其下方声明appnet:,然后在两个服务的networks:列表中都加入- appnet。 - 在
web中放置ports:并加入"127.0.0.1:8081:80"。不要在cache中放置ports。 - 在顶层放置
volumes:并声明webdata:,然后在web的volumes:中加入webdata:/usr/share/nginx/html。 - 在
cache的environment:中加入CACHE_TTL,值为60,并在web的depends_on:中加入- cache。 - 手动启动相同的技术栈。网络名称为
ops3net;容器分别为ops3-web(nginx:1.27-alpine,发布127.0.0.1:8081:80)和ops3-cache(alpine:3.20,环境变量CACHE_TTL=60),两者都连接到ops3net。 - 此步骤无需新建任何内容。确认第 6 步之前的声明与第 7 步的实际容器在镜像、端口、环境变量三个方面完全一致。
参考
- 顶层键按
services:→volumes:→networks:的顺序排列会更易读。 - 本实验第 8 步的评分会直接比较解析 compose 文件得到的值与
docker inspect的值。 - 常见错误 1:如果服务名称缩进 4 个空格,结构就会改变。必须正好是 2 个空格。
- 常见错误 2:如果在第 7 步使用
nginx:alpine这样不同的镜像标签,第 8 步对照时就会不一致。
声明两个服务
在顶层放置 services:,在其下方用 2 个空格缩进声明 web: 和 cache: 两个服务。
在顶层 services 下方,用 2 个空格缩进服务名称。缩进错位会改变整个文件的含义。
指定镜像和命令
将 web 的 image 设为 nginx:1.27-alpine,将 cache 的 image 设为 alpine:3.20,并为 cache 同时填写使其持续运行的 command。
alpine 的默认命令会立即结束,因此必须同时指定一个持续运行的 command。
声明共享网络
在顶层放置 networks:,在其下方声明 appnet:,然后在两个服务的 networks: 列表中都加入 - appnet。
在顶层声明 networks,并在每个服务中引用其名称。两处都不可缺少。
仅向环回地址开放端口
在 web 中放置 ports: 并加入 "127.0.0.1:8081:80"。不要在 cache 中放置 ports。
可以在端口字符串前加上绑定地址。只进行内部通信的服务不要使用 ports。
声明命名卷
在顶层放置 volumes: 并声明 webdata:,然后在 web 的 volumes: 中加入 webdata:/usr/share/nginx/html。
在顶层 volumes 中声明名称,并在服务中连同目标路径一起使用。
环境变量与启动顺序
在 cache 的 environment: 中加入 CACHE_TTL,值为 60,并在 web 的 depends_on: 中加入 - cache。
请记住,depends_on 只保证顺序,并不保证服务已经就绪。
手动启动相同的技术栈
手动启动相同的技术栈。网络名称为 ops3net;容器分别为 ops3-web(nginx:1.27-alpine,发布 127.0.0.1:8081:80)和 ops3-cache(alpine:3.20,环境变量 CACHE_TTL=60),两者都连接到 ops3net。
先创建网络,再连接容器。请使用与声明文件中完全相同的值。
对照声明与实际状态
此步骤无需新建任何内容。确认第 6 步之前的声明与第 7 步的实际容器在镜像、端口、环境变量三个方面完全一致。
评分会直接比较从 compose 文件读取的值与实际容器的 inspect 值。哪怕相差一个字符也属于不一致。