Docker Compose vs Kubernetes:2023 年该如何选择
前言
“小项目用 Compose,大项目上 K8s”——这句在开发者社区流传的话,大致方向是对的,但实际的技术选型远比这复杂。2023 年,Kubernetes 的复杂度依然让人望而却步,而 Docker Compose 也在逐步进化。本文将抛开"K8s 就是高大上"的滤镜,从你真实的业务场景出发,帮你做选择。
核心差异一览
先看一张总览表——两种方案的定位完全不同:
| 对比维度 | Docker Compose | Kubernetes |
|---|---|---|
| 定位 | 单机容器编排 | 集群容器编排 |
| 学习成本 | 低(1-2 天) | 高(数周至数月) |
| 运维成本 | 几乎为零 | 需要专业运维团队 |
| 高可用 | ❌ 不支持 | ✅ 原生支持 |
| 自动伸缩 | ❌ 不支持 | ✅ HPA 自动伸缩 |
| 服务发现 | DNS 内部解析 | Service + DNS |
| 滚动更新 | 基本支持 | 丰富策略 |
| 存储卷 | 本地绑定 | 多种 CSI 驱动 |
| 网络模型 | 简单桥接 | CNI 插件(Calico、Flannel 等) |
| 监控日志 | docker logs | Prometheus + EFK/Loki |
| 安装复杂度 | apt install docker-compose |
kubeadm / 托管集群 |
Docker Compose 的目标是让单机容器管理变得简单,K8s 的目标是让大规模集群变得可控。
Docker Compose 详解
适合的场景
- 个人项目 / 小团队:1-5 个微服务,单台服务器
- 开发环境标准化:让团队所有人用相同的本地环境
- CI/CD 中的测试环境:临时启停集成测试依赖
- 小规模生产部署:无高可用要求的小型 SaaS 或 API
一个典型的 Compose 文件
version: "3.9"
services:
# Web 后端
api:
build: ./api
ports:
- "8080:8080"
environment:
- DB_HOST=postgres
- REDIS_HOST=redis
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
# 数据库
postgres:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_DB=myapp
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 5s
# 缓存
redis:
image: redis:7-alpine
volumes:
- redisdata:/data
# 前端静态文件
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./static:/usr/share/nginx/html:ro
depends_on:
- api
volumes:
pgdata:
redisdata:
secrets:
db_password:
file: ./secrets/db_password.txtCompose 的进化:Docker Compose v2
2023 年,Docker Compose 从 Python 实现的 v1 全面转向 Go 实现的 v2(作为 Docker CLI 插件 docker compose,不带短横线):
# 新版本用法(docker compose 替代 docker-compose)
docker compose up -d # 启动所有服务
docker compose ps # 查看状态
docker compose logs -f # 跟踪日志
docker compose exec api sh # 进入容器
docker compose down # 停止并清理
docker compose pull # 拉取镜像更新新版的改进:
- 更快的解析速度:Go 原生实现,启动比 v1 快 3-5 倍
- 更好的资源隔离:支持
--scale实现简单的水平扩展 - Watch 模式:
docker compose watch自动同步文件变更到容器
Kubernetes 详解
适合的场景
- 中大型团队:10 个以上微服务
- 高可用要求:99.9% 以上可用性
- 弹性伸缩需求:流量波动大,需要自动扩缩容
- 多环境管理:开发 / 预发布 / 生产多套环境
- 混合云 / 多云部署:需要跨云平台调度
必知的核心概念
| 概念 | 类比 | 说明 |
|---|---|---|
| Pod | 容器实例 | K8s 的最小调度单元,一个或多个容器 |
| Deployment | 无状态应用 | 管理 Pod 的副本数和滚动更新 |
| Service | 稳定网络端点 | 为 Pod 提供固定的 DNS 和负载均衡 |
| Ingress | 反向代理 | HTTP/HTTPS 路由到不同 Service |
| ConfigMap | 配置文件 | 将配置从容器镜像中解耦 |
| Secret | 密钥 | 敏感信息存储 |
| PersistentVolume | 存储卷 | 有状态应用的数据持久化 |
一个简单的 K8s 部署
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapp/api:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "postgres-service"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80这只是最基础的部署配置。实际生产还需要配置 HPA、NetworkPolicy、PodDisruptionBudget、RBAC 等,复杂度可见一斑。
2023 年的 K8s 趋势
- Sidecar-less 服务网格:Istio Ambient Mesh 在 2023 年进入 Beta,不再需要每个 Pod 挂载 Sidecar
- Gateway API 取代 Ingress:K8s 官方的新一代 API 网关标准,功能远超传统 Ingress
- K8s on the Edge:K3s、KubeEdge 等轻量级 K8s 发行版让容器编排走向边缘
- eBPF 深度集成:Cilium 成为 CNI 首选,eBPF 替代 iptables 带来性能飞跃
决策树:你到底该选哪个?
用下面的问题走一遍,就能明确方向:
你的应用需要运行在几台机器上?
├── 1 台 → Docker Compose(足够用了)
└── 多台 → 继续看下一个问题
你需要自愈(宕机自动重启)吗?
├── 是 → 考虑 K8s(Swarm 已边缘化)
└── 否 → 继续看
你的团队有专职运维吗?
├── 有 → K8s(托管集群更省心)
└── 无 → 继续看
你的服务数量?
├── 3 个以下 → Docker Compose + 单机 + 定时备份
├── 3-10 个 → Docker Compose / 托管 K8s(折中)
└── 10 个以上 → 托管 K8s(EKS/GKE/ACK)折中方案:托管 K8s + Compose 本地开发
2023 年最常见的实际做法是两者都要:
开发环境 → Docker Compose(本地快速启动)
CI 集成测试 → Docker Compose(轻量、无依赖)
预发布环境 → 托管 K8s(与生产一致)
生产环境 → 托管 K8s(高可用、弹性伸缩)托管 K8s(EKS / GKE / AKS / ACK)可以大幅降低运维成本——你只管 kubectl apply,集群管理交给云厂商。
用 Compose 模拟 K8s 本地开发
2023 年的工具生态已经可以让你在本地用 Compose 风格的配置,跑出接近 K8s 的效果:
# docker-compose.yml 模拟 K8s 的 Secret 和 ConfigMap
version: "3.9"
configs:
app_config:
file: ./config/app.yaml
secrets:
db_password:
file: ./secrets/db_password.txt
services:
api:
image: myapp/api
configs:
- source: app_config
target: /etc/config/app.yaml
secrets:
- db_password
environment:
- K8S_NAMESPACE=development配合 kind(Kubernetes in Docker)或 k3d,也可以在本地启动一个真实的 K8s 集群:
# 用 kind 在本地启动一个 3 节点的 K8s 集群
kind create cluster --config kind-config.yaml --name dev
# 查看集群
kubectl cluster-info
kubectl get nodes误区澄清
“K8s 就是 YAML 复杂?”
更准确的说法是:容器化本身就有一套抽象概念——网络、存储、配置、安全——在 Compose 中这些概念被简化,在 K8s 中被完整暴露。不是 K8s 的问题,而是你的应用复杂度到了需要这些抽象的时候。
“用 K8s 就不需要 Compose?”
❌ 实际上 K8s 官方也在自己的项目中大量使用 Compose。两个工具解决的是不同层面的事情。
“小项目用 Compose 以后能平滑迁移到 K8s?”
⚠️ 部分可以。如果你的 Compose 配置遵循了微服务的最佳实践(环境变量注入、无状态、健康检查),迁移成本可控。但如果用了大量 Compose 特有的特性(如 depends_on 隐式依赖、links),迁移会比较痛苦。
总结
| 你的情况 | 推荐方案 |
|---|---|
| 个人项目 / 小团队·单机 | Docker Compose |
| 小团队·多机·无专人运维 | Docker Compose + 简单自动化部署脚本 |
| 中型团队·3-10 服务 | 托管 K8s(EKS/GKE) |
| 大型团队·10+ 服务·高可用 | 托管 K8s + 专业运维 |
| 开发 / 测试环境 | Docker Compose(不管线上用啥) |
选择容器编排工具的核心原则:用最少的工具复杂度和运维成本,解决你的实际问题。 如果你的项目只有两个微服务 + 一个数据库,跑在一台 4 核 8G 的服务器上,Docker Compose 就是最好的选择——K8s 带来的高可用和弹性伸缩对你毫无意义,只会增加痛苦。
2023 年,容器编排的正确态度是:不要为了 K8s 而 K8s,但也别在需要它的时候硬扛。