Ubuntu Docker 安装、镜像加速与配置排障
Ubuntu Docker 安装、镜像加速与配置排障
本文记录 Ubuntu 上安装 Docker Engine、配置 Docker Hub 镜像加速,以及排查 daemon.json 未按预期生效的方法。
先说明结论:排障时应当区分已经验证的事实和暂时的猜测。看到 dockerd 的启动参数中没有 --config-file,并不能说明 Docker 没有读取配置文件;普通 Linux 安装默认就会读取 /etc/docker/daemon.json。只有掌握日志、配置路径和实际运行方式后,才能判断问题出在哪里。
一、通过 Docker 官方软件源安装
以下步骤适用于 Docker 官方支持的 Ubuntu 版本。安装前应先确认系统版本、CPU 架构和防火墙策略符合官方要求。
1. 移除可能冲突的软件包
Ubuntu 软件源中的 docker.io、旧版 Compose、podman-docker,以及单独安装的 containerd、runc,可能与 Docker 官方软件包冲突。
1 | |
如果系统提示没有安装这些软件包,可以继续下一步。该命令不会自动删除已有的 Docker 镜像、容器和数据卷。
2. 添加 Docker 官方 GPG 密钥与软件源
1 | |
3. 安装并验证
1 | |
hello-world 能正常拉取并运行,才说明软件安装、守护进程和基础网络链路均可用。
二、配置 Docker Hub 镜像加速
当主机访问 Docker Hub 较慢或超时时,可以使用组织内部的缓存仓库,或自己有权使用的镜像服务。第三方镜像站的地址、可用性和使用规则可能变化,使用前需要以服务提供方的最新说明为准。
普通 Docker Engine 的默认配置文件为:
1 | |
创建或编辑该文件:
1 | |
修改后先校验 JSON 和 Docker 配置,再重启服务:
1 | |
只有在校验成功、docker info 显示了预期配置,并且实际拉取镜像成功后,才能认为配置已经生效。
三、一个需要纠正的判断
原排障记录曾根据下面的进程参数作出判断:
1 | |
因为其中没有 --config-file /etc/docker/daemon.json,便认为 Docker 没有加载 daemon.json。这个判断不成立。
Docker Engine 在普通 Linux 环境中默认读取 /etc/docker/daemon.json,--config-file 只是用于显式指定其他路径。换句话说,参数没有出现,不等于默认行为不存在。
此外,同一个配置项如果同时出现在启动参数和 daemon.json 中,Docker 可能因配置冲突而无法启动。因此,不应在没有确认原因时直接重写 ExecStart。
四、daemon.json 不生效时的排查顺序
1. 确认运行方式和配置路径
不同运行方式使用的配置位置不同:
- 普通 Linux Docker Engine:
/etc/docker/daemon.json - Rootless 模式:
~/.config/docker/daemon.json - 设置了
XDG_CONFIG_HOME的 Rootless 模式:$XDG_CONFIG_HOME/docker/daemon.json - Docker Desktop:应通过 Docker Desktop 的设置界面修改 Docker Engine 配置
可以先检查当前上下文、进程和 systemd 服务:
1 | |
2. 校验配置文件
1 | |
除了 JSON 语法,还要检查同一个选项是否同时出现在 ExecStart 参数和配置文件中。
3. 重启服务并立即查看日志
只修改 daemon.json 时,通常直接重启 Docker 即可:
1 | |
systemctl daemon-reload 用于重新加载 systemd 单元或 drop-in 文件;仅修改 daemon.json 时,它不是关键步骤。
4. 验证配置和实际请求
1 | |
不要只依赖配置文件“看起来正确”。docker info 用于确认守护进程当前报告的配置,实际拉取则用于验证 DNS、TLS、代理、镜像服务和上游仓库是否共同可用。
5. 检查 DNS、TLS 和出口网络
1 | |
访问 /v2/ 返回 401 Unauthorized 并不一定是故障,它通常表示网络和 TLS 已经连通,只是当前请求没有携带认证信息。连接超时、DNS 解析失败和证书验证失败则需要分别排查。
6. 检查 Docker 守护进程的代理
终端里设置的代理不一定会自动传给由 systemd 启动的 Docker 守护进程。组织网络需要代理时,可以在 daemon.json 中配置:
1 | |
也可以通过 systemd drop-in 设置 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY。修改后要重启 Docker,并用下面的命令核对 systemd 实际加载的环境变量:
1 | |
五、什么时候才需要修改 systemd 启动命令
只有日志明确显示启动参数与 daemon.json 冲突,或者确实需要改变 Docker 的监听地址等启动行为时,才考虑创建 systemd drop-in。
例如,Ubuntu 的 systemd 单元可能通过 -H fd:// 指定监听方式;如果又在 daemon.json 中设置 hosts,相同配置会发生冲突。此时应根据日志和 Docker 官方文档消除重复项,而不是为了“强制读取配置”盲目加入 --config-file。
修改 systemd 配置后才需要执行:
1 | |
六、重装应当是最后手段
配置未生效不等于 Docker 安装已经损坏。重装之前,至少应完成以下检查:
- 确认安装的是 Docker Engine、Rootless Docker 还是 Docker Desktop。
- 确认修改了对应运行方式的配置文件。
- 使用
dockerd --validate校验配置。 - 检查
journalctl中的明确错误。 - 排除参数冲突、代理、DNS、TLS 和镜像服务自身故障。
如果已经确认软件包混装或系统状态确实无法恢复,可以卸载 Docker 软件包:
1 | |
卸载软件包不会自动删除 /var/lib/docker 和 /var/lib/containerd 中的数据。下面的命令会永久删除本地镜像、容器、数据卷等内容,不能作为普通排障步骤:
1 | |
只有在已完成必要备份、确认数据不再需要,并且确实要进行全新初始化时,才能执行删除。
七、wget 无法建立 SSL 连接
系统时间错误是证书校验失败的一种原因,但不是唯一原因。CA 根证书过期、代理或网关替换证书、DNS 异常、服务端 TLS 配置不兼容,也可能造成类似现象。
先检查时间和时区:
1 | |
需要时启用 NTP:
1 | |
如果时间正确,再检查证书包和详细连接日志:
1 | |
不建议用 --no-check-certificate 作为长期解决方案,因为它绕过了证书身份校验,只会隐藏真正的问题。
八、总结
这次记录中最重要的经验不是“重装能解决问题”,而是排障结论必须由证据支撑:
- 默认配置路径存在,不代表配置内容一定正确。
- 启动参数中没有
--config-file,不代表 Docker 没有读取默认配置。 - 服务成功重启,不代表镜像地址和网络链路一定可用。
- 某次重装后问题消失,只能证明环境状态发生了变化,不能反推唯一根因。
按照“确认运行方式 → 校验配置 → 查看日志 → 验证网络 → 最后考虑重装”的顺序,更容易找到真正原因,也能减少不必要的数据风险。
