尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

国内Linux服务器Docker安装:镜像源与daemon.json配置全指南

发布时间:2026/9/29 2:55:31

资讯中心
01
ARTICLE

国内Linux服务器Docker安装:镜像源与daemon.json配置全指南

国内Linux服务器Docker安装:镜像源与daemon.json配置全指南
网上搜 Linux 装 Docker几乎每条教程都会甩给你一条curl ... | sh的命令。早年我也图省事直接复制粘贴后来在几台机器上翻过车才明白一个道理一键安装解决的是“装得上”解决不了“拉得动、跑得稳、管得住”。尤其是国内网络环境里的服务器Docker 引擎装起来往往只需要几分钟拉镜像的加速器和 daemon 配置反而要花掉更多时间。这篇文章不打算复述官方文档的安装步骤而是把我在多台 Linux 机器上验证过的完整路径写出来安装前如何检测内核、发行版、残留环境安装过程中一键脚本内部的几个关键选择装完后国内镜像源怎么配才真正生效daemon.json 里还有哪些配置项直接影响使用体验最后给出一条可复用的故障排查链路。如果你手里的机器是 Ubuntu 22.04、Debian 12 或 CentOS 7照着走基本能一次跑通。1. 安装前先摸清三件事避免把时间浪费在卸载重装上很多“一键装不上”的问题根源不在命令本身。我踩过的第一个坑就是在 CentOS 7 上直接敲官方一键脚本命令执行到一半仓库里的包版本与当前内核不兼容装完之后 docker.service 根本起不来。所以安装之前我会先花十分钟把环境信息完整收集一遍。1.1 内核版本与发行版匹配Docker 依赖 Linux 内核的 cgroups、namespaces、overlayfs 和网络栈。虽然新版 Docker 对内核的要求已经放宽很多但不同发行版预装的内核差异依然会影响最终行为。uname -r cat /etc/os-release以我常用的几套系统为例发行版常见内核版本Docker 兼容性表现Ubuntu 22.045.15基本没有兼容性障碍overlay2 默认正常Debian 126.1cgroup v2建议用较新 Docker 版本CentOS 73.10老内核部分新镜像的 runc 要求较高注意升级内核CentOS 7 的问题最明显。3.10 内核不是说不能跑 Docker而是遇到高并发网络、新版本 runc 或特定存储驱动时报错会很奇怪。如果可以CentOS 7 上不要追新装一个长期稳定版本并且提前记录内核版本是否支持 overlay2。xfs 文件系统下还要判断 ftype 参数这个细节放在后面的优化章节展开。另外x86_64 和 aarch64 的镜像并不完全通用。一键脚本会自动识别架构但如果你在 ARM 开发板上手动拷贝 deb 包很可能装上后启动时报 Exec format error。先执行uname -m确认架构再决定用哪个软件源。1.2 旧环境残留是大多数启动失败的源头如果以前装过 docker、docker.io、podman 或 containerd一键脚本往往不会帮你彻底清理。最常见的现象是安装完成systemctl start docker之后立刻退出日志里出现 containerd 已经被别的进程占用之类的提示。我的习惯是先做一轮“温和清理”systemctl stop docker docker.socket 2/dev/null apt-get remove docker docker-engine docker.io containerd runc 2/dev/null yum remove docker docker-client docker-common docker-engine 2/dev/null这里的温和指的是只卸载软件包不动/var/lib/docker。数据目录里可能还有以前业务用的镜像层和容器卷直接rm -rf的话后续想恢复会非常难受。稳妥做法是把目录改名保留mv /var/lib/docker /var/lib/docker.bak.$(date %F)等新环境验证没问题之后再决定是否把备份目录删除。这个习惯在旧服务器上尤其重要特别是你接手同事留下的机器时。1.3 磁盘空间与数据目录规划镜像、容器日志、临时构建缓存都会占用/var/lib/docker。很多服务器根分区只有 40G一个带模型的基础镜像就能吃掉十几 G。安装前我会检查df -h df -h /var/lib如果/var/lib所在分区剩余空间小于 20G强烈建议在安装前就把>data-root: /data/docker这里有个容易忽略的点data-root 路径的父目录权限。Docker daemon 以 root 运行但目录归属必须清楚。如果是新挂载的数据盘先格式化、建目录给 0755 权限即可。不要反复在/var/lib/docker和自定义路径之间切换否则那些“找不到镜像层”“容器状态丢失”的报错会接踵而来。顺带看一下网络端口。虽然 Docker 默认通过 Unix socket/var/run/docker.sock通信但一旦你开启了 TCP 2375 监听生产环境会暴露很大的安全面。安装前可以用ss -lntp看一眼如果有进程占了 2375先理清楚业务再装 Docker。2. 一键脚本并不神秘它只是把你手工做的事自动化了大多数人喜欢一键脚本是因为它省事。但它到底替你做完了哪些事如果完全不清楚后续排查也会无从下手。2.1 get-docker.sh 的执行逻辑官方脚本 get-docker.sh 本质上是一个“发行版适配器”。它不会自己编译二进制而是做三件事探测当前系统用的是 apt 还是 yum/dnf写入 Docker 官方的软件仓库地址调用对应的包管理器安装 docker-ce、docker-ce-cli、containerd.io 等组件。理解了这一点你就明白为什么直接执行命令和下载下来慢慢看是有区别的。我习惯先把脚本落盘再决定怎么执行curl -fsSL https://get.docker.com -o get-docker.sh less get-docker.sh sh get-docker.sh这不是过度谨慎。脚本里会调用 sudo、systemctl、sed 等权限较高的操作落盘之后你至少能 grep 出危险动作grep -nE curl|wget|rm -rf|chmod|crontab get-docker.sh | head -20虽然官方脚本相对可信但在生产环境机器上这种“先看再执行”的习惯能避免很多意外。2.2 国内服务器上怎么让“一键安装”阶段也走国内源一键脚本默认写入 Docker 官方软件源。在国内服务器上curl 下载依赖包经常跑到超时。官方脚本对此提供了参数sh get-docker.sh --mirror Aliyun这个参数会把 apt 的sources.list.d/docker.list或 yum 的docker-ce.repo替换成阿里云镜像站。安装阶段的包下载速度会有明显提升。需要说明的是它只影响 Docker 软件包本身的下载源不会帮你配置后面拉取镜像的加速器。很多教程把这两件事混在一起说导致用户以为跑了这条命令docker pull 就一定快。实际上镜像加速器是 daemon.json 里 registry-mirrors 的事下一章专门讲。如果你的发行版不是 Debian/Ubuntu 体系而是 Fedora、AlmaLinux 这类基于 dnf 的系统也可以先手工把 repo 文件里的 baseurl 改成国内可信镜像站再执行脚本。注意导入 GPG 密钥这一步不能漏否则安装会被密钥校验拦截。2.3 内网离线安装真正的“一键”反而是配置包有些生产环境没有外网一键脚本再方便也白搭。这种情况我会在另一台相同发行版版本的机器上准备好离线包。CentOS/RHEL 系yum install --downloadonly --downloaddir/opt/docker-offline docker-ce docker-ce-cli containerd.io docker-compose-pluginUbuntu/Debian 系apt-get download docker-ce docker-ce-cli containerd.io docker-compose-plugin然后把整个目录拷贝到目标机分别执行rpm -ivh *.rpm或dpkg -i *.deb。这种方式的“一键”体现在软件包依赖已经解析好目标机不需要访问任何软件源。需要提醒的是离线包版本务必和目标机的内核匹配特别是 containerd 附带的 runc 版本否则容器创建时容易报 unknown version 错误。2.4 对网上的第三方一键脚本保留一点警惕网上流传的很多“Docker 一键安装脚本”会顺手修改系统源、配置计划任务、限制资源上限。有的脚本甚至会替换你的基础 yum 源。我不能武断地说所有脚本都有问题但至少你应该遵守一个底线一段花很长时间还看不太懂的 shell 脚本不要直接 root 执行尤其是以curl | bash形式出现的拆开看的行为完全没有。先把脚本下载下来检查一下或者找官方维护的版本实际上不会多花多少时间。3. 国内镜像源配置把 registry-mirrors 理解透再动手标题里的国内镜像源其实包含两层意思。上文提到的软件仓库源是第一层第二层才是在 Docker 拉取镜像时配置 registry mirror。很多人就是在这里被各种旧教程带偏。3.1 镜像加速器的作用边界registry-mirrors 只对从 Docker Hub 拉取公共镜像有效。它本质上是一个代理或缓存daemon 在请求镜像时先去 mirror 站点已同步的 layer 会被命中命中后速度极快。但这不代表所有镜像都能加速——如果镜像来自别的 registry比如 ghcr.io、quay.io、私有仓库那它根本不会走这个 mirror。另外一个常被忽略的点mirror 站点本身是 Docker Hub 的缓存它同步的是合规、公开的镜像。如果拉一个非常冷门的 tag缓存里没有就要回源时间一样可能很长。所以不要以为配了 mirror 就能解决一切拉取问题。判断 mirror 是否可用不要只信别人的列表。先用 curl 检查 endpoint 是否响应curl -I --connect-timeout 5 https://docker.m.daocloud.io/v2/返回 200 或 401 都说明服务可达。如果直接超时就把这个站点的配置暂时去掉。3.2 一份值得直接抄的 daemon.json配置国内镜像源并不是简单堆 mirror 列表。我在生产环境里一般会参考下面这份基础配置再根据机器情况调整部分项{ registry-mirrors: [ https://docker.m.daocloud.io, https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ], data-root: /data/docker, storage-driver: overlay2, log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, exec-opts: [native.cgroupdriversystemd], max-concurrent-downloads: 6, iptables: true, ip-forward: true }逐项解释一下为什么这么写registry-mirrors只放两到三个即可。Docker 会按顺序尝试太多反而会在第一个失效时增加额外超时。上面是示例不同站点的可用性会随时间变化具体以你自己 curl 验证的结果为准。>python3 -m json.tool /etc/docker/daemon.json确认格式没问题再重新加载配置systemctl daemon-reload systemctl restart docker注意restart 会引起 docker daemon 的短暂不可用。虽然在 containerd 托管下运行中的容器不一定被中止但docker ps、docker exec等操作会暂时卡住所以在有存量业务的机器上尽量选择维护窗口操作。如果只是改 registry-mirrors、日志配置这类可 reload 的项也可以试试systemctl reload docker不过要接受一个事实data-root、storage-driver 这类字段不会热生效改完必须 restart。验证配置是否生效最直接的是看 docker infodocker info | grep -A5 Registry Mirrors输出里能看到你配置的 mirror 列表。然后拉一个最小镜像做冒烟测试docker pull busybox:latest docker run --rm busybox echo ok不要一上来就 pull redis、mysql 这种大镜像。先用 busybox 确定整条拉取链路正常再上业务镜像排查效率会高很多。比如你要搭 redis 主从也要先确认基础拉取没问题再继续。4. 装完之后的配置优化才是日常体验最直接影响因素Docker 装上能启动只是开始。真正影响生产使用的是存储驱动、日志、网络和 cgroup 这些平时不太注意的配置。下面几项是我在多台机器上总结出来的按优先级排序。4.1 存储驱动和底层文件系统是否匹配overlay2 依赖底层文件系统的 d_type 支持。大部分 ext4 没问题但 XFS 在旧内核时代有个坑如果格式化时没有开启 ftype1overlay2 会报没有 d_type support。检查方式df -hT /var/lib/docker xfs_info /var/lib/docker | grep ftype如果 ftype0而你又要在这个目录上用 overlay2基本只有三条路重新 mkfs.xfs 并加上-n ftype1或者改用 ext4或者在 daemon.json 里临时设置 storage-driver 为 vfs。vfs 会复制整个镜像层磁盘占用大只适合临时救急。不要小看这个细节我在一台历史遗留的 XFS 数据盘上装 Docker连续几天都在处理 overlay2 相关报错最后发现根因就是 ftype。新环境最好在安装前就规划好文件系统用 ext4 或 xfs ftype1省得日后迁移。4.2 日志体积是磁盘最大暗雷运行中的容器每打一条日志json-file 文件就会增长。系统默认是不裁剪的。如果业务日志很频繁一晚上就能写进去 10G。daemon.json 里配置过 log-opts 之后只对之后创建的容器生效已经存在的容器要么 recreate要么手动清理。手动清理前先定位du -sh /var/lib/docker/containers/*/*-json.log find /var/lib/docker/containers -name *-json.log -size 100M -exec ls -lh {} \;如果业务不允许重启容器可以临时清空某个超大日志文件truncate -s 0 /var/lib/docker/containers/container-id/container-id-json.log这里要特别说明一个细节不要用rm删除日志文件。某些版本的 Docker 会保持文件句柄删了之后磁盘空间并不会释放只有重启才能恢复正常。truncate把文件截断为 0 则没有这个问题。更彻底的做法是用docker system prune清理无用的镜像和构建缓存但 prune 不会动正在运行的容器。真正要收紧日志还是靠 daemon.json 里的全局 log-opts或者每个容器单独传参数。4.3 网络转发和防火墙容器要访问外网依赖宿主机开启 IPv4 转发sysctl net.ipv4.ip_forward如果输出 0就需要写入 sysctl.confecho net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -pdocker.service 启动时会尝试开启 ip_forward但有些云镜像有加固策略会把配置改回 0。所以容器网络不通时第一反应不是去看容器内部而是先看宿主机的 ip_forward。另一个容易忽略的是 iptables FORWARD 链默认策略。只要 FORWARD 是 DROP即使 ip_forward 已开容器流量也会被卡住。检查如下iptables -L FORWARD -n -v如果不确定哪条规则导致问题可以在测试环境先临时把策略改成 ACCEPT 验证生产环境则需要按你的安全策略精准放行。Docker 本身会往 iptables 写入 DOCKER 链实现端口映射和容器间通信。如果你在宿主机上再跑一个 firewalld要特别小心重启防火墙后覆盖掉 Docker 的规则。常见现象是防火墙重启容器端口映射失效外部访问不了发布的服务。这种问题的解决路径不是去容器里改配置而是看 iptables 的 nat 表里 DOCKER 链是否还在iptables -t nat -L -n | grep DOCKER很多人在容器网络问题上绕远路往往是因为没从宿主机网络栈这个角度切入。4.4 cgroup v2 与 systemd 的协作新发行的 Debian 12、Ubuntu 22.04 默认使用 cgroup v2。Docker 20.10 及更高版本都支持但在 cgroup 驱动选择上要注意。如果宿主机直接被 systemd 管理Docker 的 cgroup 驱动与 systemd 保持一致会更顺滑尤其是在后续要接入 Kubernetes 或使用 systemd 管控容器资源时。查看当前驱动docker info | grep -i Cgroup如果显示 cgroupfs而你确认自己环境里有 systemd 强依赖就在 daemon.json 里保留exec-opts: [native.cgroupdriversystemd]改完重启 docker再次确认。要注意的是这个配置如果与底层运行时版本严重不匹配反而会启动失败。所以升级 Docker 版本后同样要再看一眼 Cgroup Driver避免配置残留。5. 故障排查链路不是玄学是顺序问题下面这段是踩坑实录不是官方问答。我遇到的大部分问题其实都可以通过一套固定的排查顺序快速定位。原则很简单docker 服务起不来先看日志镜像拉不下来先验证网络容器网络不通先查内核转发。把顺序理顺大部分问题都能在十分钟内定位。5.1 docker.service 起不来最常见的报错是Job for docker.service failed because the control process exited with error code.看到这个先别急着卸载重装。排查顺序如下systemctl status docker.service --no-pager journalctl -u docker.service -n 50 --no-pager日志里出现 JSON 解析错误就去检查 daemon.json。出现 overlay 相关错误就去确认存储驱动与文件系统。出现 containerd 被占用就去检查是不是有老的 dockerd 或 cri-containerd 进程还在。一个很隐蔽的原因daemon.json 里>docker run --rm busybox ping -c 1 114.114.114.114 # 通 docker run --rm busybox nslookup www.example.com # 失败或超时问题不在镜像而在 resolv.conf。很多 Linux 发行版默认使用 systemd-resolved宿主机/etc/resolv.conf指向 127.0.0.53。这个地址只对宿主机本机的网络命名空间有效容器是独立的 net namespace访问 127.0.0.53 自然解析不了。解决办法之一是在 daemon.json 中给全局容器配置一个稳定 DNSdns: [223.5.5.5, 119.29.29.29]然后 restart docker。也可以只对单容器指定docker run --dns 223.5.5.5 --rm busybox nslookup www.example.com需要说明的是不建议无脑在 daemon.json 里配置公共 DNS。如果公司内部有私有 DNS应该优先使用内部 DNS 来解析私有域名和外部域名。这里的核心是把容器 DNS 与宿主机命名空间解耦避免 127.0.0.53 这种环回地址渗透进容器。5.4 磁盘被镜像垃圾塞满磁盘明明拉过镜像、跑过构建df -h显示/var/lib/docker占了不少空间。清理方式要分主次用docker system df查看磁盘占用概况docker system prune -a清理所有未被容器引用的镜像这个比较激进执行前先确认不再需要的镜像docker builder prune清理 BuildKit 缓存按照前面日志清理方法处理超大 json 文件。还有一个容易被忽略的场景你反复docker run临时容器容器退出后仍然存在。执行docker container prune可以清除所有已退出的容器定期做一次能释放不少空间。如果清理完还是占用很高不要直接rm -rf /var/lib/docker。先df -hT确认是不是有文件句柄仍被占用的 deleted 文件。处理这种问题的首选是lsof /var/lib/docker找到那个还开着文件句柄的进程。强制删目录往往是最后一招而且删完基本只能重装代价太大。6. 一些技术之外的长期经验最后聊聊我习惯性在安装流程里坚持做的事。不写官方的“最佳实践”只讲个人认为值得参考的经验。6.1 我给自己定的安装检查清单装完后立刻备份 daemon.json路径我用/etc/docker/daemon.json.bak。看似多此一举但后面每次调优前看一眼备份能快速知道自己的改动了什么。排错时这份备份的价值非常大。用一份脚本模板封装安装动作而不是每次都去敲命令。模板里把内核检查、残留清理、软件源切换、daemon.json 写入分开。这样几十台机器批量安装时只有一台出现异常定位成本会低很多。mirror 列表要列入定期检查项。镜像加速站点不会永远可用有些会停止服务有些会调整路径。隔一两个月重新 curl 一遍去掉失效项、补充可用项docker pull 体验就能保持在一个稳定状态。6.2 那些返工后才明白的教训不要把生产环境的/var/lib/docker当临时目录随便折腾。迁移数据根目录之前先停 Docker、再移动数据、再修改>
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。