Skip to content

Docker 引擎架构原理

Docker 引擎是容器技术的核心,理解其架构原理对于深入掌握 Docker 至关重要。本文将详细介绍 Docker 引擎的组件、工作流程和底层技术。

目录

  1. 架构概述
  2. 客户端-服务器架构
  3. Docker Daemon
  4. Containerd
  5. Runc
  6. 底层技术
  7. 工作流程

架构概述

1.1 Docker 引擎演进

Docker 引擎经历了多次架构演进:

Docker 架构演进:

v1.0 (2013)                    v1.11+ (2016+)
┌─────────────────┐            ┌─────────────────────────────────────┐
│   Docker CLI    │            │   Docker CLI                        │
└────────┬────────┘            └────────┬────────────────────────────┘
         │                              │
         │ REST API                     │ REST API
         ▼                              ▼
┌─────────────────┐            ┌─────────────────┐  ┌───────────────┐
│  Docker Daemon  │            │  Docker Daemon  │  │   containerd  │
│  (monolithic)   │            │  (lightweight)  │  │  (container   │
│                 │            │                 │  │   runtime)    │
│  ┌───────────┐  │            │  ┌───────────┐  │  │               │
│  │  Image    │  │            │  │   Image   │  │  │  ┌─────────┐  │
│  │  Mgmt     │  │     →      │  │   Mgmt    │  │  │  │  runc   │  │
│  ├───────────┤  │            │  ├───────────┤  │  │  │ (OCI    │  │
│  │ Container │  │            │  │  Network  │  │  │  │ runtime)│  │
│  │  Runtime  │  │            │  │   Mgmt    │  │  │  └─────────┘  │
│  ├───────────┤  │            │  ├───────────┤  │  │               │
│  │  Network  │  │            │  │  Volume   │  │  │               │
│  │   Mgmt    │  │            │  │   Mgmt    │  │  │               │
│  ├───────────┤  │            └─────────────────┘  └───────────────┘
│  │  Volume   │  │
│  │   Mgmt    │  │
│  └───────────┘  │
└─────────────────┘

1.2 当前架构组件

┌─────────────────────────────────────────────────────────────────────┐
│                         Docker 架构                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌──────────────┐      REST API       ┌──────────────────────────┐  │
│  │ Docker CLI   │ ◄─────────────────► │    Docker Daemon         │  │
│  │ docker       │      (Unix Socket   │    (dockerd)             │  │
│  │ docker-compose│      or TCP)       │                          │  │
│  └──────────────┘                     │  ┌────────────────────┐   │  │
│                                       │  │   Image Service    │   │  │
│  ┌──────────────┐                     │  │   - Pull/Push      │   │  │
│  │ Docker SDK   │ ◄─────────────────► │  │   - Build          │   │  │
│  │ (Go/Python/  │                     │  └────────────────────┘   │  │
│  │  Node.js...) │                     │  ┌────────────────────┐   │  │
│  └──────────────┘                     │  │   Network Service  │   │  │
│                                       │  │   - Create/Manage  │   │  │
│                                       │  └────────────────────┘   │  │
│                                       │  ┌────────────────────┐   │  │
│                                       │  │   Volume Service   │   │  │
│                                       │  │   - Create/Mount   │   │  │
│                                       │  └────────────────────┘   │  │
│                                       │                           │  │
│                                       └───────────┬───────────────┘  │
│                                                   │                  │
│                                                   │ gRPC             │
│                                                   ▼                  │
│                                       ┌──────────────────────────┐  │
│                                       │      containerd          │  │
│                                       │  (CNCF 毕业项目)          │  │
│                                       │                          │  │
│                                       │  ┌────────────────────┐   │  │
│                                       │  │   Image Service    │   │  │
│                                       │  │   - Store/Transfer │   │  │
│                                       │  └────────────────────┘   │  │
│                                       │  ┌────────────────────┐   │  │
│                                       │  │   Runtime Service  │   │  │
│                                       │  │   - Task Management│   │  │
│                                       │  └────────────────────┘   │  │
│                                       │                           │  │
│                                       └───────────┬───────────────┘  │
│                                                   │                  │
│                                                   │ OCI Runtime      │
│                                                   ▼                  │
│                                       ┌──────────────────────────┐  │
│                                       │         runc             │  │
│                                       │    (OCI 标准实现)         │  │
│                                       │                          │  │
│                                       │  - Namespace 创建        │  │
│                                       │  - Cgroups 配置          │  │
│                                       │  - 容器进程启动          │  │
│                                       └──────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

