在 Docker 容器中控制宿主机 Docker:DoD 与 DinD 的技术原理解析

在构建 CI/CD 平台、发布系统或容器管理工具时,经常会看到如下配置:

plain 复制代码
volumes:
  - /var/run/docker.sock:/var/run/docker.sock

这个配置看似简单,却涉及 Docker 的核心通信机制。本文从底层原理出发,系统梳理:

  • docker.sock 的作用
  • 容器如何控制宿主机 Docker
  • CLI 与 SDK 两种调用方式的区别
  • DoD 与 DinD 架构差异
  • 生产环境需要关注的安全问题

一、docker.sock 的本质

在 Linux 系统中,Docker Daemon 通过 Unix Socket 提供 API 服务:

plain 复制代码
/var/run/docker.sock

Docker CLI(docker 命令)并不直接管理容器,它只是一个客户端工具。

当执行:

plain 复制代码
docker ps

实际发生的是:

plain 复制代码
docker CLI
    ↓
/var/run/docker.sock
    ↓
Docker Daemon
    ↓
返回容器列表

也就是说,真正执行容器操作的是 Docker Daemon,而 CLI 只是 API 调用者。


二、容器挂载 docker.sock 后发生了什么?

当在容器中挂载:

plain 复制代码
- /var/run/docker.sock:/var/run/docker.sock

意味着容器内部也可以访问宿主机的 Docker API。

此时,在容器内执行:

plain 复制代码
docker ps

控制的仍然是宿主机的 Docker Daemon,而不是容器内部的 Docker。

这也是很多发布平台和容器管理工具的实现方式。


三、两种常见调用方式

1️⃣ 通过 Docker CLI

示例:

plain 复制代码
import { exec } from "child_process";

exec("docker ps", (err, stdout) => {
  console.log(stdout);
});

特点:

  • 需要在容器中安装 docker-cli
  • 本质仍然是 CLI 调用 docker.sock
  • 错误处理依赖字符串解析

调用链:

plain 复制代码
Agent
   ↓
docker CLI
   ↓
/var/run/docker.sock
   ↓
Docker Daemon

2️⃣ 通过 Docker SDK(如 dockerode)

示例:

plain 复制代码
import Docker from "dockerode";

const docker = new Docker({
  socketPath: "/var/run/docker.sock",
});

const containers = await docker.listContainers();

调用链:

plain 复制代码
Agent
   ↓
Docker SDK
   ↓
/var/run/docker.sock
   ↓
Docker Daemon

对比:

维度 CLI 方式 SDK 方式
是否需要 docker-cli
调用方式 shell HTTP API
错误处理 字符串 JSON
日志流支持 复杂 原生支持
可扩展性 一般

两种方式最终控制的都是宿主机 Docker,差异仅在调用层。


四、DoD 与 DinD 的区别

Docker outside of Docker(DoD)

特点:

  • 容器内部没有 Docker Daemon
  • 通过挂载 docker.sock 控制宿主机 Docker
  • 资源消耗低
  • 启动速度快

架构模型:

plain 复制代码
Container (Agent)
       ↓
/var/run/docker.sock
       ↓
Host Docker Daemon

常见于:

  • Portainer
  • Watchtower

Docker in Docker(DinD)

特点:

  • 容器内部运行独立 Docker Daemon
  • 通常需要 privileged 模式
  • 适用于 CI 构建隔离环境

架构模型:

plain 复制代码
Container
   ↓
Docker Daemon(容器内部)
   ↓
子容器

常见于:

  • GitLab CI
  • Jenkins

五、安全风险分析

挂载 docker.sock 等价于授予容器对宿主机 Docker 的完全控制权。

通过 Docker API 可以:

  • 启动特权容器
  • 挂载宿主机目录
  • 修改网络配置
  • 删除任意容器

一旦容器被入侵,宿主机安全将受到影响。

常见缓解方式:

  • 不暴露 Agent 至公网
  • 使用内网通信
  • 使用强认证 Token
  • 尽量使用 SDK 而非 shell 执行

六、核心结论

  1. docker.sock 是 Docker Daemon 的通信入口
  2. 挂载 docker.sock 后,容器可以直接控制宿主机 Docker
  3. CLI 与 SDK 本质相同,区别在调用方式
  4. DoD 是生产环境常见方案
  5. DinD 适用于需要隔离 Docker 环境的场景

理解 docker.sock 的通信模型,有助于在设计 CI/CD 或容器管理系统时做出正确的架构选择。

相关推荐
杨浦老苏1 小时前
开源多用户图书追踪系统LibrisLog
docker·群晖·收藏管理
赵渝强老师3 小时前
【赵渝强老师】Kubernetes(K8s)中的金丝雀升级
linux·docker·云原生·容器·kubernetes
鹤落晴春3 小时前
【K8s】配置存储卷
云原生·容器·kubernetes
我叫张小白。4 小时前
CentOS 7 安装 Docker并配置镜像加速(完整指南)
linux·docker·centos
原来是猿6 小时前
Docker 【 技术架构(1)】
docker·容器·架构
ba_pi6 小时前
k8s删除pod
linux·容器·kubernetes
木雷坞6 小时前
Qdrant Docker 部署教程:数据卷、API Key 和集合初始化
运维·docker·容器·知识图谱
梦梦代码精6 小时前
为什么这个开源的AI平台会火?有点东西。。。
人工智能·算法·机器学习·docker·开源
Lv_沐曦7 小时前
银河麒麟桌面版安装、多屏配置、触摸校准
运维·docker·samba·vsftpd·银河麒麟·触控校准·多屏配置
浩风祭月8 小时前
一个开发者的“看门狗”:我把服务器监控从被动告警变成了主动预防
后端·docker