Docker 容器与 Kubernetes 是什么关系?
Docker 容器和 Kubernetes 不是替代关系。Docker 更像开发者打包、构建、运行容器的一套工具,Kubernetes 是在一组机器上管理容器的编排系统。生产集群里,Kubernetes 通常不会直接调用 Docker CLI,而是通过 CRI 调用 containerd、CRI-O 这类运行时,再由 runc 创建真正的 Linux 容器进程。
还有一个容易误解的点:Kubernetes 不再内置 dockershim,不等于 Docker 镜像不能用了。Docker 构建出的镜像只要符合 OCI 标准,containerd 和 CRI-O 仍然可以正常拉取、运行。
Docker 负责什么?
日常说 Docker,通常混着指几件事:
- Docker CLI / Dockerfile / BuildKit:写 Dockerfile、构建镜像、推送到镜像仓库;
- Docker Engine:在本机管理容器的守护进程;
- containerd / runc:拉取镜像、管理容器生命周期、创建容器进程的底层组件。
本地开发时,Docker Desktop 或 Docker Engine 很方便。一个 docker build 生成镜像,一个 docker run 就能验证服务能不能跑起来。它主要解决的是“怎么把应用和依赖打成一个可迁移的包”。
Kubernetes 负责什么?
Kubernetes 关心的是另一层问题:当容器不只一个,而是跑在几十台、几百台机器上时,谁来决定它们放在哪台机器?挂了谁来拉起?流量怎么进来?副本怎么扩容?
这些才是 Kubernetes 的核心职责:
- 调度:根据资源、亲和性、污点等规则把 Pod 放到合适节点;
- 自愈:容器或节点异常时重新创建 Pod;
- 扩缩容:按副本数或指标调整服务规模;
- 服务发现与负载均衡:用 Service、Ingress 等把流量导向后端 Pod;
- 配置与发布管理:配合 ConfigMap、Secret、Deployment 做滚动发布和回滚。
所以,Docker 解决的是“怎么把应用装进容器并运行”,Kubernetes 解决的是“怎么在集群里可靠地管理大量容器”。
Docker 和 Kubernetes 怎么衔接?
Kubernetes 不会直接执行 docker run。它通过 CRI(Container Runtime Interface) 和节点上的容器运行时通信。常见运行时是 containerd 和 CRI-O。运行时再调用更底层的 runc 创建容器进程。
早期 Kubernetes 为了兼容 Docker Engine,内置过一个 dockershim 适配层。Kubernetes v1.20 开始弃用 dockershim,v1.24 正式移除。移除的是内置 Docker Engine 适配层,不是 Docker 镜像格式。
现在大多数新集群会直接使用 containerd。Docker Engine 本身不是 CRI 运行时;如果确实要让 Kubernetes 继续对接 Docker Engine,需要额外安装 cri-dockerd 来做适配。
实际项目里怎么分工?
常见流程是:
- 开发者写 Dockerfile;
- 用 Docker CLI 或 CI 中的 BuildKit 构建镜像;
- 把镜像推到镜像仓库;
- Kubernetes 从仓库拉取镜像;
- 节点上的 containerd 运行容器;
- Kubernetes 负责调度、扩容、重启和对外暴露服务。
本地开发继续用 Docker 很正常,因为它简单、反馈快。生产环境通常把 Docker 的“构建镜像”能力留在开发机或 CI,把“运行和编排”交给 Kubernetes + containerd。这样分工更清楚,也更符合现在 Kubernetes 集群的主流做法。