一、Composition与System概述
说实话,我刚接触容器化那会儿,也被Composition和System这两个概念搞晕过。它们听起来像是一回事,但实际用起来差别还挺大。今天咱们就好好聊聊,这两个文件到底是什么、怎么用、在系统设计里扮演什么角色。
1.1 什么是Composition文件
Composition文件,说白了就是一个描述「一组容器如何协同工作」的配置文件。我习惯把它理解成「微服务的菜谱」——里面写清楚了要启动哪些服务、每个服务用什么镜像、端口怎么映射、环境变量怎么配。
举个例子,一个典型的Composition文件长这样:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
depends_on:
- api
api:
image: my-api:latest
environment:
- DB_HOST=db
db:
image: postgres:13
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
嗯,这里要注意:Composition文件的核心价值在于「编排」。它不关心单个容器怎么跑,它关心的是多个容器怎么配合。我在项目中遇到过好几次,开发环境用Composition文件一把梭,所有服务一键启动,确实方便。
1.2 什么是System文件
System文件就不同了。它描述的是「整个系统的拓扑结构」——包括服务、网络、存储、安全策略等等。你可以把它想象成一张建筑蓝图,不光画了房间布局,连水管、电线、承重墙都标得清清楚楚。
来看一个简化的System文件示例:
system:
name: "电商平台"
version: "2.0"
services:
- name: "用户服务"
replicas: 3
resources:
cpu: "2"
memory: "4Gi"
network:
- "internal-net"
- name: "订单服务"
replicas: 5
resources:
cpu: "4"
memory: "8Gi"
network:
- "internal-net"
- "external-net"
networks:
- name: "internal-net"
cidr: "10.0.0.0/16"
- name: "external-net"
cidr: "172.16.0.0/16"
storage:
- name: "order-db"
size: "500Gi"
type: "ssd"
你想想看,System文件关注的是「系统级」的约束——多少个副本、多少资源、网络怎么隔离。这些在Composition文件里是看不到的。
1.3 两者的关系与区别
我经常被问到:「这两个文件能不能互相替代?」答案是不能。它们的关系更像是「宏观 vs 微观」:
| 维度 | Composition文件 | System文件 |
|---|---|---|
| 关注粒度 | 单个服务/容器 | 整个系统架构 |
| 部署环境 | 开发/测试环境 | 生产/预发布环境 |
| 资源管理 | 不涉及 | CPU、内存、存储 |
| 网络策略 | 简单端口映射 | 子网、路由、防火墙 |
| 扩缩容 | 不支持 | 支持副本数定义 |
| 版本管理 | 通常单文件 | 多文件、版本化 |
核心区别一句话总结:Composition文件告诉你「怎么跑」,System文件告诉你「跑成什么样」。
1.4 在系统设计中的角色
这两个文件在系统设计里扮演的角色完全不同,但缺一不可。
Composition文件的角色:
- 开发者的脚手架——快速搭建本地开发环境
- CI/CD的测试床——在流水线里跑集成测试
- 微服务的说明书——新人来了看一眼就知道项目怎么启动
System文件的角色:
- 架构师的蓝图——定义系统边界和依赖关系
- 运维的作业指导书——明确资源需求和部署策略
- 团队的沟通工具——所有人对系统结构有统一认知
我曾经在一个项目里吃过亏:开发团队只用Composition文件,结果上线时发现服务之间的网络不通、资源不够用。后来我们补了System文件,把整个拓扑画清楚,问题才解决。说白了,Composition管「跑起来」,System管「跑得稳」。
1.5 知识体系总览
下面这张图是我自己画的,把本章的核心逻辑串起来了:
我的建议:刚开始做系统设计时,先写Composition文件把服务跑通。等架构稳定了,再补System文件做规范化。别一上来就想搞大而全,容易把自己绕进去。
注意:不要把Composition文件直接用于生产环境。它缺少资源隔离、安全策略、监控告警等关键配置。我曾经见过有人图省事,把docker-compose.yml直接部署到线上,结果出问题连回滚都困难。