本节摘要:本节回答"规模大了往哪走"。核心认知有三条:Compose 是单机编排工具,不具备自动故障转移;Docker Swarm 是 Docker 原生的集群方案,与 Compose 兼容性最好但发展停滞;Kubernetes 是容器编排的事实标准,功能全、生态大、学习成本高。选型的关键是规模与团队能力。最后给出"Compose 文件是最小公共描述"的思路:一份文件用 docker stack deploy 直通 Swarm,用 kompose 转换上 Kubernetes。
前面几节反复提到 Compose 的能力边界,这里集中说透。Compose 主要面向单机环境或小型集群,上生产要直面四条限制。
第一,单点故障。Compose 通常运行在单个 Docker 主机上,这台机器宕了,整个应用就停了——没有别的节点可以接管。第二,扩展性有限。它无法轻松跨多台主机扩展,副本数受限于单机资源,docker compose up --scale 只能在当前机器上加副本。第三,没有高可用机制。Compose 本身不提供自动故障转移,容器挂了靠 restart 策略拉起,节点挂了没有任何机制迁移服务。第四,服务发现简单。Compose 的服务发现依赖 Docker 内置 DNS,在复杂网络环境里不够灵活。第五,资源调度简单。它不能根据应用需求动态分配资源,限额是静态配置。
这不是贬低 Compose——它的设计目标就是"单机上的多容器编排",在目标范围内它做得足够好。关键是别越界使用:业务是单机可承载的,Compose 就是最优解;业务要求跨节点高可用,就该换工具。
Docker Swarm 是 Docker 官方自带的容器编排工具,把多台 Docker 主机组成一个集群,对外像管理单机一样管理整个集群。它的优势恰恰是 Compose 缺的:内置服务发现,容器通过服务名互相访问;内置高可用机制,节点故障时自动把容器重新调度到健康节点;扩展只需往集群里加机器,一条命令加节点。而且它和 Docker 生态无缝集成,用 Docker CLI 就能管理,学习曲线比 Kubernetes 平缓得多。
Swarm 和 Compose 的关系最特别:Compose 文件可以直接部署到 Swarm,用 docker stack deploy 命令:
docker stack deploy -c docker-compose.yml myapp
这条命令把 docker-compose.yml 里定义的服务部署到名为 myapp 的 Stack 中。Swarm Manager 负责把服务调度到各个 Worker 节点上运行。这意味着我们从单机 Compose 迁移到 Swarm,不需要重写任何文件——这是 Compose 文件"最小公共描述"价值的第一个体现。
但要诚实说明 Swarm 的现状:Docker 公司对 Swarm 的投入早已收缩,功能停在多年前的水平,社区活跃度远不如 Kubernetes。它仍然是"简单、够用、与 Docker 同源"的集群方案,适合团队不大、不想学 Kubernetes 的中型场景;但它不是生态的将来,选择它要有"未来可能迁移"的觉悟。
Kubernetes 是开源的容器编排平台,自动化部署、扩展、管理容器化应用,已经成为事实标准,被广泛应用于各种规模的组织。它的能力清单比 Swarm 长得多:自动部署、滚动更新、服务发现、负载均衡、自动伸缩、健康检查与自愈,还能扩展到数千节点的规模。生态是它最厚的壁垒——云厂商、监控、日志、服务网格、CI/CD 工具全部围绕 Kubernetes 构建。
代价是复杂度。Kubernetes 的概念体系(Pod、Deployment、Service、Ingress、Namespace)需要专门学习,集群本身要运维,出事排查的链路也长。对小团队而言,学习成本和运维成本可能超过业务本身。
Compose 与 Kubernetes 之间没有直通车,但有转换器。Kompose 可以把 Compose 文件转换成 Kubernetes 的 Deployment、Service 等资源定义文件。典型流程是:安装 kompose 二进制(我们常用 v1.26.1 版本,从官方发布页下载对应平台的压缩包解压后放入 PATH),然后执行转换:
kompose convert -f docker-compose.yml
这条命令会生成 Kubernetes 的 YAML 文件,再用 kubectl 部署:
kubectl apply -f deployment.yaml kubectl apply -f service.yaml
转换的思路是"把 compose 的意图翻译成 Kubernetes 原语":service 转 Deployment,网络转 Service,卷转 PersistentVolumeClaim。但转换是有损的,两个例子:compose 的 healthcheck 与 Kubernetes 的探针语义并不完全对齐;deploy.resources 的保留语义(reservations)在 Kubernetes 里对应不同的调度模型。所以我们的建议是:kompose 适合把原型快速搬上 Kubernetes 做验证,长期运行的复杂应用,还是按 Kubernetes 原语直接写清单更可控。
三种方案的取舍,集中在一张表里:
| 维度 | Docker Compose | Docker Swarm | Kubernetes |
|---|---|---|---|
| 定位 | 单机多容器编排 | 中型集群编排 | 大规模容器平台 |
| 学习成本 | 低 | 中 | 高 |
| 自动伸缩 | 无 | 支持 | 支持且更灵活 |
| 自动故障转移 | 无 | 节点故障自动调度 | 自愈机制完善 |
| 滚动更新 | 粗糙,易中断 | 支持 | 精细化控制 |
| 服务发现 | 依赖 Docker DNS | 内置 | 内置加生态 |
| 跨主机扩展 | 不支持 | 支持 | 数千节点 |
| 与 Compose 兼容 | 原生 | docker stack deploy 直通 | kompose 转换有损 |
| 生态与社区 | 单机生态 | 收缩停滞 | 事实标准,最活跃 |
选型建议可以浓缩成三句话。应用规模小、单机可承载、团队刚接触容器:直接用 Compose,把精力花在安全、监控、备份上。需要跨节点高可用、团队都是 Docker 思维、不想学新体系:Swarm 是低成本过渡,docker stack deploy 零改写。规模大、要完整的调度与生态、有专职平台团队:Kubernetes,别绕路。
把"最小公共描述"的思路落成例子。一份最简单的 compose 文件:
version: "3.9" services: web: image: nginx:1.25 ports: - "8080:80" redis: image: redis:7-alpine volumes: - redis_data:/data volumes: redis_data:
这份文件有三个去处。单机开发与测试:docker compose up -d,一行拉起。Swarm 集群:docker stack deploy -c docker-compose.yml myapp,同一份文件直接部署,Swarm 负责副本调度与故障迁移。Kubernetes:先 kompose convert -f docker-compose.yml 生成清单,再 kubectl apply 部署。
关系图画出来是这样的:
这个例子的意义在于:Compose 文件写的是"应用长什么样"——有哪些服务、怎么连接、数据放哪,这是与编排层无关的意图描述。Swarm 和 Kubernetes 只是不同的"执行引擎"。理解了这一点,选择工具时就不会被绑定感困扰:先用 Compose 快速起步,规模到了,同一份描述可以换引擎。
选型不是一次性决定,常见路径是"Compose 起步,规模逼近单机极限时再迁移"。判断迁移时机的信号有三个:单机资源接近上限且加机器无法平滑扩展;业务要求发布不中断、节点故障自动恢复;团队开始频繁讨论"如果这台机器挂了怎么办"。出现任何一个,就该认真评估 Swarm 或 Kubernetes 了。
迁移路线有两条。平滑路线,Compose 到 Swarm:文件基本不用改,但要注意几个字段差异——deploy.replicas 在 Swarm 下真正生效,副本数由 Swarm 调度;deploy.placement 可以约束服务跑在哪些节点;端口发布用 ports 还是 expose 要按 Swarm 网络模型调整。先起一个两节点的 Swarm 集群,把非核心服务迁过去跑两周,稳定了再迁核心。跳级路线,Compose 到 Kubernetes:kompose 转换生成初版清单,然后按 Kubernetes 习惯手工完善——健康检查改成探针、环境变量改 ConfigMap、密钥改 Secret、卷改 PersistentVolumeClaim。转换后的清单要当"初稿"看待,直接上生产会踩语义差异的坑。
几个高频坑。把 stack 当 compose 用:docker stack deploy 之后,docker compose down 并不管理 Swarm 的服务,停服务要用 docker stack rm,两套命令体系别混用。忽略服务发现差异:Swarm 和 Kubernetes 里服务名解析与端口语义和单机不同,应用里的连接串要按新环境调整,最常见的翻车点是应用还在连 localhost。卷不迁移:单机的 named volume 不会自动出现在集群节点上,迁移前先把数据卷备份好,按 4.5 的流程恢复到新环境。低估 Kubernetes 运维成本:集群要升级、证书要轮换、节点要维护,小团队没有专职平台工程师的话,Swarm 或 Compose 可能更务实。
把这些串起来看,选型决策就一句话:能单机就别集群,要集群先试 Swarm,真要完整生态和规模再上 Kubernetes。Compose 文件作为最小公共描述,让每一步迁移都有退路——这也是它最大的价值。迁移团队里至少要有一个能扛住新体系排障的人,其他人跟着他逐步上手,比全员同时从零开始稳妥。
从 Compose 跳到 Swarm 或 Kubernetes,最痛苦的是概念对不上号。做一张对照表能省不少学习时间:Compose 的 service 对应 Swarm 的 service,对应 Kubernetes 的 Deployment 加 Service 两个对象——前者管副本和更新,后者管访问入口;Compose 的 network 对应 Swarm 的 overlay 网络,对应 Kubernetes 的 Service 与 Ingress;Compose 的 volume 对应 Swarm 的 volume,对应 Kubernetes 的 PersistentVolumeClaim;Compose 的 healthcheck 对应 Swarm 的 healthcheck,对应 Kubernetes 的探针,分为存活探针与就绪探针。概念映射到位后,原来写的 compose 文件就变成了学习新体系的参照系:每个键都能问一句"这个在新体系里对应什么"。
映射之外还有两个心态准备。第一,字段不是一一对应的,很多 compose 简写在新体系里要拆成多个对象,这是正常的,不是工具缺陷。第二,新体系的排查链路更长:Compose 出问题看 docker compose ps 和 logs 就够,Kubernetes 要按 Pod、Deployment、Service 逐层查,排查顺序本身就是学习材料。Swarm 侧的常用命令也就三条:docker service ls 看服务,docker service scale 调副本,docker stack rm 停栈;Kubernetes 侧先用 kubectl get pods 和 kubectl logs 入门,其余随用随查。理解了这些,迁移期的挫败感会小很多。
迁移落地还有一条实操建议:先迁无状态服务。Web 前端、API 这类不落数据的服务迁移风险最低,跑顺了再迁带卷的数据库和缓存,最后处理定时任务和特殊网络需求。每迁一个服务就更新一次部署文档和回滚方案,别一口气全量迁移——分步迁移失败时能退,全量迁移失败时只能通宵。迁移窗口选业务低峰,迁移完成后保留旧环境至少一个发布周期,确认新环境稳定再拆除。
⚠️ docker stack deploy 不是 compose 字段的完全兼容。deploy.resources 在 Swarm 下是调度约束,在单机 compose 下只是软提示;部分字段(如部分健康检查语义)在两种模式下行为不同。升级前先在 Swarm 环境试跑一遍,别直接拿生产文件上。
💡 把 Compose 文件当成"应用的档案"。即使最终上了 Kubernetes,保留一份可运行的 Compose 文件依然有价值:本地复现、快速原型、文档说明,它比任何架构图都准确。
到这里,第四章的七个维度全部过完了:从部署考量到安全、性能、日志、备份,再到 CI/CD 与编排选型。下一章,我们把视角转向故障现场——排查与解决。