Docker 与 Kubernetes 的关系
学 Docker 的过程中,几乎一定会听到 Kubernetes(常简写为 K8s)这个名字。很多人会有疑问:它们是不是一类东西?学了 Docker 还要不要学 K8s?网上说「K8s 弃用 Docker」又是怎么回事?
这篇附录就把这些问题一次讲清楚。
各自解决的问题
Docker 和 K8s 不是竞品,它们解决的是两个不同层面的问题。
Docker 解决的是单机上的容器化问题:怎么把应用打包成镜像,怎么在一台机器上把容器跑起来。 具体包括:
- 用 Dockerfile 定义镜像,把应用和依赖环境打包成一个标准交付物。
- 用
docker run在单机上创建、启动、管理容器。 - 用 Volume 管理单机上的数据持久化,用 Docker 网络实现单机内容器之间的通信。
- 用 Docker Compose 编排单机上的多个容器(比如一个应用 + 一个数据库)。
Kubernetes 解决的是多机环境下的容器编排调度问题:当容器要跑在几十、几百台机器组成的集群上时,怎么管理它们。 具体包括:
- 调度:一个新容器应该放到集群里哪台机器上跑?K8s 根据资源占用、亲和性等规则自动决策。
- 自愈:容器挂了自动重启,节点宕机了把上面的容器迁移到其他节点重新拉起。
- 扩缩容:流量大了就把容器副本从 2 个加到 10 个,流量小了再缩回来。
- 服务发现与负载均衡:容器副本分布在不同机器上,IP 还会变,K8s 用 Service 提供固定入口并分发流量。
- 滚动更新与回滚:发布新版本时逐步替换旧容器,出问题一键回滚。
- 配置与存储管理:统一管理集群级别的配置(ConfigMap/Secret)和存储(PV/PVC)。
Docker 管「一台机器上怎么跑容器」,Kubernetes 管「一群机器上怎么跑容器」。Docker 是容器技术本身,K8s 是容器的集群管理者。
可以打个比方:Docker 是一辆汽车(负责把货物装好并跑起来),Kubernetes 是一个物流调度中心(负责决定成百上千辆车各走哪条路、哪辆坏了派新的顶上)。
概念对照
学过 Docker 再看 K8s,很多概念都能找到对应关系。下面这张表可以作为入门时的「翻译表」:
| Docker 世界 | Kubernetes 世界 | 说明 |
|---|---|---|
| Container(容器) | Container(容器) | 最底层运行单元是同一个东西,K8s 里跑的容器和 Docker 跑的本质相同 |
docker run 启动的单个容器 | Pod | K8s 的最小调度单位。一个 Pod 通常只装一个容器,也可以装多个紧密协作的容器,共享网络和存储 |
| Docker Compose | Deployment + Service | Compose 在单机上编排多容器;Deployment 负责在集群里维持 N 个 Pod 副本并支持滚动更新,Service 提供固定访问入口和负载均衡 |
docker-compose.yml | 各种 YAML 资源清单 | 都是声明式配置:写好期望状态,工具负责达成。K8s 的资源种类更多(Deployment、Service、Ingress 等) |
| Volume(数据卷) | PV(PersistentVolume)+ PVC(PersistentVolumeClaim) | Volume 挂在单机上;PV 是集群里的存储资源,PVC 是应用对存储的申请,两者分离后可以对接云盘、NFS 等各种后端 |
| Docker 网络(bridge、容器间互通) | Service + Ingress | Docker 网络解决单机内容器互通;Service 解决集群内跨机器访问一组 Pod,Ingress 负责把集群外的 HTTP/HTTPS 流量引进来 |
| Dockerfile / 镜像 | 完全沿用 | K8s 不构建镜像,直接使用符合 OCI 标准的镜像,Docker 构建的镜像可以直接用 |
| Docker Hub / 私有 Registry | 完全沿用 | K8s 同样从镜像仓库拉取镜像,Docker Hub、Harbor 等都能直接用 |
| Docker Engine(dockerd) | CRI 容器运行时(如 containerd) | K8s 通过 CRI 接口调用运行时来真正启动容器,现在主流是 containerd,而 containerd 正是 Docker 底层也在用的组件 |
记这张表不用一次记住,先在脑子里建立「单机 Docker 命令 → 集群 K8s 资源」的映射直觉,后面学 K8s 时每个新概念都能挂到已知的 Docker 概念上,会轻松很多。
演进关系
K8s 和 Docker 的关系在历史上变过一次,这也是「K8s 弃用 Docker」这个误解的来源。时间线大致如下:
- 早期(2014 年前后):K8s 刚诞生时,Docker 几乎是唯一的容器运行时,所以 K8s 直接调用 Docker(dockerd)来启动容器。
- dockershim 阶段:后来出现了其他容器运行时(如 rkt、containerd),K8s 为了统一对接各种运行时,定义了 CRI(Container Runtime Interface,容器运行时接口)标准。但 Docker 当时没有实现 CRI 接口,K8s 只好在代码里专门维护一个叫 dockershim 的适配层,作为 K8s 和 Docker 之间的「翻译官」。
- K8s 1.20(2020 年):官方宣布 dockershim 进入弃用流程,推荐使用 containerd 等原生支持 CRI 的运行时。
- K8s 1.24(2022 年):正式移除 dockershim。此后 K8s 默认通过 containerd 来运行容器——而 containerd 本来就是 Docker 引擎内部的底层组件,Docker 自己在 2016 年把它拆出来捐给了 CNCF。

可以看到,变化只是 K8s 不再绕经 dockerd,而是直接调用 containerd,链路更短了。
这是容器圈流传最广的一个误解。准确的说法是:K8s 弃用的是 dockershim 这个适配层,而不是 Docker 这个工具,更不是 Docker 镜像。
- K8s 运行的镜像遵循 OCI(Open Container Initiative)标准,而
docker build构建出来的镜像天然就是 OCI 镜像。 - 所以用 Docker 构建的镜像照样能在 K8s 上正常跑,不需要任何改造。
- 日常开发中,你依然可以在本地用 Docker 写 Dockerfile、构建镜像、推到仓库,K8s 集群拉下来就能运行。
真正受影响的只有一类人:集群运维人员需要把节点的容器运行时从 dockerd 换成 containerd。对普通开发者来说,Docker 该怎么用还怎么用。
新手学习路径建议
对新手来说,顺序很重要,建议先 Docker,后 K8s:
- 先学好 Docker:理解镜像、容器、Volume、网络这几个核心概念,会写 Dockerfile,会用 Docker Compose 编排单机多容器。本系列前面的文章覆盖的就是这部分内容。
- Docker 熟练后再碰 K8s:K8s 的所有概念(Pod、Deployment、Service、PV/PVC)都建立在容器之上,没有 Docker 基础直接学 K8s,会被大量抽象概念淹没,学得很痛苦。
- 入门 K8s 从本地环境开始:不要一上来就折腾云上的多节点集群,先用 Docker Desktop 自带的 Kubernetes、minikube 或 kind 在本地起一个单节点集群,跟着官方教程把 Deployment 和 Service 跑通。
- 带着对照表学:学每个 K8s 概念时,回头想想它对应 Docker 里的什么(参考上面的概念对照表),用已知带动未知。
如果你的目标只是「把自己的小项目跑起来」,单机 Docker + Compose 往往就够了,不一定需要 K8s。K8s 解决的是规模化、高可用场景下的管理问题,项目没到那个体量时引入 K8s 反而是负担。按需学习即可。