Docker 引擎架构原理
Docker 引擎是容器技术的核心,理解其架构原理对于深入掌握 Docker 至关重要。本文将详细介绍 Docker 引擎的组件、工作流程和底层技术。
目录
架构概述
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 ps2.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/create2.3 API 版本管理
| Docker 版本 | API 版本 | 主要特性 |
|---|---|---|
| 24.0.x | 1.43 | BuildKit 默认 |
| 23.0.x | 1.42 | 新构建系统 |
| 20.10.x | 1.41 | 多平台构建 |
| 19.03.x | 1.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 versionContainerd
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 ls4.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 | 进程 ID | CLONE_NEWPID | 2.6.24 |
| Network | 网络设备、端口 | CLONE_NEWNET | 2.6.29 |
| IPC | 信号量、消息队列 | CLONE_NEWIPC | 2.6.19 |
| Mount | 挂载点 | CLONE_NEWNS | 2.4.19 |
| UTS | 主机名、域名 | CLONE_NEWUTS | 2.6.19 |
| User | 用户和组 ID | CLONE_NEWUSER | 3.8 |
| Cgroup | Cgroup 根目录 | CLONE_NEWCGROUP | 4.6 |
bash
# 查看进程的 namespace
ls -la /proc/self/ns/
# 进入指定 namespace
nsenter -t <pid> -n ip addr
# 创建新 namespace
unshare --pid --fork --mount-proc /bin/bash6.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.procs6.3 Union 文件系统
Union 文件系统结构:
┌─────────────────────────────────────────┐
│ 容器层 (读写层) │
│ ┌─────────────────────────────────┐ │
│ │ 新增/修改的文件 │ │
│ └─────────────────────────────────┘ │
├─────────────────────────────────────────┤
│ 镜像层 (只读层) │
│ ┌─────────────────────────────────┐ │
│ │ 镜像文件系统层 1 │ │
│ ├─────────────────────────────────┤ │
│ │ 镜像文件系统层 2 │ │
│ ├─────────────────────────────────┤ │
│ │ 基础镜像层 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘支持的存储驱动:
| 驱动 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| overlay2 | 推荐 | 性能好、成熟 | 需要 Linux 4.0+ |
| aufs | 旧版 Ubuntu 默认 | 成熟 | 未进入主线内核 |
| devicemapper | RHEL/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. 使用多阶段构建
# 参考多阶段构建文档下一步
- 学习 Docker CLI 命令参考
- 了解 Docker 配置管理
- 掌握 Docker API 参考
- 深入 镜像构建最佳实践