6月19日 18:55

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) 和节点上的容器运行时通信。常见运行时是 containerdCRI-O。运行时再调用更底层的 runc 创建容器进程。

早期 Kubernetes 为了兼容 Docker Engine,内置过一个 dockershim 适配层。Kubernetes v1.20 开始弃用 dockershim,v1.24 正式移除。移除的是内置 Docker Engine 适配层,不是 Docker 镜像格式。

现在大多数新集群会直接使用 containerd。Docker Engine 本身不是 CRI 运行时;如果确实要让 Kubernetes 继续对接 Docker Engine,需要额外安装 cri-dockerd 来做适配。

实际项目里怎么分工?

常见流程是:

  1. 开发者写 Dockerfile;
  2. 用 Docker CLI 或 CI 中的 BuildKit 构建镜像;
  3. 把镜像推到镜像仓库;
  4. Kubernetes 从仓库拉取镜像;
  5. 节点上的 containerd 运行容器;
  6. Kubernetes 负责调度、扩容、重启和对外暴露服务。

本地开发继续用 Docker 很正常,因为它简单、反馈快。生产环境通常把 Docker 的“构建镜像”能力留在开发机或 CI,把“运行和编排”交给 Kubernetes + containerd。这样分工更清楚,也更符合现在 Kubernetes 集群的主流做法。

标签:Docker