Docker 镜像越拉越慢?换源加速与镜像瘦身一次讲清
Docker 镜像越拉越慢?换源加速与镜像瘦身一次讲清
刚装好 Docker,第一次 docker pull nginx 就卡在进度条上半天不动;好不容易拉下来,docker images 一看,几个镜像加起来十几 GB,磁盘告急。这是很多新手第一次用 Docker 都会撞上的两堵墙:拉取慢、镜像大。今天一次讲清:怎么换源加速,以及怎么给镜像瘦身。
先搞清慢在哪:镜像拉取的三个环节
一次 docker pull 其实分三步:先向镜像仓库(默认 Docker Hub)查询镜像元数据,再按层(layer)逐一下层文件,最后解压落盘。国内用户卡住,十有八九在第二步——到 Docker Hub 的网络链路不稳,某个大层反复重试,进度条来回横跳。
判断方法很简单:跑 docker pull 时看日志,如果长时间停在 Pulling fs layer 或某个层 Retrying,基本就是网络问题;如果秒过元数据、层下载飞快但解压慢,那是磁盘或 CPU 的问题,两者解法完全不同。
换源:给 Docker 配一个国内镜像加速器
最直接的办法是给 Docker 配镜像加速器(registry mirror)。原理是:拉取请求先走国内的镜像站,镜像站背后会回源到 Docker Hub,你拿到的是缓存,速度通常能快一个数量级。
配置方法(Linux,systemd 管理的 Docker):编辑或新建 /etc/docker/daemon.json,写入 {“registry-mirrors”: [“https://docker.mirrors.ustc.edu.cn”]}(用中科大镜像站举例,实际可用地址以查到的当前可用镜像站为准,配一个即可,不要堆一堆失效地址)。然后重启生效:sudo systemctl daemon-reload && sudo systemctl restart docker。验证:docker info | grep -i -A1 “registry mirrors”,能看到配的地址即生效。
注意两点:第一,加速器只加速拉取,不加速推送;第二,daemon.json 是 JSON,多个配置项要用逗号分隔,写错一个逗号 Docker 就起不来,改完先看 systemctl status docker 确认。
镜像为什么这么大:层层叠加的账
即使拉取快了,镜像体积还是个问题。一个 Python 应用镜像动辄 1GB 以上,原因通常在两处:基础镜像本身就大(python:3.12 约 1GB),以及 Dockerfile 里每条 RUN 指令都会产生一个新层,中间文件(apt 缓存、编译产物、下载的 tar 包)全留在了层里,删都删不掉——因为层是只加不减的。看镜像的层构成:docker history your-image:tag,哪一层几百 MB,一目了然。瘦身就从最大的层下手。
瘦身第一招:换小的基础镜像
同样是 Python 3.12,几个常见基础镜像体积差距很大:python:3.12 约 1GB,带完整 Debian 工具链;python:3.12-slim 约 130MB,只保留运行必需品;python:3.12-alpine 约 60MB,极简 musl 系统。如果应用只是跑一个 Web 服务,slim 通常是最佳平衡点:体积小一个数量级,又保留了 glibc,绝大多数 Python 包都能直接装。Alpine 更小,但 musl 与 glibc 的差异会让某些需要编译的包装不上或装得很慢,新手不建议首选。改法就一行:FROM python:3.12-slim。
瘦身第二招:同一层里装完就清理
常见肥胖写法是三条 RUN 各写一行:apt-get update、apt-get install -y gcc、pip install -r requirements.txt,三层下来 apt 包列表缓存、gcc 安装文件全留下了。正确写法是合并到一层,并在同一层里清理:RUN apt-get update && apt-get install -y --no-install-recommends gcc && pip install --no-cache-dir -r requirements.txt && apt-get purge -y --auto-remove gcc && rm -rf /var/lib/apt/lists/。关键点:–no-install-recommends 不装推荐包;pip install --no-cache-dir 不留 pip 缓存;rm -rf /var/lib/apt/lists/ 清掉 apt 列表。
瘦身第三招:多阶段构建
如果应用需要编译,最干净的做法是多阶段构建:第一阶段用完整工具链编译,第二阶段只把编译产物拷到 slim 镜像里。示例:FROM python:3.12 AS builder,WORKDIR /app,COPY requirements.txt .,RUN pip install --no-cache-dir --target=/deps -r requirements.txt;第二阶段 FROM python:3.12-slim,COPY --from=builder /deps 到 site-packages,COPY . .,CMD [“python”, “app.py”]。最终镜像里只有运行时的依赖,没有编译器、没有中间文件,体积常常只有原来的三分之一。
瘦身第四招:.dockerignore 别忘了
docker build 时构建上下文会整个发给 Docker daemon。目录里有 .git、虚拟环境 venv/、测试数据、几个 GB 的数据集,构建慢、缓存失效还频繁。建一个 .dockerignore,写入 .git、venv/、pycache/、.pyc、tests/、.log。效果和 .gitignore 类似,但很多人第一次写 Dockerfile 都会漏掉它。
日常维护:定期清掉用不上的东西
长期运行的机器上还会攒下停掉的容器、没人用的镜像、悬空的层、构建缓存。先看占用:docker system df,会列出镜像、容器、卷、构建缓存各占多少磁盘。清理:docker system prune 会删停掉的容器、未被使用的镜像和网络;docker system prune -a --volumes 还会清匿名卷。生产机器上别直接照抄 -a,先不带 -a 跑看看会删多少,确认没有要保留的镜像再加 -a;带 --volumes 前先确认没有重要数据只放在匿名卷里。
一张自查清单:拉取慢配 registry-mirrors 并验证 docker info;镜像大换 slim 基础镜像;层里有垃圾就 RUN 合并写、同一层装完即清、–no-cache-dir 常驻;要编译上多阶段构建;构建慢补 .dockerignore;磁盘告急用 docker system df 看占用再分级清理。拉取加速解决的是等得久,镜像瘦身解决的是占得多、传得慢、部署久。两者都不需要换工具、不用花钱,改几行配置就能见效。
- 点赞
- 收藏
- 关注作者
评论(0)