/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.json是 Linux 专属的标准路径。Docker Desktop(Mac/Windows)走 GUI 设置面板,本质也是写上面那个文件。
二、完整配置示例
| |
三、字段逐个解读
3.1 registry-mirrors:镜像加速
国内服务器拉 Docker Hub 镜像慢到秒级超时,配镜像源是必做项。
| |
机制:Docker daemon 拉镜像时先尝试 mirrors,失败才回源。多 mirror 是 fallback 链——不是并发。
验证:
| |
测速:
| |
3.2 insecure-registries:私有仓库(HTTP)
公司内部 / 测试环境的私有 Registry 通常没有 HTTPS 证书。配置后 Docker 才允许 docker pull/push:
| |
注意:HTTP 仓库在 daemon 层就被标记为"不加密",生产环境强烈建议升级到 HTTPS——攻击者能篡改镜像内容,等于供应链投毒。
3.3 exec-opts:cgroup driver
| |
Why 必须 systemd:K8s 1.22+ 强制要求 kubelet 的 cgroup driver 和容器 runtime 一致。如果 dockerd 用
cgroupfs而 kubelet 用systemd,Pod 启动可能失败、CPU / 内存 limit 不生效。
验证:
| |
3.4 log-driver / log-opts:日志配置
| |
| 字段 | 默认 | 推荐 | 说明 |
|---|---|---|---|
max-size | 无 | "50m" | 单个日志文件最大 50MB |
max-file | 1 | "3" | 最多保留 3 个文件(50MB × 3 = 150MB) |
labels | - | "production,app" | 只收集带这些 label 的容器日志 |
env | - | "ENV=prod" | 只收集带这些环境变量的容器日志 |
生产环境:
max-size必须配——不配的话容器日志会无限增长撑爆磁盘max-file建议 3-5 个——多了浪费 IO,少了不便排查- 高吞吐服务(nginx、Kafka)考虑改
log-driver: syslog或fluentd推 ELK
3.5 storage-driver:存储驱动
| 驱动 | 内核要求 | 适用 |
|---|---|---|
overlay2 | Linux 4.0+ | 默认推荐(CentOS 7+、Ubuntu 16.04+、Debian 9+) |
devicemapper | Linux 3.18+ | 老 CentOS 7 / RHEL 7 |
btrfs | Linux 3.16+ | btrfs 文件系统 |
zfs | Linux 3.16+ | ZFS 文件系统 |
vfs | 任意 | 调试用,性能差 |
不要轻易改
storage-driver——已有镜像 / 容器迁移成本极高,且 Docker 不支持在 daemon.json 改 storage driver 时自动迁移已有数据。
3.6 data-root:数据根目录
| |
为什么需要改:
/var容量不够(最常见)- 用 XFS / ext4 大盘替代
- 把数据放到独立 SSD
详见 Docker 数据目录搬家 一文。
3.7 live-restore:daemon 升级不停容器
| |
What:daemon 重启时(升级、crash 恢复)正在运行的容器不会停。默认是
false——daemon 一重启,所有容器被 SIGTERM。
验证:
| |
注意事项:
- 仅在 dockerd 是 pid 1 时有效(systemd 管理的标准场景)
- 不支持 Windows 容器
- 不支持
--userland-proxy=false的某些边界场景- Docker Swarm 模式下行为可能不一致
3.8 features.buildkit:启用 BuildKit
| |
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?
| 操作 | 行为 | 适用 |
|---|---|---|
reload | 发 SIGHUP 给 dockerd,热加载配置 | log-opts / registry-mirrors / insecure-registries / live-restore |
restart | 优雅停所有容器 → 重启 daemon | data-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不重读
| |
五、多机同步:批量应用 daemon.json
在 K8s 集群里,所有节点的 daemon.json 应保持一致:
| |
生产警示:在 K8s 集群里改 daemon.json 之前,先
kubectl drain <node> --ignore-daemonsets,避免 Pod 被 dockerd 重启打断。
六、常见问题
6.1 unable to configure the Docker daemon 启动失败
daemon.json 语法错(多余逗号、引号不配对)。journalctl -u docker 找具体报错行。
| |
6.2 镜像源不生效
| |
6.3 cgroup driver 冲突(K8s)
| |
解决:dockerd 和 kubelet 都用 systemd。dockerd 改 exec-opts: ["native.cgroupdriver=systemd"],kubelet 改 --cgroup-driver=systemd,两边都改完再重启。
七、要点回顾
registry-mirrors必配——国内服务器不配镜像源拉镜像会卡log-opts: max-size + max-file必配——不配日志能撑爆磁盘- K8s 集群里 cgroup driver 必须
systemd——exec-opts加native.cgroupdriver=systemd live-restore: true是 daemon 升级不停机的关键reloadvsrestart取决于改的字段——改 data-root / cgroup 必须 restart- 改完 JSON 一定要
python3 -m json.tool校验——JSON 错 daemon 起不来 - 多机同步用
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 接力——后者是"应用层"的标准化。
