3. Docker Compose 入门:Compose文件结构、服务定义、网络与卷的声明、常用Compose命令
在搭建缓存一致性测试环境时,多个容器(如 Redis 主从、Sentinel、应用模拟器)需要协同工作。手动管理每个容器的启动顺序、网络连接和数据持久化非常繁琐。Docker Compose 正是解决这一问题的利器——它通过一个声明式 YAML 文件,定义整个多容器应用栈,实现一键部署与销毁。
3.1 Compose 文件结构
Compose 文件(默认名为 docker-compose.yml 或 compose.yaml)采用 YAML 格式,顶层结构固定为三个主要区块:services、networks 和 volumes。此外,version 字段在 Compose V2 中已废弃,但旧版文件仍可能保留。
| 顶层区块 | 作用 | 是否必选 |
|---|---|---|
services |
定义每个容器的镜像、端口、环境变量、依赖关系等 | 必选 |
networks |
声明自定义网络,实现服务间隔离与通信 | 可选(默认使用 default 网络) |
volumes |
声明持久化卷或绑定挂载,用于数据持久化 | 可选 |
最佳实践:始终显式声明
networks 和 volumes,即使只使用默认值。这能提升文件可读性,并避免后续扩展时遗漏配置。
3.2 服务定义详解
每个服务对应一个容器。以下是一个缓存测试场景中典型的服务定义示例,包含 Redis 主节点和 Sentinel 节点:
services:
redis-master:
image: redis:7-alpine
container_name: cache-master
ports:
- "6379:6379"
volumes:
- master-data:/data
- ./config/redis-master.conf:/usr/local/etc/redis/redis.conf
networks:
- cache-net
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
sentinel-1:
image: redis:7-alpine
container_name: sentinel-1
ports:
- "26379:26379"
volumes:
- ./config/sentinel.conf:/usr/local/etc/redis/sentinel.conf
networks:
- cache-net
depends_on:
- redis-master
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
| 字段 | 说明 | 缓存测试场景示例 |
|---|---|---|
image |
指定容器镜像,支持标签 | redis:7-alpine(轻量 Redis 镜像) |
container_name |
自定义容器名称,便于识别 | cache-master |
ports |
宿主机端口:容器端口映射 | "6379:6379" |
volumes |
挂载卷或绑定宿主机路径 | 持久化 RDB/AOF 文件、挂载配置文件 |
networks |
加入的自定义网络 | cache-net |
depends_on |
声明启动顺序依赖 | Sentinel 依赖 Master 先启动 |
command |
覆盖 Dockerfile 中的 CMD | 指定配置文件启动 Redis |
注意:
depends_on 仅控制容器启动顺序,不保证服务就绪。在缓存一致性测试中,建议配合 healthcheck 或等待脚本,确保主节点完全启动后再启动 Sentinel。
3.3 网络与卷的声明
在 Compose 文件中,网络和卷需要在顶层声明,然后在服务中引用。这种分离设计使得网络拓扑和存储策略可以独立复用。
网络声明
networks:
cache-net:
driver: bridge
ipam:
config:
- subnet: "172.20.0.0/16"
gateway: "172.20.0.1"
在缓存测试中,自定义网络可以固定子网,便于配置静态 IP 或模拟网络分区故障。如果不指定 driver,默认使用 bridge。
卷声明
volumes:
master-data:
driver: local
sentinel-data:
driver: local
卷声明后,在服务中通过 volumes: 引用:
services:
redis-master:
volumes:
- master-data:/data
绑定挂载(bind mount)则直接在服务中写宿主机路径,无需在顶层声明:
volumes:
- ./config/redis-master.conf:/usr/local/etc/redis/redis.conf
3.4 常用 Compose 命令
以下命令覆盖了缓存测试环境从启动到清理的完整生命周期:
| 命令 | 作用 | 缓存测试场景示例 |
|---|---|---|
docker compose up -d |
后台启动所有服务 | 启动 Redis 主从 + Sentinel 集群 |
docker compose down |
停止并移除容器、网络 | 清理测试环境,保留卷数据 |
docker compose down -v |
停止并移除容器、网络、卷 | 完全重置测试环境,清除所有数据 |
docker compose ps |
查看服务状态 | 确认所有节点运行正常 |
docker compose logs -f |
实时查看日志 | 观察主从同步或故障转移日志 |
docker compose exec <service> <cmd> |
在运行中的容器内执行命令 | exec redis-master redis-cli info replication |
docker compose restart |
重启指定或所有服务 | 模拟节点重启,测试缓存恢复 |
docker compose config |
验证并显示合并后的 Compose 配置 | 检查多文件合并后的最终配置 |
效率提示:在缓存一致性测试中,频繁使用
docker compose up -d 和 docker compose down -v 组合,可以快速在“干净状态”和“故障恢复”场景之间切换,大幅缩短测试准备时间。
3.5 完整 Compose 文件示例
以下是一个面向缓存一致性测试的最小化 Compose 文件,包含 Redis 主节点和一个 Sentinel 实例:
version: "3.8"
services:
redis-master:
image: redis:7-alpine
container_name: cache-master
ports:
- "6379:6379"
volumes:
- master-data:/data
- ./config/redis-master.conf:/usr/local/etc/redis/redis.conf
networks:
cache-net:
ipv4_address: 172.20.0.10
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 3
sentinel-1:
image: redis:7-alpine
container_name: sentinel-1
ports:
- "26379:26379"
volumes:
- ./config/sentinel.conf:/usr/local/etc/redis/sentinel.conf
networks:
cache-net:
ipv4_address: 172.20.0.20
depends_on:
redis-master:
condition: service_healthy
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
networks:
cache-net:
driver: bridge
ipam:
config:
- subnet: "172.20.0.0/16"
volumes:
master-data:
driver: local
该示例展示了 healthcheck 与 depends_on.condition 的配合使用,确保 Sentinel 仅在 Master 健康就绪后才启动——这是缓存一致性测试中避免竞态条件的关键配置。