Compose 中的 services、networks、volumes
三大核心配置的关系
在 Docker Compose 中,services、networks、volumes 是三个最顶层的配置区块。它们的关系可以类比为真实数据中心的规划:
| 配置 | 类比 | 作用 |
|---|---|---|
| services | 服务器 | 运行什么应用 |
| networks | 交换机/网线 | 服务器之间怎么连接 |
| volumes | 硬盘 | 数据存哪里 |
三者独立声明、组合使用,实现了关注点分离。
services:定义应用组件
services 是整个 Compose 配置的核心,每个 service 对应一个或多个容器实例。
service 的常见配置
services:
# 一个 Web API 服务
api:
build: ./api
ports:
- "8080:8080"
environment:
DB_HOST: db
networks:
- frontend
- backend
volumes:
- app-data:/app/data
depends_on:
- db
# 数据库服务
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
volumes:
- pg-data:/var/lib/postgresql/data
networks:
- backend
服务的多实例
services:
web:
image: nginx
# 传统方式(Compose V2)
deploy:
replicas: 3
ports:
- "80:80"
networks:定义网络拓扑
自动创建网络
当你在 services 中引用网络时,Compose 会自动创建它们:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 后端网络不可对外访问
monitoring:
external: true # 引用已存在的网络
name: monitor-net
网络类型
# Bridge 网络(默认)
networks:
my-bridge:
driver: bridge
driver_opts:
com.docker.network.bridge.name: my-bridge
# Overlay 网络(Swarm 模式)
networks:
my-overlay:
driver: overlay
attachable: true
# Macvlan 网络
networks:
my-macvlan:
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
IPAM 配置
networks:
custom-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
固定 IP 地址
services:
db:
image: postgres
networks:
backend:
ipv4_address: 172.20.0.10
networks:
backend:
ipam:
config:
- subnet: 172.20.0.0/16
volumes:定义数据存储
声明命名卷
volumes:
pg-data: # 最简单的声明
redis-data:
driver: local # 指定驱动类型
nfs-storage:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/exports/data"
external-volume:
external: true # 引用外部已存在的卷
name: prod-db-data # 覆盖外部卷名称
外部卷引用
volumes:
# 引用已存在的 Docker Volume
existing-data:
external: true
# 指定不同的外部名称
production-db:
external: true
name: prod-postgres-data # 实际的 Volume 名叫这个
三者如何协同工作
完整示例
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- static-assets:/usr/share/nginx/html:ro
- nginx-logs:/var/log/nginx
networks:
- public
- internal
depends_on:
- api
api:
build:
context: ./api
dockerfile: Dockerfile
volumes:
- api-data:/app/data
- static-assets:/app/static
environment:
DB_HOST: db
networks:
- internal
depends_on:
db:
condition: service_healthy
db:
image: postgres:15-alpine
volumes:
- db-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
POSTGRES_DB: myapp
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 10s
networks:
public:
driver: bridge
internal:
driver: bridge
internal: true
volumes:
static-assets:
api-data:
db-data:
nginx-logs:
在这个示例中:
- nginx 通过
public网络对外提供服务,通过internal网络访问 api - api 在
internal网络中工作,通过depends_on确保 db 先启动 - db 完全在
internal网络中,外部无法直接访问 - static-assets 卷被 nginx 和 api 同时挂载
- db-data 卷持久化 PostgreSQL 数据
网络拓扑图示
Internet
|
[public 网络]
|
(nginx)
|
[internal 网络]
/ | \
(api) (api) (api)
| |
(redis)(postgres)
最佳实践
- 网络安全隔离:前端服务放 public 网络,内部服务放 internal
- 卷数据共享:多个服务需要共享文件时使用同一个命名卷
- 显式声明:不要依赖默认网络和匿名卷
- 外部资源引用:
external: true用于共享已经存在的网络或卷 - IP 管理:需要固定 IP 时在 IPAM 中配置
面试要点
Q:services 中引用了未在顶级 volumes/networks 中声明的卷/网络会怎样?
A:Compose 会自动创建它们。但显式声明更清晰,也允许配置额外参数(如驱动选项、IPAM)。
Q:internal: true 的网络有什么作用?
A:阻止外部容器访问该网络,提高安全性。数据库等服务应该放在 internal 网络中。
Q:external: true 和默认声明的区别?
A:external: true 表示引用一个已经存在的网络/卷,Compose 不会尝试创建它。如果不存在会报错。常用于共享基础设施。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容