客户端-服务器架构

2.1 通信机制

bash
# Docker 客户端与守护进程通信方式

# 1. Unix Socket (默认,本地)
docker ps  # 使用 /var/run/docker.sock

# 2. TCP Socket (远程)
export DOCKER_HOST=tcp://192.168.1.100:2376
docker ps

# 3. SSH (Docker 18.09+)
export DOCKER_HOST=ssh://[email protected]
docker ps

2.2 REST API

bash
# 查看 API 版本
curl --unix-socket /var/run/docker.sock http://localhost/version

# 列出容器
curl --unix-socket /var/run/docker.sock http://localhost/containers/json

# 创建容器
curl -X POST \
  --unix-socket /var/run/docker.sock \
  -H "Content-Type: application/json" \
  -d '{
    "Image": "nginx:alpine",
    "HostConfig": {
      "PortBindings": {
        "80/tcp": [{"HostPort": "8080"}]
      }
    }
  }' \
  http://localhost/containers/create

2.3 API 版本管理

Docker 版本API 版本主要特性
24.0.x1.43BuildKit 默认
23.0.x1.42新构建系统
20.10.x1.41多平台构建
19.03.x1.40上下文支持

Docker Daemon

3.1 守护进程配置

bash
# 查看守护进程配置
cat /etc/docker/daemon.json

# 示例配置
{
  "debug": false,
  "log-level": "info",
  "storage-driver": "overlay2",
  "data-root": "/var/lib/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "live-restore": true,
  "userland-proxy": false,
  "experimental": false,
  "metrics-addr": "0.0.0.0:9323",
  "features": {
    "buildkit": true
  }
}

3.2 守护进程管理

bash
# 启动守护进程
sudo dockerd

# 使用 systemd 管理
sudo systemctl start docker
sudo systemctl stop docker
sudo systemctl restart docker

# 查看守护进程日志
sudo journalctl -u docker.service -f

# 重新加载配置
sudo systemctl reload docker
# 或
sudo kill -SIGHUP $(pidof dockerd)

3.3 守护进程安全

bash
# 启用 TLS
dockerd \
  --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=server-cert.pem \
  --tlskey=server-key.pem \
  -H=0.0.0.0:2376

# 客户端使用 TLS
docker --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=cert.pem \
  --tlskey=key.pem \
  -H=tcp://server:2376 version

Containerd

4.1 Containerd 架构

┌─────────────────────────────────────────────────────────────┐
│                      containerd                             │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                    API Layer                         │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │
│  │  │   Images    │  │  Content    │  │   Snapshots │  │   │
│  │  │   Service   │  │   Service   │  │   Service   │  │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │
│  │  │  Runtime    │  │    Task     │  │   Events    │  │   │
│  │  │   Service   │  │   Service   │  │   Service   │  │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
│                           │                                  │
│                           ▼                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                   Core Layer                         │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │
│  │  │   Metadata  │  │    GC       │  │  Runtime    │  │   │
│  │  │   (BoltDB)  │  │  (垃圾回收)  │  │  (Shim)     │  │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
│                           │                                  │
│                           ▼                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                  Backend Layer                       │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │
│  │  │  Snapshotter│  │    Content  │  │   Diff      │  │   │
│  │  │  (overlayfs)│  │    Store    │  │   Service   │  │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

4.2 Containerd CLI (ctr)

bash
# 查看 containerd 版本
ctr version

# 查看命名空间
ctr namespace ls

# 查看镜像
ctr -n default images ls

# 拉取镜像
ctr -n default images pull docker.io/library/nginx:alpine

# 运行容器
ctr -n default run --rm docker.io/library/nginx:alpine web

# 查看容器
ctr -n default containers ls

# 查看任务(运行的容器)
ctr -n default tasks ls

4.3 Containerd 与 Docker 的关系

Docker 调用 containerd 的流程:

1. docker run nginx:alpine


2. Docker Daemon (dockerd)
   - 解析命令
   - 检查镜像


