1. Docker 基础回顾:架构、镜像、容器与编排
在进入集成测试与接口校验实战之前,必须夯实 Docker 核心基础。本章从架构、镜像、容器、Dockerfile 编写规范到 Docker Compose 入门,为后续的测试环境编排与接口验证建立统一认知。
1.1 Docker 架构:C/S 模式与核心组件
Docker 采用典型的客户端-服务器(C/S)架构,由 Docker 客户端、Docker 守护进程和 容器运行时 三部分组成。客户端通过 REST API 与守护进程通信,守护进程负责管理镜像、容器、网络与数据卷。
关键理解:Docker 守护进程(dockerd)是核心引擎,负责监听 API 请求、管理容器生命周期、维护镜像层缓存。集成测试中,我们通常通过客户端向守护进程发送指令,启动被测服务与依赖组件。
1.2 镜像与容器:概念与生命周期
| 维度 | 镜像(Image) | 容器(Container) |
|---|---|---|
| 定义 | 只读模板,包含操作系统、应用代码、依赖与配置 | 镜像的运行实例,拥有独立的文件系统、网络与进程空间 |
| 生命周期 | 构建 → 存储 → 分发 → 删除 | 创建 → 启动 → 运行 → 停止 → 删除 |
| 可变性 | 不可变(Immutable),每次构建生成新镜像 | 可变,运行时可写入临时层(容器层) |
| 存储 | 镜像仓库(Registry) | 宿主机文件系统(/var/lib/docker/containers) |
| 集成测试角色 | 定义测试环境基线 | 执行测试用例的运行时沙箱 |
镜像分层机制:Docker 镜像由多层只读层叠加而成,每一层对应 Dockerfile 中的一条指令。容器启动时,在镜像层之上添加一个可写容器层。这种设计实现了存储复用与快速分发。
1.3 Dockerfile 编写规范
Dockerfile 是构建镜像的自动化脚本,遵循以下核心规范:
- 基础镜像选择:优先使用官方镜像(如
python:3.11-slim、openjdk:17-jdk-slim),减少攻击面与镜像体积。 - 指令顺序:将变化频率低的指令放在前面(如
RUN apt-get update),利用构建缓存加速。 - 多阶段构建:分离编译环境与运行环境,最终镜像只保留运行时产物。
- 非 root 运行:创建专用用户,降低安全风险。
# 多阶段构建示例:Python 应用
# 阶段 1:编译依赖
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# 阶段 2:运行镜像
FROM python:3.11-slim
RUN useradd -m -u 1000 appuser
WORKDIR /app
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser src/ .
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
常见陷阱:避免在 Dockerfile 中使用
ADD 指令下载远程文件(除非需要自动解压);优先使用 COPY 保证构建可复现。不要在运行镜像中保留编译工具链,这会显著增加镜像体积与安全风险。
1.4 Docker Compose 入门
Docker Compose 通过 YAML 文件定义多容器应用,实现一键启动、停止与编排。在集成测试场景中,Compose 用于同时启动被测服务、数据库、消息队列、Mock 服务等依赖。
Compose 文件核心结构:
version: "3.8"
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- db
- redis
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/testdb
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: testdb
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
mock:
image: wiremock/wiremock:latest
ports:
- "9090:8080"
test:
build: ./tests
depends_on:
- app
- mock
environment:
- BASE_URL=http://app:8080
- MOCK_URL=http://mock:9090
volumes:
pgdata:
集成测试最佳实践:使用
depends_on 控制启动顺序;通过 healthcheck 确保依赖就绪后再执行测试;利用 --exit-code-from 参数让测试容器退出码传递到 CI 管道。
1.5 常用 Docker 命令速查
| 类别 | 命令 | 说明 |
|---|---|---|
| 镜像管理 | docker images |
列出本地镜像 |
docker pull <image> |
从仓库拉取镜像 | |
docker build -t <tag> . |
构建镜像 | |
| 容器管理 | docker ps -a |
查看所有容器(含已停止) |
docker run -d --name <name> <image> |
后台运行容器 | |
docker exec -it <container> sh |
进入容器交互式 shell | |
docker logs <container> |
查看容器日志 | |
| Compose | docker compose up -d |
启动所有服务(后台) |
docker compose down -v |
停止并删除容器、网络、卷 | |
docker compose ps |
查看服务状态 |
提示:在集成测试脚本中,建议使用
docker compose up --abort-on-container-exit --exit-code-from test 确保测试容器退出时自动关闭所有服务,并将测试结果返回给 CI。