1. Docker 基础回顾:架构、镜像、容器与编排

在进入集成测试与接口校验实战之前,必须夯实 Docker 核心基础。本章从架构、镜像、容器、Dockerfile 编写规范到 Docker Compose 入门,为后续的测试环境编排与接口验证建立统一认知。

1.1 Docker 架构:C/S 模式与核心组件

Docker 采用典型的客户端-服务器(C/S)架构,由 Docker 客户端、Docker 守护进程和 容器运行时 三部分组成。客户端通过 REST API 与守护进程通信,守护进程负责管理镜像、容器、网络与数据卷。

Docker 架构:C/S 模式与核心组件 Docker 客户端 docker build / run / push REST API Docker 守护进程 dockerd 容器运行时 runc / containerd 镜像仓库 Docker Hub / 私有仓库 pull push 说明:客户端通过 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 服务等依赖。

Docker Compose 多服务编排(集成测试场景) docker-compose.yml 定义服务、网络、卷 被测服务 app:8080 PostgreSQL db:5432 Redis redis:6379 Mock 服务 mock:9090 测试容器 pytest / Postman 说明:Compose 通过服务名(如 db、redis)实现容器间 DNS 解析,测试容器可直接访问被测服务与依赖。

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。