docker-01-daemon
模块概览
模块定位与职责
职责边界
daemon 模块是 dockerd 的核心协调层,负责:
-
全局状态管理:
- 容器注册表(运行中/停止的容器列表)
- 镜像服务引用
- 网络控制器
- 卷服务
-
组件生命周期协调:
- 初始化所有子系统(containerd、libnetwork、插件、镜像服务)
- 协调容器启动/停止时多个子系统的调用顺序
- 优雅关闭(Shutdown)时的资源清理
-
配置管理与热加载:
- 加载并验证 daemon.json 配置
- 支持部分配置项的运行时热加载(如日志级别、镜像仓库镜像)
- 配置快照(atomic.Pointer)保证并发安全
-
事件总线:
- 广播容器/镜像/网络/卷的生命周期事件
- 支持客户端订阅事件流(
docker events)
-
系统信息收集:
- 系统资源信息(CPU/内存/存储)
- 运行时信息(容器数量、镜像数量)
- 插件列表
上下游依赖
上游调用方:
- API Router 层:通过 Backend 接口调用 daemon 方法
下游被依赖方:
- containerd 客户端:容器运行时操作
- libnetwork Controller:网络管理
- VolumeService:卷管理
- ImageService:镜像拉取/推送/构建
- PluginManager:插件启用/禁用
生命周期
stateDiagram-v2
[*] --> Initializing: NewDaemon()
Initializing --> LoadingConfig: 验证配置
LoadingConfig --> ConnectingContainerd: 连接 containerd
ConnectingContainerd --> InitPlugins: 初始化插件系统
InitPlugins --> InitVolumes: 初始化卷服务
InitVolumes --> LoadContainers: 加载已存在容器
LoadContainers --> InitGraphDriver: 初始化存储驱动
InitGraphDriver --> InitImageService: 初始化镜像服务
InitImageService --> InitNetwork: 初始化网络控制器
InitNetwork --> RestoreContainers: 恢复容器状态
RestoreContainers --> Running: 守护进程就绪
Running --> Reloading: 收到 SIGHUP
Reloading --> Running: 热加载完成
Running --> ShuttingDown: 收到 SIGTERM/SIGINT
ShuttingDown --> CleaningUp: 停止所有容器
CleaningUp --> [*]: Daemon 退出
状态说明:
- Initializing:验证系统要求(cgroup、内核版本等)
- LoadingConfig:加载 daemon.json、命令行参数合并
- ConnectingContainerd:建立 gRPC 连接到 containerd.sock
- InitPlugins:扫描插件目录、启动已启用插件
- InitVolumes:初始化内置 local 驱动、加载卷元数据
- LoadContainers:从磁盘读取容器配置文件
- InitGraphDriver:选择存储驱动(overlay2/aufs/devicemapper)
- InitImageService:连接到 containerd 的镜像服务
- InitNetwork:创建 libnetwork Controller、恢复网络端点
- RestoreContainers:重新连接到运行中的容器(live-restore 模式)
- Running:处理 API 请求
- ShuttingDown:关闭监听器、停止接受新请求
- CleaningUp:关闭 containerd 连接、清理临时文件
模块架构图
flowchart TB
subgraph DaemonCore["Daemon 核心"]
Daemon[Daemon 实例]
ConfigStore[配置存储<br/>atomic.Pointer]
EventService[事件服务<br/>EventsService]
ContainerStore[容器注册表<br/>container.Store]
ExecStore[Exec 命令存储<br/>ExecStore]
end
subgraph Services["服务组件"]
ImageSvc[镜像服务<br/>ImageService]
VolumeSvc[卷服务<br/>VolumesService]
PluginMgr[插件管理器<br/>PluginManager]
NetworkCtrl[网络控制器<br/>libnetwork.Controller]
RegistrySvc[注册表服务<br/>registry.Service]
end
subgraph Runtime["运行时层"]
ContainerdClient[containerd 客户端]
GraphDriver[存储驱动<br/>overlay2/aufs/...]
LibcontainerdClient[libcontainerd 客户端]
end
subgraph Storage["持久化"]
BoltDB[(BoltDB<br/>容器元数据)]
FileSystem[(文件系统<br/>/var/lib/docker)]
end
Daemon --> ConfigStore
Daemon --> EventService
Daemon --> ContainerStore
Daemon --> ExecStore
Daemon --> ImageSvc
Daemon --> VolumeSvc
Daemon --> PluginMgr
Daemon --> NetworkCtrl
Daemon --> RegistrySvc
ImageSvc --> ContainerdClient
ImageSvc --> GraphDriver
Daemon --> LibcontainerdClient
LibcontainerdClient --> ContainerdClient
ContainerStore --> BoltDB
ImageSvc --> FileSystem
VolumeSvc --> FileSystem
架构说明
1. Daemon 核心层:
- Daemon 实例:单例对象,持有所有子系统的引用
- 配置存储:使用
atomic.Pointer[configStore]实现无锁读取,热加载时原子替换指针 - 事件服务:发布/订阅模式,多个订阅者可并发接收事件
- 容器注册表:内存索引 + BoltDB 持久化,支持按 ID/Name 快速查找
- Exec 命令存储:记录所有
docker exec会话,支持重新连接
2. 服务组件层:
- 镜像服务:封装 containerd 的镜像 API,提供拉取/推送/构建接口
- 卷服务:管理本地卷和插件卷,处理挂载点
- 插件管理器:扫描插件目录、管理插件生命周期、提供插件发现接口
- 网络控制器:libnetwork 的 Controller 实例,管理网络和端点
- 注册表服务:解析镜像引用、认证、与 Registry V2 通信
3. 运行时层:
- containerd 客户端:gRPC 客户端,连接到
/run/containerd/containerd.sock - 存储驱动:抽象层,支持多种联合文件系统(overlay2 性能最佳)
- libcontainerd 客户端:封装 containerd 客户端,提供更高级的容器操作
4. 持久化层:
- BoltDB:存储容器视图(快速列表查询)、网络端点、镜像引用
- 文件系统:存储容器配置(JSON)、日志文件、卷数据、镜像层
初始化流程时序图
sequenceDiagram
autonumber
participant Main as cmd/dockerd/main
participant Command as daemon/command
participant Daemon as daemon.Daemon
participant Containerd as containerd Client
participant Plugin as PluginManager
participant Volume as VolumeService
participant Image as ImageService
participant Network as libnetwork
Main->>Command: NewDaemonRunner()
Main->>Command: Run(ctx)
Command->>Command: 解析配置文件 daemon.json
Command->>Command: 创建监听器(Unix Socket/TCP)
Note over Command: 初始化插件存储
Command->>Plugin: NewStore(pluginsRoot)
Note over Command: 初始化 Daemon
Command->>Daemon: NewDaemon(config, pluginStore)
Note over Daemon: 1. 平台检查
Daemon->>Daemon: checkSystem()
Daemon->>Daemon: verifyDaemonSettings()
Note over Daemon: 2. 用户命名空间
Daemon->>Daemon: setupRemappedRoot()
Note over Daemon: 3. 连接 containerd
Daemon->>Containerd: containerd.New(address)
Containerd-->>Daemon: Client 实例
Note over Daemon: 4. 初始化插件管理器
Daemon->>Plugin: NewManager(config)
Plugin->>Plugin: 扫描插件目录
Plugin->>Plugin: 启动已启用插件
Plugin-->>Daemon: PluginManager 实例
Note over Daemon: 5. 初始化卷服务
Daemon->>Volume: NewVolumeService(root, pluginStore)
Volume->>Volume: 初始化 local 驱动
Volume->>Volume: 加载卷元数据
Volume-->>Daemon: VolumeService 实例
Note over Daemon: 6. 容器存储初始化
Daemon->>Daemon: container.NewMemoryStore()
Daemon->>Daemon: container.NewViewDB()
Note over Daemon: 7. 加载已存在容器
Daemon->>Daemon: loadContainers(ctx)
loop 遍历容器目录
Daemon->>Daemon: 读取 config.v2.json
Daemon->>Daemon: 解析容器配置
Daemon->>Daemon: 注册到 ContainerStore
end
Note over Daemon: 8. 初始化存储驱动
Daemon->>Daemon: graphdriver.New(driver, root)
alt driver == overlay2
Daemon->>Daemon: 检查内核支持
Daemon->>Daemon: 挂载 overlay2
else driver == aufs
Daemon->>Daemon: 加载 aufs 模块
end
Note over Daemon: 9. 初始化镜像服务
Daemon->>Image: NewImageService(config)
Image->>Containerd: 连接镜像服务 API
Image->>Image: 初始化 LayerStore
Image->>Image: 初始化 ReferenceStore
Image-->>Daemon: ImageService 实例
Note over Daemon: 10. 初始化网络
Daemon->>Network: libnetwork.New(config)
Network->>Network: 创建默认网络(bridge)
Network->>Network: 加载网络端点
Network-->>Daemon: Controller 实例
Note over Daemon: 11. 恢复容器状态
Daemon->>Daemon: restoreContainers(ctx)
loop 运行中的容器
Daemon->>Containerd: Load(containerID)
Containerd-->>Daemon: Task 句柄
Daemon->>Daemon: 重新连接日志流
Daemon->>Daemon: 重新连接网络
end
Daemon-->>Command: Daemon 实例
Note over Command: 12. 启动 API 服务器
Command->>Command: buildRouters(daemon)
Command->>Command: CreateMux(routers)
Command->>Command: httpServer.Serve(listener)
Note over Command: 13. 启动集群(如果配置)
Command->>Command: createAndStartCluster(daemon)
Note over Command: 14. 启动 BuildKit
Command->>Command: initBuildkit(daemon)
Command-->>Main: 守护进程运行中
初始化步骤详解
步骤 1-2:平台验证与配置
- 检查系统要求:
- Linux: 内核版本 ≥ 3.10,cgroup 挂载,AppArmor/SELinux
- Windows: 容器特性是否启用
- 验证配置项合法性:
- 存储驱动与内核兼容性
- 网络配置(默认网段不冲突)
- 资源限制(CPU/内存配额)
步骤 3:连接 containerd
// 核心代码示例
d.containerdClient, err = containerd.New(
cfgStore.ContainerdAddr, // 默认 /run/containerd/containerd.sock
containerd.WithDefaultNamespace("moby"),
containerd.WithTimeout(60 * time.Second),
)
- 建立 gRPC 长连接
- 设置命名空间隔离(moby/plugins)
- 配置重连策略(指数退避)
步骤 4:插件系统初始化
d.pluginManager, err = plugin.NewManager(plugin.ManagerConfig{
Root: "/var/lib/docker/plugins",
ExecRoot: "/run/docker/plugins",
Store: d.PluginStore,
CreateExecutor: createPluginExec, // containerd 执行器
RegistryService: registryService,
LiveRestoreEnabled: true,
})
- 扫描插件根目录
- 读取插件元数据(config.json)
- 启动已启用插件(通过 containerd 运行)
步骤 5:卷服务初始化
d.volumes, err = volumesservice.NewVolumeService(
cfgStore.Root, // /var/lib/docker
d.PluginStore, // 插件卷驱动
idtools.Identity{UID: uid, GID: gid}, // 用户映射
d, // EventLogger 接口
)
- 初始化内置 local 驱动
- 扫描
/var/lib/docker/volumes目录 - 加载卷元数据到内存索引
步骤 6-7:容器存储与加载
d.containers = container.NewMemoryStore() // 内存索引
d.containersReplica, _ = container.NewViewDB() // BoltDB 视图
containers, err := d.loadContainers(ctx)
for _, c := range containers {
// 读取 /var/lib/docker/containers/<id>/config.v2.json
// 解析容器配置
// 注册到 ContainerStore
}
- 遍历容器目录
- 跳过无效或损坏的容器
- 构建内存索引(按 ID/Name 查找)
步骤 8:存储驱动初始化
driverName := os.Getenv("DOCKER_DRIVER") // 或 daemon.json 配置
graphDriver, err := graphdriver.New(
driverName, // overlay2/aufs/devicemapper
cfgStore.Root, // /var/lib/docker
graphdriver.Options{
DriverOptions: cfgStore.GraphOptions,
UIDMaps: idMapping.UIDs(),
GIDMaps: idMapping.GIDs(),
},
)
- 驱动选择优先级:环境变量 > 配置文件 > 自动检测
- overlay2 检查:内核版本、overlayfs 模块、文件系统支持
步骤 9:镜像服务初始化
d.imageService, err = images.NewImageService(images.ImageServiceConfig{
ContainerdClient: d.containerdClient,
LayerStore: layerStore, // 存储驱动封装
ReferenceStore: refStore, // 镜像引用(tag -> digest)
RegistryService: d.registryService,
EventsService: d.EventsService,
...
})
- 连接 containerd 的镜像内容存储
- 初始化镜像引用数据库
- 启动镜像垃圾回收器(未被引用的层)
步骤 10:网络初始化
controller, err := libnetwork.New(libnetwork.OptionDataDir(
filepath.Join(cfgStore.Root, "network"),
))
// 创建默认 bridge 网络
if !cfgStore.DisableBridge {
controller.NewNetwork("bridge", "bridge", networkOptions...)
}
- 加载网络驱动(bridge/overlay/macvlan)
- 恢复网络端点
- 启动 DNS 服务器(内置 DNS 解析)
步骤 11:容器状态恢复
func (daemon *Daemon) restoreContainers(ctx context.Context) {
for _, c := range daemon.containers.List() {
if c.IsRunning() {
// 重新连接到 containerd Task
task, err := daemon.containerd.LoadContainer(ctx, c.ID)
// 重新连接日志流
daemon.attachContainerStreams(c)
// 重新连接网络
daemon.connectToNetwork(c)
}
}
}
- 仅在 live-restore 模式启用时恢复
- 重新订阅容器事件(exit/OOM)
- 恢复健康检查定时器
边界条件与异常处理
并发控制
容器并发操作:
func (daemon *Daemon) containerStart(ctx context.Context, container *container.Container) error {
container.Lock()
defer container.Unlock()
// 检查状态
if container.Running {
return nil // 幂等:已启动返回成功
}
if container.RemovalInProgress {
return errdefs.Conflict("container is being removed")
}
// 启动逻辑...
}
- 每个容器有独立的读写锁
- 状态检查与修改在锁保护下原子执行
- 避免死锁:严格按顺序加锁(Daemon 锁 → Container 锁)
配置热加载:
func (daemon *Daemon) Reload(conf *config.Config) error {
daemon.configReload.Lock()
defer daemon.configReload.Unlock()
// 验证新配置
if err := validateReloadableConfig(conf); err != nil {
return err
}
// 原子替换配置指针
newStore := &configStore{Config: *conf}
daemon.configStore.Store(newStore)
// 应用新配置到子系统
daemon.reloadLogConfig(conf)
daemon.reloadLabels(conf)
return nil
}
- 使用
atomic.Pointer避免读锁 - 部分配置项立即生效(日志级别)
- 部分配置项需重启(存储驱动)
超时与资源限制
启动超时:
- 默认 30 秒(可通过
--start-timeout配置) - 超时后自动清理已分配资源(网络端点、卷挂载)
并发限制:
- 镜像拉取并发:
max-concurrent-downloads(默认 3) - 镜像推送并发:
max-concurrent-uploads(默认 5) - 容器启动无限制(建议通过外部编排工具控制)
异常恢复
containerd 连接断开:
// 监听 containerd 事件流
go func() {
for {
events, errs := d.containerd.Subscribe(ctx, filters...)
select {
case err := <-errs:
log.Errorf("containerd connection lost: %v", err)
// 指数退避重连
backoff.Retry(func() error {
return d.reconnectContainerd()
})
case evt := <-events:
d.processContainerdEvent(evt)
}
}
}()
- 自动重连机制(最多重试 10 次)
- 重连后恢复事件订阅
- 容器状态可能短暂不一致(最终一致性)
磁盘满处理:
- 容器创建失败:返回 507 Insufficient Storage
- 日志写入失败:停止日志收集、发送警告事件
- 镜像拉取失败:清理部分下载的层
性能关键路径
容器启动 P95 延迟分析
| 阶段 | 耗时 (ms) | 占比 | 优化点 |
|---|---|---|---|
| API 解析 | 2 | 1% | - |
| 配置验证 | 5 | 2% | 缓存镜像元数据 |
| 镜像层准备 | 20 | 10% | 使用 overlay2 |
| 生成 OCI Spec | 8 | 4% | - |
| containerd 创建容器 | 30 | 15% | - |
| runc 创建命名空间 | 60 | 30% | 使用用户命名空间 |
| 挂载文件系统 | 25 | 12% | 预热镜像层 |
| 网络配置 | 40 | 20% | 使用 host 网络 |
| 启动进程 | 10 | 5% | - |
| 连接日志流 | 2 | 1% | - |
| 总计 | 202 | 100% | - |
热点优化
1. 容器查找优化:
// 内存索引 + 前缀匹配
type Store struct {
byID map[string]*Container
byName map[string]*Container
}
func (s *Store) Get(nameOrID string) *Container {
// 精确匹配优先(O(1))
if c := s.byID[nameOrID]; c != nil {
return c
}
if c := s.byName[nameOrID]; c != nil {
return c
}
// 前缀匹配(O(n))
for id, c := range s.byID {
if strings.HasPrefix(id, nameOrID) {
return c
}
}
return nil
}
2. 事件广播优化:
// 使用带缓冲 channel 避免阻塞
type Events struct {
subscribers map[string]chan *Event
buffer int // 默认 100
}
func (e *Events) Publish(evt *Event) {
for _, ch := range e.subscribers {
select {
case ch <- evt:
default:
// 满则丢弃旧事件
<-ch
ch <- evt
}
}
}
3. 配置读取优化:
// 使用 atomic.Pointer 避免锁
type Daemon struct {
configStore atomic.Pointer[configStore]
}
func (d *Daemon) config() *configStore {
return d.configStore.Load() // 无锁读取
}
配置项与观测性
核心配置项
| 配置项 | 类型 | 默认值 | 说明 | 影响 |
|---|---|---|---|---|
data-root |
string | /var/lib/docker |
数据根目录 | 所有持久化数据位置 |
exec-root |
string | /var/run/docker |
运行时文件目录 | PID 文件、socket |
storage-driver |
string | auto | 存储驱动 | 镜像层存储方式 |
storage-opts |
[]string | [] |
存储驱动选项 | overlay2.size 等 |
live-restore |
bool | false |
守护进程重启保持容器运行 | 可用性 |
max-concurrent-downloads |
int | 3 |
镜像拉取并发数 | 网络带宽占用 |
max-concurrent-uploads |
int | 5 |
镜像推送并发数 | 网络带宽占用 |
shutdown-timeout |
int | 15 |
关闭超时(秒) | 优雅关闭时间 |
debug |
bool | false |
调试模式 | 日志级别 |
观测指标
Prometheus 指标(/metrics 端点):
# Daemon 状态
engine_daemon_info{version="24.0.0", os="linux", arch="amd64"}
# 容器操作
engine_daemon_container_actions_seconds{action="create"} histogram
engine_daemon_container_actions_seconds{action="start"} histogram
engine_daemon_container_states_containers{state="running"} gauge
engine_daemon_container_states_containers{state="paused"} gauge
engine_daemon_container_states_containers{state="stopped"} gauge
# 镜像操作
engine_daemon_image_actions_seconds{action="pull"} histogram
engine_daemon_image_actions_seconds{action="push"} histogram
# 网络操作
engine_daemon_network_actions_seconds{action="create"} histogram
engine_daemon_network_actions_seconds{action="connect"} histogram
# 健康状态
engine_daemon_health_checks_failed_total counter
事件流订阅:
# 实时监听所有事件
curl --unix-socket /var/run/docker.sock \
http://localhost/events
# 过滤容器事件
curl --unix-socket /var/run/docker.sock \
'http://localhost/events?filters={"type":["container"]}'
# 示例事件
{
"status": "start",
"id": "abc123...",
"from": "nginx:latest",
"Type": "container",
"Action": "start",
"Actor": {
"ID": "abc123...",
"Attributes": {
"image": "nginx:latest",
"name": "web"
}
},
"time": 1678886400,
"timeNano": 1678886400000000000
}
最佳实践
生产环境配置
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"compress": "true"
},
"live-restore": true,
"userland-proxy": false,
"icc": false,
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 10,
"shutdown-timeout": 60,
"debug": false,
"experimental": false
}
监控告警规则
groups:
- name: docker_daemon
rules:
- alert: DaemonContainerCreateSlow
expr: histogram_quantile(0.95, engine_daemon_container_actions_seconds{action="create"}) > 5
for: 5m
annotations:
summary: "容器创建 P95 延迟超过 5 秒"
- alert: DaemonImagePullFailed
expr: rate(engine_daemon_image_actions_seconds_count{action="pull",error="true"}[5m]) > 0.1
for: 5m
annotations:
summary: "镜像拉取失败率超过 10%"
- alert: DaemonHighMemory
expr: process_resident_memory_bytes{job="docker"} > 2e9
for: 10m
annotations:
summary: "Daemon 内存占用超过 2GB"
故障排查
1. Daemon 启动失败:
# 检查 systemd 日志
journalctl -u docker -n 100 --no-pager
# 检查配置文件语法
dockerd --validate --config-file=/etc/docker/daemon.json
# 手动启动获取详细日志
dockerd --debug --log-level=debug
2. 容器无法启动:
# 检查 containerd 状态
systemctl status containerd
# 查看 containerd 日志
journalctl -u containerd -f
# 检查存储驱动
docker info | grep -i storage
3. 性能问题:
# 查看慢操作
docker events --filter 'type=container' --format '{{.TimeNano}} {{.Status}}' \
| awk '{print ($1 - prev), $2; prev=$1}'
# 分析 CPU 占用
perf top -p $(pidof dockerd)
# 查看 goroutine 泄漏
kill -USR1 $(pidof dockerd) # 生成 goroutine dump
ls -lh /var/run/docker/goroutine-*.dump
API接口
本文档详细描述 Daemon 模块对外提供的系统级 HTTP API 接口,包括请求/响应结构、核心代码、调用链路与时序图。
附录:来源合并(posts/docker-02-API接口详细分析)
A.1 系统信息与版本接口(摘录)
// GET /info httputils.WriteJSON(w, http.StatusOK, info)
// 版本过滤示例(<1.44):
// if versions.LessThan(version, "1.44") { info.ContainerDSecriptor = nil }
// GET /version
v := &types.Version{
Platform: struct{ Name string }{dockerversion.PlatformName},
Version: dockerversion.Version,
APIVersion: dockerversion.DefaultAPIVersion,
MinAPIVersion: dockerversion.MinAPIVersion,
GitCommit: dockerversion.GitCommit,
BuildTime: dockerversion.BuildTime,
GoVersion: runtime.Version(),
Os: runtime.GOOS,
Arch: runtime.GOARCH,
}
说明:整合自 posts/docker-02-API接口详细分析 的系统与版本接口要点,保持与本章节“目录与示例”的风格一致。
API 目录
| 序号 | API | 方法 | 路径 | 说明 |
|---|---|---|---|---|
| 1 | 健康检查 | GET/HEAD | /_ping |
检查 Docker 守护进程健康状态 |
| 2 | 获取系统信息 | GET | /info |
获取 Docker 守护进程详细信息 |
| 3 | 获取版本信息 | GET | /version |
获取 Docker 版本信息 |
| 4 | 获取事件流 | GET | /events |
实时订阅 Docker 事件 |
| 5 | 获取磁盘使用 | GET | /system/df |
获取磁盘空间使用情况 |
| 6 | 注册表认证 | POST | /auth |
验证注册表凭据 |
1. 健康检查
基本信息
- 路径:
GET /_ping或HEAD /_ping - 用途:检查 Docker 守护进程是否正常运行
- 最小 API 版本:v1.24
- 幂等性:是
响应
响应头:
| 头 | 说明 |
|---|---|
| Content-Type | text/plain; charset=utf-8 |
| Cache-Control | no-cache, no-store, must-revalidate |
| Builder-Version | 构建器版本(1/2) |
| Swarm | Swarm 状态(active/inactive/pending/error) |
响应体:
- GET:
OK(2 字节) - HEAD:空(Content-Length: 0)
状态码:
- 200 OK:守护进程正常
- 500 Internal Server Error:守护进程异常
入口函数与核心代码
func (s *systemRouter) pingHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
// 1. 设置缓存控制头
w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Add("Pragma", "no-cache")
// 2. 设置构建器版本
builderVersion := build.BuilderVersion(s.features())
w.Header().Set("Builder-Version", string(builderVersion))
// 3. 设置 Swarm 状态
w.Header().Set("Swarm", s.swarmStatus())
// 4. HEAD 请求仅返回头
if r.Method == http.MethodHead {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Content-Length", "0")
return nil
}
// 5. GET 请求返回 "OK"
_, err := w.Write([]byte{'O', 'K'})
return err
}
使用场景
健康检查脚本:
#!/bin/bash
# Docker健康检查
if curl -f -s http://localhost:2375/_ping > /dev/null; then
echo "Docker is healthy"
exit 0
else
echo "Docker is unhealthy"
exit 1
fi
Docker Compose健康检查:
services:
app:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:2375/_ping"]
interval: 30s
timeout: 10s
retries: 3
2. 获取系统信息
基本信息
- 路径:
GET /info - 用途:获取 Docker 守护进程的详细系统信息
- 最小 API 版本:v1.24
- 幂等性:是
响应结构体
type Info struct {
// 守护进程信息
ID string // 守护进程唯一 ID
Name string // 主机名
ServerVersion string // Docker 版本
OperatingSystem string // 操作系统
OSType string // OS 类型(linux/windows)
Architecture string // CPU 架构
KernelVersion string // 内核版本
// 容器信息
Containers int // 总容器数
ContainersRunning int // 运行中容器数
ContainersPaused int // 暂停的容器数
ContainersStopped int // 停止的容器数
// 镜像信息
Images int // 镜像数量
// 驱动信息
Driver string // 存储驱动
DriverStatus [][2]string // 驱动状态
Plugins PluginsInfo // 插件信息
// 资源限制
MemTotal int64 // 总内存(字节)
NCPU int // CPU 数量
// 网络
IndexServerAddress string // 注册表服务器地址
// Swarm 信息
Swarm swarm.Info
// 运行时
Runtimes map[string]Runtime
DefaultRuntime string
// 警告
Warnings []string
}
入口函数与核心代码
func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
version := httputils.VersionFromContext(ctx)
// 使用单飞模式防止并发调用
info, _, _ := s.collectSystemInfo.Do(ctx, version, func(ctx context.Context) (*infoResponse, error) {
// 1. 获取基础信息
info, err := s.backend.SystemInfo(ctx)
// 2. 添加 Swarm 信息
if s.cluster != nil {
info.Swarm = s.cluster.Info(ctx)
info.Warnings = append(info.Warnings, info.Swarm.Warnings...)
}
// 3. API 版本兼容性处理
if versions.LessThan(version, "1.44") {
// 移除 v1.44 引入的字段
}
return &infoResponse{Info: info}, nil
})
return httputils.WriteJSON(w, http.StatusOK, info)
}
Backend 实现:
func (daemon *Daemon) SystemInfo(ctx context.Context) (*system.Info, error) {
// 1. 收集容器信息
containers := daemon.containers.List()
var running, paused, stopped int
for _, c := range containers {
switch c.State.StateString() {
case "running":
running++
case "paused":
paused++
default:
stopped++
}
}
// 2. 收集镜像信息
images, _ := daemon.imageService.Images(ctx)
// 3. 收集系统资源
memInfo, _ := meminfo.Read()
// 4. 组装响应
return &system.Info{
ID: daemon.id,
Containers: len(containers),
ContainersRunning: running,
ContainersPaused: paused,
ContainersStopped: stopped,
Images: len(images),
Driver: daemon.imageService.StorageDriver(),
MemTotal: memInfo.MemTotal,
NCPU: runtime.NumCPU(),
OperatingSystem: platform.GetOperatingSystem(),
OSType: runtime.GOOS,
Architecture: platform.Architecture,
KernelVersion: platform.GetKernelVersion(),
ServerVersion: dockerversion.Version,
Runtimes: daemon.runtimes,
DefaultRuntime: daemon.defaultRuntime,
}, nil
}
3. 获取版本信息
基本信息
- 路径:
GET /version - 用途:获取 Docker 版本信息
- 最小 API 版本:v1.24
- 幂等性:是
响应结构体
type Version struct {
Version string // Docker 版本(例如:"24.0.7")
ApiVersion string // API 版本(例如:"1.43")
MinAPIVersion string // 最小 API 版本
GitCommit string // Git commit ID
GoVersion string // Go 版本
Os string // 操作系统
Arch string // 架构
KernelVersion string // 内核版本
BuildTime string // 构建时间
// 组件版本
Components []ComponentVersion
}
type ComponentVersion struct {
Name string // 组件名称(Engine/containerd/runc/docker-init)
Version string // 版本号
Details map[string]string // 详细信息
}
入口函数与核心代码
func (s *systemRouter) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
info, err := s.backend.SystemVersion(ctx)
return httputils.WriteJSON(w, http.StatusOK, info)
}
4. 获取事件流
基本信息
- 路径:
GET /events - 用途:实时订阅 Docker 事件流
- 最小 API 版本:v1.24
- 幂等性:否(流式接口)
请求参数
| 参数 | 类型 | 说明 |
|---|---|---|
| since | int64 | 起始时间戳 |
| until | int64 | 结束时间戳 |
| filters | JSON | 过滤器 |
过滤器选项:
| 过滤器 | 说明 |
|---|---|
| type | 事件类型(container/image/volume/network/daemon) |
| event | 事件名称(create/start/stop/die) |
| container | 容器 ID |
| image | 镜像名称 |
| label | 标签过滤 |
响应结构体
type Message struct {
Type string // 事件类型
Action string // 动作(create/start/stop/die)
Actor Actor // 事件主体
Time int64 // 时间戳
TimeNano int64 // 纳秒时间戳
}
type Actor struct {
ID string // 对象 ID
Attributes map[string]string // 属性
}
入口函数与核心代码
func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
// 1. 解析参数
since, _ := strconv.ParseInt(r.Form.Get("since"), 10, 64)
until, _ := strconv.ParseInt(r.Form.Get("until"), 10, 64)
filters, _ := filters.FromJSON(r.Form.Get("filters"))
// 2. 订阅事件
eventCh := s.backend.SubscribeToEvents(since, until, filters)
defer s.backend.UnsubscribeFromEvents(eventCh)
// 3. 流式输出
w.Header().Set("Content-Type", "application/json")
enc := json.NewEncoder(w)
for {
select {
case event := <-eventCh:
if err := enc.Encode(event); err != nil {
return err
}
w.(http.Flusher).Flush()
case <-ctx.Done():
return nil
}
}
}
5. 获取磁盘使用
基本信息
- 路径:
GET /system/df - 用途:获取 Docker 磁盘空间使用情况
- 最小 API 版本:v1.25
- 幂等性:是
请求参数
| 参数 | 类型 | 说明 |
|---|---|---|
| type | string[] | 对象类型(container/image/volume/build-cache) |
响应结构体
type DiskUsage struct {
LayersSize int64 // 镜像层总大小
Images []*ImageSummary // 镜像列表
Containers []*Container // 容器列表
Volumes []*Volume // 卷列表
BuildCache []*BuildCacheDiskUsage // 构建缓存
}
入口函数与核心代码
func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
// 1. 解析类型参数
var getContainers, getImages, getVolumes, getBuildCache bool
typeStrs := r.Form["type"]
// 2. 并发收集各类资源
var eg errgroup.Group
var usage backend.DiskUsage
if getImages {
eg.Go(func() error {
usage.Images, _ = s.backend.ImageDiskUsage(ctx)
return nil
})
}
if getContainers {
eg.Go(func() error {
usage.Containers, _ = s.backend.ContainerDiskUsage(ctx)
return nil
})
}
if getVolumes {
eg.Go(func() error {
usage.Volumes, _ = s.backend.VolumesDiskUsage(ctx)
return nil
})
}
if getBuildCache {
eg.Go(func() error {
usage.BuildCache, _ = s.builder.DiskUsage(ctx)
return nil
})
}
eg.Wait()
return httputils.WriteJSON(w, http.StatusOK, usage)
}
6. 注册表认证
基本信息
- 路径:
POST /auth - 用途:验证注册表凭据
- 最小 API 版本:v1.24
- 幂等性:是
请求结构体
type AuthConfig struct {
Username string // 用户名
Password string // 密码
Auth string // Base64 编码的 username:password
Email string // 邮箱(已废弃)
ServerAddress string // 注册表服务器地址
IdentityToken string // 身份令牌
RegistryToken string // 注册表令牌
}
响应结构体
type AuthenticateOKBody struct {
Status string // 认证状态
IdentityToken string // 身份令牌
}
入口函数与核心代码
func (s *systemRouter) postAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
// 1. 解析认证配置
var authConfig registry.AuthConfig
if err := json.NewDecoder(r.Body).Decode(&authConfig); err != nil {
return err
}
// 2. 验证凭据
status, token, err := s.backend.AuthenticateToRegistry(ctx, &authConfig)
if err != nil {
return err
}
// 3. 返回结果
return httputils.WriteJSON(w, http.StatusOK, registry.AuthenticateOKBody{
Status: status,
IdentityToken: token,
})
}
附录:事件类型
Container 事件
| 事件 | 说明 |
|---|---|
| create | 容器创建 |
| start | 容器启动 |
| stop | 容器停止 |
| restart | 容器重启 |
| kill | 容器被杀死 |
| die | 容器退出 |
| pause | 容器暂停 |
| unpause | 容器恢复 |
| attach | 附加到容器 |
| exec_create | 创建 exec |
| exec_start | 启动 exec |
| exec_die | exec 退出 |
| rename | 容器重命名 |
| destroy | 容器删除 |
Image 事件
| 事件 | 说明 |
|---|---|
| pull | 拉取镜像 |
| push | 推送镜像 |
| tag | 打标签 |
| untag | 删除标签 |
| delete | 删除镜像 |
| import | 导入镜像 |
| load | 加载镜像 |
| save | 保存镜像 |
Volume 事件
| 事件 | 说明 |
|---|---|
| create | 创建卷 |
| mount | 挂载卷 |
| unmount | 卸载卷 |
| destroy | 删除卷 |
Network 事件
| 事件 | 说明 |
|---|---|
| create | 创建网络 |
| connect | 容器连接到网络 |
| disconnect | 容器断开网络 |
| destroy | 删除网络 |
文档版本:v1.0
最后更新:2025-10-04
补充:Daemon 生产实践要点
-
接口稳定性
- 路由按资源粒度划分;幂等接口支持条件请求;长耗时端点提供流式输出与中断机制。
-
版本兼容
- 基于
ApiVersion/MinAPIVersion做兼容分支;新增字段默认可选,废弃字段保留过渡期。
- 基于
-
可观测性
- 统一错误结构/状态码;埋点时延、错误率;结构化日志与
trace_id贯穿调用链。
- 统一错误结构/状态码;埋点时延、错误率;结构化日志与
-
安全与限流
- Unix socket 权限与 TLS 双向认证;高风险端点加 RBAC;按 token/ip 做滑窗限流与配额。
数据结构
本文档详细描述 Daemon 模块的核心数据结构,包括 UML 类图、字段说明与配置管理。
数据结构概览
classDiagram
class Daemon {
-string id
-string repository
-container.Store containers
-*container.ViewDB containersReplica
-*container.ExecStore execCommands
-ImageService imageService
-*atomic.Pointer~configStore~ configStore
-*events.Events EventsService
-*libnetwork.Controller netController
-*volumesservice.VolumesService volumes
-string root
-*plugin.Manager pluginManager
-*containerd.Client containerdClient
-user.IdentityMapping idMapping
-[]byte seccompProfile
-uint64 machineMemory
+Shutdown() error
+Reload(config) error
}
class Config {
+string Root
+bool Debug
+[]string Hosts
+map~string,bool~ Features
+string DefaultRuntime
+map~string,RuntimeConfig~ Runtimes
+NetworkConfig NetworkConfig
+LogConfig LogConfig
+int MaxConcurrentDownloads
+int MaxConcurrentUploads
+bool LiveRestoreEnabled
}
class Info {
+string ID
+int Containers
+int ContainersRunning
+int ContainersPaused
+int ContainersStopped
+int Images
+string Driver
+int64 MemTotal
+int NCPU
+string OperatingSystem
+string OSType
+string Architecture
+string KernelVersion
+string ServerVersion
+map~string,Runtime~ Runtimes
+string DefaultRuntime
+swarm.Info Swarm
+[]string Warnings
}
class EventsService {
+Subscribe() chan Message
+Unsubscribe(chan)
+Publish(Message)
}
class Message {
+string Type
+string Action
+Actor Actor
+int64 Time
+int64 TimeNano
}
Daemon "1" *-- "1" Config : uses
Daemon "1" *-- "1" EventsService : manages
EventsService "1" --> "*" Message : publishes
1. Daemon(守护进程核心)
结构定义
type Daemon struct {
// 标识
id string // 守护进程唯一 ID
repository string // 存储仓库路径
// 容器管理
containers container.Store // 容器存储
containersReplica *container.ViewDB // 容器视图数据库
execCommands *container.ExecStore // Exec 命令存储
// 镜像管理
imageService ImageService // 镜像服务
// 配置
configStore atomic.Pointer[configStore] // 配置存储(支持热重载)
configReload sync.Mutex // 配置重载锁
// 事件服务
EventsService *events.Events // 事件发布/订阅
// 网络管理
netController *libnetwork.Controller // 网络控制器
// 卷管理
volumes *volumesservice.VolumesService // 卷服务
// 存储
root string // 根目录(/var/lib/docker)
sysInfo *sysinfo.SysInfo // 系统信息缓存
// 插件
pluginManager *plugin.Manager // 插件管理器
// 容器运行时
containerdClient *containerd.Client // containerd 客户端
containerd libcontainerdtypes.Client // containerd 接口
// 安全
idMapping user.IdentityMapping // 用户命名空间映射
seccompProfile []byte // Seccomp 配置
// 资源
machineMemory uint64 // 机器总内存
// 状态
shutdown bool // 是否正在关闭
startupDone chan struct{} // 启动完成信号
}
核心方法
// 生命周期
func NewDaemon(ctx context.Context, config *config.Config) (*Daemon, error)
func (daemon *Daemon) Shutdown() error
func (daemon *Daemon) Reload(conf *config.Config) error
// 系统信息
func (daemon *Daemon) SystemInfo(ctx context.Context) (*system.Info, error)
func (daemon *Daemon) SystemVersion(ctx context.Context) system.Version
// 事件
func (daemon *Daemon) LogContainerEvent(container *container.Container, action events.Action)
func (daemon *Daemon) LogImageEvent(imageID, refName string, action events.Action)
2. Config(配置)
结构定义
type Config struct {
// 存储
Root string // 根目录
ExecRoot string // Exec 根目录
// 调试
Debug bool // 调试模式
LogLevel string // 日志级别
// 网络
Hosts []string // 监听地址
NetworkConfig NetworkConfig // 网络配置
// 功能开关
Features map[string]bool // 特性开关
// 运行时
DefaultRuntime string // 默认运行时
Runtimes map[string]RuntimeConfig // 运行时配置
// 资源限制
MaxConcurrentDownloads int // 最大并发下载数
MaxConcurrentUploads int // 最大并发上传数
// 日志
LogConfig container.LogConfig // 默认日志配置
// 高级选项
LiveRestoreEnabled bool // 实时恢复
UserlandProxy bool // 用户态代理
}
配置文件示例
{
"debug": false,
"log-level": "info",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"default-runtime": "runc",
"runtimes": {
"runc": {
"path": "runc"
}
},
"max-concurrent-downloads": 3,
"max-concurrent-uploads": 5,
"live-restore": true,
"features": {
"buildkit": true
}
}
3. Info(系统信息)
结构定义
type Info struct {
// 守护进程信息
ID string // 守护进程 ID
Name string // 主机名
ServerVersion string // Docker 版本
// 容器统计
Containers int // 总容器数
ContainersRunning int // 运行中
ContainersPaused int // 暂停
ContainersStopped int // 停止
// 镜像统计
Images int // 镜像数
// 存储
Driver string // 存储驱动
DriverStatus [][2]string // 驱动状态
// 系统资源
MemTotal int64 // 总内存
NCPU int // CPU 数
OperatingSystem string // 操作系统
OSType string // OS 类型
Architecture string // 架构
KernelVersion string // 内核版本
// 运行时
Runtimes map[string]Runtime // 运行时列表
DefaultRuntime string // 默认运行时
// Swarm
Swarm swarm.Info // Swarm 信息
// 警告
Warnings []string // 警告信息
}
4. EventsService(事件服务)
结构定义
type EventsService struct {
mu sync.RWMutex
subscribers map[chan events.Message]struct{}
}
type Message struct {
Type string // 类型(container/image/volume/network/daemon)
Action string // 动作(create/start/stop/destroy)
Actor Actor // 事件主体
Time int64 // 时间戳(秒)
TimeNano int64 // 时间戳(纳秒)
}
type Actor struct {
ID string // 对象 ID
Attributes map[string]string // 属性
}
核心方法
// 订阅事件
func (e *EventsService) Subscribe() chan events.Message
// 取消订阅
func (e *EventsService) Unsubscribe(ch chan events.Message)
// 发布事件
func (e *EventsService) Publish(msg events.Message)
使用场景
// 订阅事件
eventCh := daemon.EventsService.Subscribe()
defer daemon.EventsService.Unsubscribe(eventCh)
for event := range eventCh {
fmt.Printf("Event: %s %s %s\n", event.Type, event.Action, event.Actor.ID)
}
5. 配置热重载
可重载配置项
| 配置项 | 说明 |
|---|---|
debug |
调试模式 |
log-level |
日志级别 |
max-concurrent-downloads |
最大并发下载 |
max-concurrent-uploads |
最大并发上传 |
labels |
守护进程标签 |
live-restore |
实时恢复 |
重载流程
func (daemon *Daemon) Reload(conf *config.Config) error {
daemon.configReload.Lock()
defer daemon.configReload.Unlock()
// 1. 验证配置
if err := conf.Validate(); err != nil {
return err
}
// 2. 更新配置
oldConfig := daemon.configStore.Load()
daemon.configStore.Store(conf)
// 3. 应用更改
if conf.Debug != oldConfig.Debug {
daemon.setDebugLevel(conf.Debug)
}
return nil
}
配置重载命令
# 发送 SIGHUP 信号
kill -HUP $(pidof dockerd)
# 或使用 systemd
systemctl reload docker
文档版本:v1.0
最后更新:2025-10-04
时序图
本文档通过时序图展示 Daemon 模块的典型操作流程,包括启动、配置重载、事件发布等关键场景。
时序图目录
1. Daemon 启动流程
时序图
sequenceDiagram
autonumber
participant Main as main()
participant CLI as DaemonCLI
participant Daemon as Daemon
participant Containerd as containerd
participant Plugin as PluginManager
participant Network as NetworkController
participant Volume as VolumeService
Main->>CLI: NewDaemonRunner()
Main->>CLI: Run(ctx)
CLI->>CLI: 解析配置文件
CLI->>CLI: 设置日志级别
CLI->>CLI: 创建 PID 文件
CLI->>Daemon: NewDaemon(ctx, config)
Daemon->>Daemon: 初始化目录结构
Daemon->>Containerd: 连接 containerd
Containerd-->>Daemon: client
Daemon->>Plugin: NewPluginManager()
Plugin-->>Daemon: pluginManager
Daemon->>Network: NewController(config)
Network-->>Daemon: netController
Daemon->>Volume: NewVolumeService(root)
Volume-->>Daemon: volumeService
Daemon->>Daemon: 恢复容器(live-restore)
Daemon->>Daemon: 启动事件服务
Daemon-->>CLI: daemon
CLI->>CLI: 初始化 API 服务器
CLI->>CLI: 启动 API 监听
CLI->>CLI: close(startupDone)
Note over Main,Volume: Daemon 启动完成
说明
启动阶段
- 配置解析:读取
/etc/docker/daemon.json - 目录初始化:创建
/var/lib/docker/目录结构 - Containerd 连接:连接到 containerd socket
- 插件管理器:初始化插件系统
- 网络控制器:初始化网络子系统
- 卷服务:初始化卷管理
- 容器恢复:恢复已存在的容器(live-restore)
- API 服务器:启动 HTTP API 服务
2. 配置热重载流程
时序图
sequenceDiagram
autonumber
participant Admin as 管理员
participant Signal as Signal Handler
participant Daemon as Daemon
participant Config as ConfigStore
participant Logger as Logger
Admin->>Signal: kill -HUP <pid>
Signal->>Daemon: Reload(newConfig)
Daemon->>Daemon: configReload.Lock()
Daemon->>Config: Load()
Config-->>Daemon: oldConfig
Daemon->>Daemon: newConfig.Validate()
alt debug 模式变更
Daemon->>Logger: SetLevel(newLevel)
end
alt 并发下载数变更
Daemon->>Daemon: 更新 maxDownloads
end
Daemon->>Config: Store(newConfig)
Daemon->>Daemon: configReload.Unlock()
Daemon->>Daemon: LogEvent("reload", "success")
Daemon-->>Admin: 配置已重载
3. 事件发布与订阅流程
时序图
sequenceDiagram
autonumber
participant Client as Docker Client
participant API as API Handler
participant Events as EventsService
participant Container as Container Op
Note over Client,Container: 订阅事件流
Client->>API: GET /events
API->>Events: Subscribe()
Events->>Events: 创建 channel
Events->>Events: 注册 subscriber
Events-->>API: eventCh
Note over Client,Container: 容器操作触发事件
Container->>Events: Publish(Message{<br/>Type: "container",<br/>Action: "start",<br/>Actor: {ID: "abc123"}<br/>})
Events->>Events: 遍历 subscribers
Events->>API: eventCh <- Message
API->>Client: Stream: {"Type":"container","Action":"start",...}
Note over Client,Container: 客户端断开
Client->>API: 关闭连接
API->>Events: Unsubscribe(eventCh)
Events->>Events: 删除 subscriber
Events->>Events: close(eventCh)
4. 系统信息查询流程
时序图
sequenceDiagram
autonumber
participant Client as Client
participant API as API
participant Daemon as Daemon
participant ContainerStore as Container Store
participant ImageStore as Image Store
participant Swarm as Swarm Cluster
Client->>API: GET /info
API->>Daemon: SystemInfo(ctx)
par 并发收集信息
Daemon->>ContainerStore: List()
ContainerStore-->>Daemon: [containers]
Daemon->>Daemon: 统计容器状态
and
Daemon->>ImageStore: Images(ctx)
ImageStore-->>Daemon: [images]
and
Daemon->>Swarm: Info(ctx)
Swarm-->>Daemon: swarmInfo
end
Daemon->>Daemon: 组装 Info 结构
Daemon-->>API: Info
API-->>Client: 200 OK<br/>{ID, Containers, Images, ...}