3. containerd (通过 gRPC)
   - 拉取镜像(如果需要)
   - 创建容器元数据
   - 调用 runc


4. runc (OCI Runtime)
   - 创建 namespace
   - 配置 cgroups
   - 启动容器进程


5. 容器进程运行

Runc

5.1 OCI 标准

OCI(Open Container Initiative)定义了容器运行时标准:

OCI 规范:
┌─────────────────────────────────────────┐
│  runtime-spec: 运行时规范                │
│  - 容器生命周期管理                       │
│  - 配置文件格式 (config.json)            │
│  - 操作接口(create/start/kill/delete)  │
├─────────────────────────────────────────┤
│  image-spec: 镜像规范                    │
│  - 镜像格式                              │
│  - 文件系统层                            │
│  - 配置清单 (manifest)                   │
└─────────────────────────────────────────┘

5.2 runc 使用

bash
# 创建容器根文件系统
mkdir -p /tmp/mycontainer/rootfs
docker export $(docker create busybox) | tar -C /tmp/mycontainer/rootfs -xvf -

# 生成配置
runc spec --rootless

# 运行容器
cd /tmp/mycontainer
runc run mycontainer-id

# 其他命令
runc list                    # 列出容器
runc state mycontainer-id    # 查看状态
runc kill mycontainer-id 9   # 发送信号
runc delete mycontainer-id   # 删除容器

5.3 容器配置示例

json
{
  "ociVersion": "1.0.2-dev",
  "process": {
    "terminal": false,
    "user": {
      "uid": 0,
      "gid": 0
    },
    "args": [
      "sh"
    ],
    "env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
      "TERM=xterm"
    ],
    "cwd": "/",
    "capabilities": {
      "bounding": ["CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE"],
      "effective": ["CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE"],
      "inheritable": ["CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE"],
      "permitted": ["CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE"],
      "ambient": ["CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE"]
    },
    "rlimits": [
      {
        "type": "RLIMIT_NOFILE",
        "hard": 1024,
        "soft": 1024
      }
    ],
    "noNewPrivileges": true
  },
  "root": {
    "path": "rootfs",
    "readonly": true
  },
  "hostname": "runc",
  "mounts": [
    {
      "destination": "/proc",
      "type": "proc",
      "source": "proc"
    },
    {
      "destination": "/dev",
      "type": "tmpfs",
      "source": "tmpfs",
      "options": ["nosuid", "strictatime", "mode=755", "size=65536k"]
    }
  ],
  "linux": {
    "namespaces": [
      {"type": "pid"},
      {"type": "network"},
      {"type": "ipc"},
      {"type": "uts"},
      {"type": "mount"},
      {"type": "cgroup"}
    ],
    "cgroupsPath": "runc-mycontainer",
    "resources": {
      "memory": {
        "limit": 536870912,
        "swap": 536870912
      },
      "cpu": {
        "shares": 1024,
        "quota": 100000,
        "period": 100000
      }
    }
  }
}

底层技术

6.1 Linux Namespace

Namespace 提供了进程隔离:

Namespace隔离资源系统调用内核版本
PID进程 IDCLONE_NEWPID2.6.24
Network网络设备、端口CLONE_NEWNET2.6.29
IPC信号量、消息队列CLONE_NEWIPC2.6.19
Mount挂载点CLONE_NEWNS2.4.19
UTS主机名、域名CLONE_NEWUTS2.6.19
User用户和组 IDCLONE_NEWUSER3.8
CgroupCgroup 根目录CLONE_NEWCGROUP4.6
bash
# 查看进程的 namespace
ls -la /proc/self/ns/

# 进入指定 namespace
nsenter -t <pid> -n ip addr

# 创建新 namespace
unshare --pid --fork --mount-proc /bin/bash

6.2 Cgroups

Cgroups(Control Groups)用于资源限制:

bash
# 查看 cgroup 挂载
mount | grep cgroup

# v1 版本
ls /sys/fs/cgroup/
# cpu memory blkio devices

# v2 版本 (统一层次)
ls /sys/fs/cgroup/
# cgroup.controllers cgroup.max.depth memory.stat

# 查看容器的 cgroup
docker inspect <container> --format='{{ .HostConfig.Cgroup }}'

