Docker vs Kubernetes:容器化与容器编排的选型决策

Docker 和 Kubernetes 不是二选一的关系。本文详解两者的定位差异、使用场景、协作方式,以及何时只用 Docker、何时需要 K8s、何时用 Docker Compose 过渡。附生产环境部署选型决策树。

Docker 和 Kubernetes(K8s)是最常被混淆的两个概念:很多人以为它们是同类产品,实际上它们解决的是完全不同层级的问题。Docker 是"容器运行时"(run a container),Kubernetes 是"容器编排平台"(manage thousands of containers)。本文用清晰的对比和选型决策,帮你理解两者的关系。


一、定位差异:一件事的两个层级

维度DockerKubernetes
核心层级容器运行时 + 镜像构建容器编排 / 调度平台
解决的核心问题“如何把应用打包成容器并在单机上运行”“如何在集群中管理成百上千个容器”
类比单个集装箱及其内容港口调度系统(管理无数集装箱的装卸、调度、路由)
主要操作对象镜像(Image)、容器(Container)Pod、Deployment、Service、Ingress
功能范围构建、运行、网络、存储(单机)调度、扩缩容、自愈、服务发现、负载均衡(集群)
学习曲线平缓(1-2 天上手)陡峭(2-4 周入门)
运维复杂度

协作关系

Kubernetes Cluster
  ├── Master Node(控制平面)
  │   └── API Server / Scheduler / Controller Manager / etcd
  └── Worker Node(计算节点)
      └── kubelet → 调用 → Docker / containerd(容器运行时)
                     ↑
              Docker 在这里:实际启动/停止容器

关键点:Kubernetes 本身不"运行"容器,它通过 kubelet 调用 Docker(或 containerd / CRI-O)来实际运行容器。Docker 是 K8s 的底层依赖之一


二、Docker 提供的核心能力

# 构建镜像
docker build -t my-app .

# 运行容器
docker run -d -p 3000:3000 my-app

# 容器间通信(单机)
docker network create my-net
docker run --name db --network my-net postgres
docker run --name api --network my-net my-api

Docker 的局限(单机体感):

  • 只能管理一台机器上的容器
  • 容器故障不会自动重启
  • 流量大了不能自动扩容
  • 没有内置的服务发现和负载均衡

三、Kubernetes 提供的核心能力

# deployment.yaml:声明式部署 3 个副本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-api
  template:
    metadata:
      labels:
        app: my-api
    spec:
      containers:
      - name: api
        image: my-app:v1.0
        ports:
        - containerPort: 3000

K8s 解决的核心问题:

场景Docker 单机K8s
容器挂了手动重启自动重启(Self-healing)
流量突增手动启动新容器HPA 自动扩缩容
滚动更新手动停旧启新零停机滚动更新
服务发现手动配 IP内置 DNS 服务发现
负载均衡手动配 Nginx内置 Service + Ingress
配置管理环境变量ConfigMap / Secret
存储挂载VolumePersistentVolume / StorageClass
多机部署不支持跨节点调度

四、中间层:Docker Compose

Docker Compose 是 Docker 官方的单机多容器编排工具,适合开发和测试环境:

# docker-compose.yml
version: '3'
services:
  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  api:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      DATABASE_URL: postgres://postgres:secret@db:5432/mydb

volumes:
  postgres_data:
# 一键启动整个应用栈
docker-compose up -d
# 停止
docker-compose down

Docker Compose 的定位

  • ✅ 本地开发环境
  • ✅ CI/CD 测试流水线
  • ✅ 小型项目(< 5 个服务)的单机部署
  • ❌ 生产级多机集群(这时需要 K8s)

五、选型决策树

你需要运行容器?
  ├── 是 → 只有一台服务器?
  │       ├── 是 → 服务数量?
  │       │       ├── 1-3 个服务 → Docker Compose ✅
  │       │       └── 4+ 个服务 → Docker Compose 勉强可用 ✅
  │       └── 否(多台服务器/集群)→ 需要 K8s ✅
  └── 否 → 你不需要 Docker 也不需要 K8s

Kubernetes 必需场景(必须上 K8s):
  ├── 多服务器容器调度
  ├── 自动扩缩容(HPA)
  ├── 生产级滚动更新(零停机)
  ├── 复杂的微服务拓扑(10+ 服务互调)
  └── 多云/混合云部署

场景矩阵

场景推荐方案理由
本地开发Docker Compose简单,一键启动全栈
单服务生产部署Docker + systemd最简单,运维成本低
小型 SaaS(3-5 服务)Docker Compose + 1-2 台服务器够用,维护简单
中型产品(5-20 服务)Kubernetes(托管)AWS EKS / GKE / 阿里云 ACK
大型微服务(20+ 服务)Kubernetes + Service Mesh(Istio)服务治理、流量管控
Serverless无需 Docker/K8s直接用 Vercel / Lambda / Cloud Run

六、托管 K8s vs 自建 K8s

方案成本运维负担适用
自建 K8s低(只有服务器费用)极高大规模、有专职 DevOps 团队
AWS EKS中 ($73/月集群管理费 + EC2)AWS 用户
GKE中 ($73/月 + GCP 费用)GCP 用户
阿里云 ACK中 (~¥400/月 + ECS)国内部署
Vercel / Railway / Render高(按量)不想碰 K8s 的小团队

常见问题(FAQ)

Kubernetes 正在淘汰 Docker 吗?

不是淘汰 Docker 作为容器运行时,而是 K8s 在 1.24 版本移除了对 Docker Engine 的直接支持,改用 containerd 作为默认容器运行时。containerd 是 Docker 的核心运行时组件,Docker 本身也基于 containerd。

对开发者的影响:开发机上仍然用 Docker Desktop 构建镜像、运行容器。K8s 集群内部默默用 containerd 替代 Docker Engine,这是 K8s 内部实现细节,对使用者几乎透明。

公司内部已经用 Docker 了,需要立刻迁移到 K8s 吗?

不需要。Docker 容器可以在任何地方运行。只有当以下情况才需要引入 K8s:

  • 单台服务器资源不够,需要多机部署
  • 容器数量多到手动管理困难
  • 业务对高可用和自动扩容有硬性要求

有了 K8s 还需要 Docker 吗?

仍然需要。Docker(或 BuildKit / Podman)负责构建镜像。K8s 不构建镜像,它只运行和管理镜像。两者是上下游关系,不是替代关系。

相关阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「saas」更多文章