Administrator
Published on 2026-01-08 / 5 Visits
0
0

Docker 安装时的三个“服务”: docker.service、docker.socket、containerd.service 到底在干什么?


很多人装 Docker 时,会看到系统里突然多了三个服务:
docker.servicedocker.socketcontainerd.service

有人会问:

  • 这三个都要不要装?

  • 能不能只起 docker.service?

  • containerd 是不是可以不要?

  • docker.socket 是干嘛的?

如果你没把这件事搞清楚,Docker 出问题时你一定不知道该从哪下手。


一、先给结论

正常安装 Docker:你只需要“安装 Docker”,不需要单独安装或手工启动这三个服务。

原因是:

  • docker.serviceDocker 主服务

  • containerd.serviceDocker 的底层运行时

  • docker.socketDocker 的按需启动入口

👉 它们是一个完整体系,不是三个独立组件。


二、Docker 的真实架构

Docker 并不是一个“单体程序”,而是一个分层架构

docker CLI
   │
   ▼
dockerd(docker.service)
   │
   ▼
containerd(containerd.service)
   │
   ▼
runc / OCI runtime

这 3 个 systemd 单元,对应的是 不同层级的职责


三、docker.service:Docker 的“大脑”

1️⃣ 它是什么?

docker.service

对应的进程是:

dockerd

它是 Docker Daemon(守护进程)


2️⃣ docker.service 主要干什么?

  • 接收 docker 命令(CLI)

  • 管理镜像(pull / build)

  • 管理容器生命周期(start / stop / restart)

  • 管理网络、volume、日志、plugin

  • 对外提供 Docker API(HTTP)

只要你在用 Docker,docker.service 一定在。


3️⃣ 没有 docker.service 会怎样?

docker ps
Cannot connect to the Docker daemon

👉 Docker 完全不可用


四、containerd.service:真正“跑容器”的人

1️⃣ 它是什么?

containerd.service

对应的进程是:

containerd

它是一个 通用的容器运行时(CNCF 项目)


2️⃣ containerd 在 Docker 里干什么?

  • 真正创建 / 启动 / 停止容器

  • 管理容器进程

  • 管理镜像 layer

  • 调用 runc 执行 OCI 容器

👉 dockerd 不直接跑容器,是 containerd 在跑。


3️⃣ containerd 和 Docker 是什么关系?

  • Docker 依赖 containerd

  • containerd 可以独立使用(Kubernetes 就是直接用它)

  • Docker 离不开 containerd

如果你停掉 containerd:

systemctl stop containerd

结果是:

  • Docker Daemon 可能还在

  • 容器全部起不来


4️⃣ containerd 需要你单独安装吗?

不需要

在现代 Docker(20.x 以后)中:

  • 安装 Docker 时

  • 会自动安装并管理 containerd

特点:

  • 没有 systemd unit

  • containerd 由 dockerd fork 出来

  • systemctl status containerd 必然不存在

不应该

  • 手工单独装一个 containerd

  • 自己改 containerd.service(除非你很清楚后果)


五、docker.socket:被误解最多的一个

1️⃣ 它是什么?

docker.socket

这是一个 systemd socket unit(套接字激活)


2️⃣ docker.socket 干什么用?

它监听:

/var/run/docker.sock

当发生以下情况之一:

  • 执行 docker ps

  • 有程序访问 Docker API

systemd 会:

  • 自动拉起 docker.service

  • 再把请求转交给 dockerd

👉 这叫“按需启动(socket activation)”。


3️⃣ docker.socket 存在 ≠ docker.service 已启动

你可能会看到:

docker.socket active
docker.service inactive

这是完全正常的

只要你一运行 docker ps

  • docker.service 就会被自动拉起


4️⃣ docker.socket 可以关掉吗?

可以,但要明确后果

systemctl disable docker.socket

后果:

  • docker.service 不再自动启动

  • 你必须手动 systemctl start docker

👉 在服务器/生产环境,一般保留 docker.socket


六、三者关系一句话总结(非常重要)

服务

角色

docker.service

Docker 的“控制中心”

containerd.service

真正“执行容器”的运行时

docker.socket

Docker 的“自动唤醒按钮”

关系是:

docker.socket → docker.service → containerd.service → runc

七、安装 Docker 时,正确的“认知与操作姿势”

✅ 正确做法

# 安装 docker-ce / docker.io
# 系统会自动安装并配置:
# - docker.service
# - docker.socket
# - containerd.service

你只需要关心:

systemctl status docker

❌ 错误做法(常见踩坑)

❌ 手工单独安装 containerd
❌ 停用 containerd 以为 Docker 还能跑
❌ 删除 docker.socket 但不手动启动 docker.service
❌ 把 docker.service 和 containerd.service 当成“可选组件”


八、在什么场景下,你才需要“单独关注”它们?

1️⃣ Docker 起不来

  • docker.service 日志

  • 再看 containerd.service

2️⃣ 容器起不来

  • containerd / runc 报错

3️⃣ Docker 被莫名自动拉起

  • 你启用了 docker.socket

4️⃣ Kubernetes / CRI 场景

  • 你可能 不用 docker.service

  • 但一定用 containerd.service


Docker 的运行依赖 docker.service、containerd.service 及 docker.socket 三个 systemd 单元,安装 Docker 时无需单独部署;其中 docker.service 提供控制平面,containerd.service 提供容器运行时能力,docker.socket 用于按需激活 Docker 服务。


九、runc又是什么

runc 是“真正创建并运行 Linux 容器进程”的最底层执行器。
Docker / containerd 都不直接跑容器,它们最终都是 调用 runc

官方身份

  • OCI Runtime Reference Implementation

  • CNCF(云原生计算基金会)项目

  • 原 Docker 核心代码拆分而来

用一句话概括

runc 把“普通 Linux 进程”放进“隔离的命名空间 + 受控的资源限制”里运行。


9.1、为什么一定要有 runc?

Linux 本身并没有“容器”这个概念,只有:

  • namespace(隔离)

  • cgroups(资源限制)

  • capabilities / seccomp(权限与系统调用控制)

runc 做的事就是:

  1. 根据配置(OCI spec)

  2. 创建 namespace(pid / net / mnt / ipc / uts / user)

  3. 应用 cgroups 限制(CPU / 内存 / IO)

  4. 设置安全策略(capabilities / seccomp)

  5. fork + exec 真正的容器进程

它是“把配置变成真实进程”的那一步。

实际上是:

docker CLI
   │
   ▼
dockerd          (管理、API、网络、镜像)
   │
   ▼
containerd       (容器生命周期管理)
   │
   ▼
runc              (真正创建容器进程)
   │
   ▼
Linux Kernel

组件

干什么

docker

给人用的

containerd

给系统用的

runc

给内核用的

9.2、runc 和 “容器 ≠ 虚拟机” 的关系

虚拟机

  • 有自己的内核

  • 通过 Hypervisor

容器(runc)

  • 共享宿主机内核

  • 本质是 受限的 Linux 进程

你在容器里看到的:

ps aux

其实就是宿主机上的进程,只是:

  • PID 被隔离

  • 文件系统被 chroot/mount

  • 资源被限制

runc 就是“制造这种错觉”的工具。

Docker 20.10.24 为例:

  • Docker 强依赖 containerd

  • containerd 强依赖 runc

  • 没有 runc:

container create failed: runtime create failed

常见报错关键词:

runc did not terminate successfully
failed to create shim task

runc 是“不可替代的最后一环”。

十、最后一句“工程化总结”

Docker 不是一个服务,而是一套协同工作的服务体系。
你只负责安装 Docker,剩下的交给 systemd。



Comment