2Docker 深度探索

Docker 引擎

Docker 的架构

Docker 引擎守护进程CLI

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第2章:Docker引擎(The Docker Engine)

一、导读

1.1 本章学习目标

本章深入 Docker 引擎的内部架构。你将理解 Docker 的 Client-Server 模型、各组件的职责分工、以及 Docker 对象模型。

本章的核心学习目标包括:

  • 理解 Docker 的分层架构:CLI → Daemon → containerd → runc。
  • 掌握各组件的职责:dockerd、containerd、runc 各自做什么。
  • 了解 Docker 对象模型:镜像、容器、网络、卷、插件。
  • 学会使用 Docker API:通过 REST API 直接操作 Docker。
  • 掌握 Docker Daemon 的配置:daemon.json 的配置选项。

1.2 为什么本章如此重要

理解 Docker 引擎的架构,你才能:

  • 排查容器运行问题
  • 优化 Docker 性能
  • 理解 Kubernetes 为什么从 Docker 迁移到 containerd
  • 通过 API 自动化 Docker 操作

1.3 核心问题引导

Docker CLI 和 Docker Daemon 如何通信?

containerd 和 Docker Daemon 的区别是什么?

runc 的作用是什么?它如何创建容器?

Docker 的 REST API 可以直接调用吗?

daemon.json 中可以配置哪些选项?


二、核心概念详解

2.1 Docker 架构

┌──────────────┐
│  Docker CLI  │  用户接口
└──────┬───────┘
       │ REST API (HTTP/JSON)
┌──────▼───────┐
│  dockerd     │  Docker Daemon,管理 Docker 对象
└──────┬───────┘
       │ gRPC
┌──────▼───────┐
│ containerd   │  容器生命周期管理
└──────┬───────┘
       │ OCI Runtime Spec
┌──────▼───────┐
│    runc      │  创建和运行容器
└──────┬───────┘
       │ Linux Kernel APIs
┌──────▼───────┐
│   Kernel     │  Namespace + Cgroups + UnionFS
└──────────────┘

2.2 Docker Daemon(dockerd)

Docker Daemon 是 Docker 的核心守护进程,负责:

  • 管理 Docker 对象(镜像、容器、网络、卷)
  • 处理 API 请求
  • 构建镜像
  • 管理容器生命周期(通过 containerd)
bash
# 查看 dockerd 状态
systemctl status docker

# 查看 dockerd 日志
journalctl -u docker -f

2.3 containerd

containerd 从 Docker 中剥离,专注于容器生命周期管理。它是 CNCF 毕业项目,被 Kubernetes 直接采用。

bash
# containerd 的职责
# - 管理容器生命周期(创建、启动、停止、删除)
# - 管理镜像(拉取、存储)
# - 管理网络和存储
# - 提供 gRPC API

2.4 runc

runc 是 OCI 标准的容器运行时实现。它的唯一职责:根据 OCI 规范创建和运行容器。

bash
# runc 的工作
# 1. 创建容器的 Namespace 和 Cgroup
# 2. 设置容器的文件系统(UnionFS)
# 3. 启动容器进程
# 4. 将容器进程的管理权交给 containerd

2.5 Docker 对象

  • Images:只读模板,用于创建容器
  • Containers:镜像的运行实例
  • Networks:容器间的通信网络
  • Volumes:持久化存储
  • Plugins:扩展 Docker 功能

2.6 Docker API

bash
# 通过 Unix Socket 调用 API
curl --unix-socket /var/run/docker.sock \
  http://localhost/v1.41/containers/json

# 通过 TCP 调用(需配置 TLS)
curl -H "Content-Type: application/json" \
  https://192.168.1.100:2376/v1.41/containers/json \
  --cert client.pem --key client-key.pem

2.7 Docker Daemon 配置

json
// /etc/docker/daemon.json
{
  "registry-mirrors": ["https://mirror.example.com"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "default-address-pools": [
    {"base": "172.80.0.0/16", "size": 24}
  ],
  "live-restore": true
}

三、实战案例

3.1 使用 API 操作 Docker

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

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

# 启动容器
curl --unix-socket /var/run/docker.sock \
  -X POST \
  http://localhost/v1.41/containers/my-nginx/start

3.2 配置 Docker Daemon

bash
# 修改 daemon.json
sudo tee /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"},
  "storage-driver": "overlay2"
}
EOF

# 重启 Docker
sudo systemctl restart docker

# 验证配置
docker info

四、本章小结

Docker 采用分层架构:CLI → Daemon → containerd → runc。

containerd 专注于容器生命周期,是 K8s 推荐的运行时。

runc 只负责创建容器,是 OCI 标准的实现。

Docker API 可以通过 HTTP 直接操作 Docker。

daemon.json 配置镜像加速、日志轮转、存储驱动等。


五、思考与练习

思考题

为什么 Docker 要将 containerd 从 Daemon 中剥离?

Kubernetes 为什么从 Docker 迁移到 containerd?

Docker API 的安全性如何保证?如何防止未授权访问?

练习题

使用 curl 调用 Docker API 列出容器和镜像。

配置 daemon.json 添加镜像加速和日志轮转。

使用 docker system df 查看磁盘占用,用 docker system prune 清理。

2/8Dock
0%