# 手动创建 cgroup (v1)
sudo mkdir /sys/fs/cgroup/memory/mygroup
echo 100000000 | sudo tee /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
echo $$ | sudo tee /sys/fs/cgroup/memory/mygroup/cgroup.procs

6.3 Union 文件系统

Union 文件系统结构:

┌─────────────────────────────────────────┐
│           容器层 (读写层)                │
│  ┌─────────────────────────────────┐   │
│  │ 新增/修改的文件                   │   │
│  └─────────────────────────────────┘   │
├─────────────────────────────────────────┤
│           镜像层 (只读层)                │
│  ┌─────────────────────────────────┐   │
│  │ 镜像文件系统层 1                  │   │
│  ├─────────────────────────────────┤   │
│  │ 镜像文件系统层 2                  │   │
│  ├─────────────────────────────────┤   │
│  │ 基础镜像层                        │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

支持的存储驱动:

驱动说明优点缺点
overlay2推荐性能好、成熟需要 Linux 4.0+
aufs旧版 Ubuntu 默认成熟未进入主线内核
devicemapperRHEL/CentOS块级操作性能一般
btrfs需要 btrfs快照支持需要特定文件系统
zfs需要 zfs高级特性需要特定文件系统

6.4 容器网络

容器网络架构:

┌─────────────────────────────────────────┐
│              容器网络                    │
├─────────────────────────────────────────┤
│  ┌─────────────────────────────────┐   │
│  │         Docker0 (网桥)           │   │
│  │    172.17.0.1/16                │   │
│  └─────────────┬───────────────────┘   │
│                │                        │
│    ┌───────────┼───────────┐           │
│    │           │           │           │
│    ▼           ▼           ▼           │
│ ┌──────┐   ┌──────┐   ┌──────┐        │
│ │veth0 │   │veth1 │   │veth2 │        │
│ └──┬───┘   └──┬───┘   └──┬───┘        │
│    │          │          │            │
│ ┌──┴───┐   ┌──┴───┐   ┌──┴───┐        │
│ │Container│  │Container│  │Container│        │
│ │172.17.0.2│  │172.17.0.3│  │172.17.0.4│        │
│ └────────┘   └────────┘   └────────┘        │
└─────────────────────────────────────────┘

工作流程

7.1 docker run 完整流程

docker run 执行流程:

1. 解析命令行参数
   docker run -d --name web -p 80:80 nginx:alpine


2. 客户端发送 REST API 请求
   POST /containers/create
   POST /containers/{id}/start


3. Docker Daemon 处理
   ├─ 检查镜像是否存在
   ├─ 如不存在,调用 containerd 拉取镜像
   ├─ 创建容器配置
   └─ 调用 containerd 创建容器


4. containerd 处理
   ├─ 存储容器元数据
   ├─ 准备 rootfs(联合挂载)
   ├─ 创建 shim 进程
   └─ 调用 runc 启动容器


5. runc 处理
   ├─ 创建 namespace
   ├─ 配置 cgroups
   ├─ 设置 capabilities
   └─ exec 容器进程


6. 容器进程运行
   ├─ 执行 entrypoint/cmd
   ├─ shim 作为父进程监控
   └─ containerd 管理生命周期

7.2 镜像构建流程

docker build 执行流程:

1. 发送构建上下文到 Daemon


2. 解析 Dockerfile
   ├─ 逐行解析指令
   └─ 构建依赖图


3. 执行构建指令
   ├─ FROM: 拉取基础镜像
   ├─ RUN: 创建临时容器执行命令
   ├─ COPY/ADD: 复制文件到临时容器
   ├─ 提交临时容器为新镜像层
   └─ 重复直到所有指令完成


4. 输出最终镜像
   ├─ 创建镜像配置
   ├─ 计算镜像 digest
   └─ 存储到本地

7.3 性能优化

bash
# 1. 使用 BuildKit 加速构建
export DOCKER_BUILDKIT=1

# 2. 并行构建
docker build --parallel .

# 3. 使用缓存挂载
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt

# 4. 优化构建上下文
echo 'node_modules' >> .dockerignore

# 5. 使用多阶段构建
# 参考多阶段构建文档

下一步

基于 MIT 许可发布