Featured image of post Docker daemon.json 配置详解:镜像加速、存储驱动与日志轮转

Docker daemon.json 配置详解:镜像加速、存储驱动与日志轮转

/etc/docker/daemon.json 完整字段解析:registry-mirrors 镜像加速、insecure-registries、cgroup driver、log-opts 日志轮转、多机同步

/etc/docker/daemon.json 是 Docker daemon 的核心配置文件,所有"非启动命令行"参数都在这里——registry-mirrors、insecure-registries、cgroup driver、log driver、storage driver、live-restore、default-runtime 等等。

这一篇把 daemon.json 的常用字段、最佳配置、reload / restart 区别、多机同步一次性收齐。

阅读对象:需要标准化 Docker 部署的运维同学、想搞懂 daemon.json 各字段的开发者 覆盖范围:镜像加速 + cgroup driver + 日志轮转 + K8s 集成 + 多机同步

一、daemon.json 在哪

系统路径
Linux/etc/docker/daemon.json
Windows (Docker Desktop)%ProgramData%\docker\config\daemon.json
macOS (Docker Desktop)~/Library/Group Containers/group.com.docker/settings.json
通过 --config-file flag任意路径

重要daemon.jsonLinux 专属的标准路径。Docker Desktop(Mac/Windows)走 GUI 设置面板,本质也是写上面那个文件。

二、完整配置示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "live-restore": true,
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  },
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com",
    "https://docker.nju.edu.cn",
    "https://docker.mirrors.sjtug.sjtu.edu.cn",
    "https://dockerproxy.com"
  ],
  "insecure-registries": [
    "registry.internal.example.com:5000"
  ],
  "storage-driver": "overlay2",
  "data-root": "/var/lib/docker",
  "default-runtime": "runc",
  "features": {
    "buildkit": true
  }
}

三、字段逐个解读

3.1 registry-mirrors:镜像加速

国内服务器拉 Docker Hub 镜像慢到秒级超时,配镜像源是必做项

1
2
3
4
5
6
7
8
"registry-mirrors": [
  "https://docker.m.daocloud.io",
  "https://hub-mirror.c.163.com",
  "https://mirror.baidubce.com",
  "https://docker.nju.edu.cn",
  "https://docker.mirrors.sjtug.sjtu.edu.cn",
  "https://dockerproxy.com"
]

机制:Docker daemon 拉镜像时先尝试 mirrors,失败才回源。多 mirror 是 fallback 链——不是并发。

验证

1
2
3
4
5
$ docker info | grep -A 5 'Registry Mirrors'
Registry Mirrors:
 https://docker.m.daocloud.io/
 https://hub-mirror.c.163.com/
 ...

测速

1
2
3
4
5
# 删本地缓存后用 time 计时
docker rmi node:latest
time docker pull node:latest
# 国内典型:~5-15s(用 mirror)
# 直连 Docker Hub:~1m+(甚至超时)

3.2 insecure-registries:私有仓库(HTTP)

公司内部 / 测试环境的私有 Registry 通常没有 HTTPS 证书。配置后 Docker 才允许 docker pull/push

1
2
3
4
"insecure-registries": [
  "registry.internal.example.com:5000",
  "10.0.0.10:5000"
]

注意:HTTP 仓库在 daemon 层就被标记为"不加密",生产环境强烈建议升级到 HTTPS——攻击者能篡改镜像内容,等于供应链投毒。

3.3 exec-opts:cgroup driver

1
"exec-opts": ["native.cgroupdriver=systemd"]

Why 必须 systemd:K8s 1.22+ 强制要求 kubelet 的 cgroup driver 和容器 runtime 一致。如果 dockerd 用 cgroupfs 而 kubelet 用 systemd,Pod 启动可能失败、CPU / 内存 limit 不生效。

验证

1
2
docker info | grep -i cgroup
# 期望:Cgroup Driver: systemd

3.4 log-driver / log-opts:日志配置

1
2
3
4
5
"log-driver": "json-file",
"log-opts": {
  "max-size": "50m",
  "max-file": "3"
}
字段默认推荐说明
max-size"50m"单个日志文件最大 50MB
max-file1"3"最多保留 3 个文件(50MB × 3 = 150MB)
labels-"production,app"只收集带这些 label 的容器日志
env-"ENV=prod"只收集带这些环境变量的容器日志

生产环境

  • max-size 必须配——不配的话容器日志会无限增长撑爆磁盘
  • max-file 建议 3-5 个——多了浪费 IO,少了不便排查
  • 高吞吐服务(nginx、Kafka)考虑改 log-driver: syslogfluentd 推 ELK

3.5 storage-driver:存储驱动

驱动内核要求适用
overlay2Linux 4.0+默认推荐(CentOS 7+、Ubuntu 16.04+、Debian 9+)
devicemapperLinux 3.18+老 CentOS 7 / RHEL 7
btrfsLinux 3.16+btrfs 文件系统
zfsLinux 3.16+ZFS 文件系统
vfs任意调试用,性能差

不要轻易改 storage-driver——已有镜像 / 容器迁移成本极高,且 Docker 不支持在 daemon.json 改 storage driver 时自动迁移已有数据。

3.6 data-root:数据根目录

1
"data-root": "/var/lib/docker"

为什么需要改

  • /var 容量不够(最常见)
  • 用 XFS / ext4 大盘替代
  • 把数据放到独立 SSD

详见 Docker 数据目录搬家 一文。

3.7 live-restore:daemon 升级不停容器

1
"live-restore": true

What:daemon 重启时(升级、crash 恢复)正在运行的容器不会停。默认是 false——daemon 一重启,所有容器被 SIGTERM。

验证

1
2
$ docker info | grep -i live
Live Restore Enabled: true

注意事项

  • 仅在 dockerd 是 pid 1 时有效(systemd 管理的标准场景)
  • 不支持 Windows 容器
  • 不支持 --userland-proxy=false 的某些边界场景
  • Docker Swarm 模式下行为可能不一致

3.8 features.buildkit:启用 BuildKit

1
2
3
"features": {
  "buildkit": true
}

BuildKit 是新一代构建引擎,2020 年起逐步成为默认。优势:

  • 并行构建层(用 RUN 多步骤时显著加速)
  • 增量构建缓存(按文件变更检测)
  • 改进的 Dockerfile 语法
  • --mount=type=cache / --mount=type=secret 高级特性

Docker 23.0+(2023-02) 起 BuildKit 默认开启,无需显式配置。

四、reload vs restart:什么时候用哪个

daemon.json 修改后,systemctl reload docker 还是 systemctl restart docker

操作行为适用
reloadSIGHUP 给 dockerd,热加载配置log-opts / registry-mirrors / insecure-registries / live-restore
restart优雅停所有容器 → 重启 daemondata-root / storage-driver / exec-opts(cgroup driver)

重要

  • live-restore: true 时,reload 不会中断容器
  • live-restore: false 时,restart停所有运行中的容器
  • data-root 必须 restart——reload 不重读路径
  • exec-opts 涉及 cgroup driver,必须 restart——reload 不重读
1
2
3
4
5
# 标准生效流程
systemctl daemon-reload    # 重新加载 systemd unit 文件
systemctl reload docker    # 热加载 daemon.json
# 或
systemctl restart docker   # 重启 daemon

五、多机同步:批量应用 daemon.json

在 K8s 集群里,所有节点的 daemon.json 应保持一致

1
2
3
4
5
6
7
8
9
# 单文件分发
scp /etc/docker/daemon.json worker1:/etc/docker/

# 批量
for NODE in master2 master3 worker1 worker2; do
  echo $NODE
  scp /etc/docker/daemon.json $NODE:/etc/docker/
  ssh root@$NODE "systemctl daemon-reload && systemctl reload docker && systemctl restart docker"
done

生产警示:在 K8s 集群里改 daemon.json 之前,kubectl drain <node> --ignore-daemonsets,避免 Pod 被 dockerd 重启打断。

六、常见问题

6.1 unable to configure the Docker daemon 启动失败

daemon.json 语法错(多余逗号、引号不配对)。journalctl -u docker 找具体报错行。

1
2
3
4
# 验证 JSON 语法
python3 -m json.tool /etc/docker/daemon.json
# 或
jq . /etc/docker/daemon.json

6.2 镜像源不生效

1
2
3
4
5
6
7
# 1. 看 mirror 是否在 daemon 配置里
docker info | grep 'Registry Mirrors'

# 2. 没生效 = 没 reload
systemctl reload docker    # 或 restart

# 3. 还是不行 = 源本身失效了,换一个

6.3 cgroup driver 冲突(K8s)

1
Failed to run kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver "cgroupfs" is different from docker cgroup driver "systemd"

解决:dockerd 和 kubelet 都用 systemd。dockerd 改 exec-opts: ["native.cgroupdriver=systemd"],kubelet 改 --cgroup-driver=systemd两边都改完再重启

七、要点回顾

  1. registry-mirrors 必配——国内服务器不配镜像源拉镜像会卡
  2. log-opts: max-size + max-file 必配——不配日志能撑爆磁盘
  3. K8s 集群里 cgroup driver 必须 systemd——exec-optsnative.cgroupdriver=systemd
  4. live-restore: true 是 daemon 升级不停机的关键
  5. reload vs restart 取决于改的字段——改 data-root / cgroup 必须 restart
  6. 改完 JSON 一定要 python3 -m json.tool 校验——JSON 错 daemon 起不来
  7. 多机同步用 scp + 批量 systemctl reload

八、小结

daemon.json 是 Docker 标准化的"地基"。一个规范的 daemon.json 应该满足:

  • 镜像加速——registry-mirrors 国内必配
  • 日志轮转——log-opts 限制大小和文件数
  • K8s 友好——cgroupdriver=systemd
  • 生产稳定——live-restore: true
  • 多机一致——所有节点同一份配置

下一步:daemon.json 是"daemon 自身"的配置。容器内部的"声明式配置"由 Dockerfile + Compose + K8s Manifest 接力——后者是"应用层"的标准化。

参考资料

使用 Hugo 构建
主题 StackJimmy 设计