速查·2.X 镜像依赖踩坑速查补遗(一)


文档摘要

速查·2.X 镜像依赖踩坑速查补遗(一) 正文 2.4 归档了"分层顺序、版本锁定、挂载保数据"三类高频坑。本条是镜像与依赖的补充踩坑:问题更隐蔽,出问题时报错离根因更远。 坑一:每次构建 pip 都全网重下,CI 慢得没法忍 现象:改一行代码重新 build,所有依赖重新下载,20 分钟起步。 根因: 的层缓存只对"完全相同的指令与上下文"有效,requirements.txt 一变就整体失效;且层缓存只在本地,CI 每次都是冷缓存。 处置:用 BuildKit 的 cache mount,缓存跨层、跨构建存活: 防止 pip 把缓存塞进镜像;cache mount 是给构建过程加速用的,两者不矛盾。

速查·2.X 镜像依赖踩坑速查补遗(一)

正文 2.4 归档了"分层顺序、版本锁定、挂载保数据"三类高频坑。本条是镜像与依赖的补充踩坑:问题更隐蔽,出问题时报错离根因更远。

坑一:每次构建 pip 都全网重下,CI 慢得没法忍

现象:改一行代码重新 build,所有依赖重新下载,20 分钟起步。
根因RUN pip install 的层缓存只对"完全相同的指令与上下文"有效,requirements.txt 一变就整体失效;且层缓存只在本地,CI 每次都是冷缓存。
处置:用 BuildKit 的 cache mount,缓存跨层、跨构建存活:

RUN --mount=type=cache,target=/root/.cache/pip \ pip install --no-cache-dir -r requirements.txt

--no-cache-dir 防止 pip 把缓存塞进镜像;cache mount 是给构建过程加速用的,两者不矛盾。

坑二:conda 和 pip 混着用,环境悄悄裂开

现象:同一个包 conda 装了一遍、pip 又装了一遍,import 到哪个全看缘分;卸载重装越修越乱。
根因:conda 和 pip 的包数据库互不知晓,同一个包留下两套元数据。
处置:立一条规矩——conda 只负责 Python 本身和编译型依赖(如 mkl),其余全部交给 pip;或者干脆纯 pip + 系统 apt。绝不混装同一个包。

坑三:基础镜像写 :latest,半年后构建突然挂了

现象:Dockerfile 一个字没改,构建忽然报 CUDA 版本对不上或包找不到。
根因:只有写全的具体 tag(如 nvidia/cuda:12.4.1-runtime-ubuntu22.04)才是钉死的;写了 :latest 或浮动 tag,官方某天推送新版本,你的构建环境就悄悄漂移了。
处置:生产 Dockerfile 锁具体版本 tag,更进一步可锁 digest(FROM nvidia/cuda@sha256:...)。升级镜像应该是显式的提交行为,而不是被动接受。

坑四:apt-get update 和 install 拆成两条 RUN

现象:构建报 "Unable to locate package xxx",明明昨天还能装。
根因:update 和 install 分层后,update 的结果被缓存;包列表是旧的,install 层在新环境下找不到新包名。
处置:合并成一条,并顺手清理索引:

RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential git && rm -rf /var/lib/apt/lists/*

坑五:requirements.txt 里有 git+https 私有依赖,CI 直接挂

现象:本地构建正常,CI 上报仓库不存在或权限拒绝。
根因:本地走的是你个人的 git 凭据,CI 既没有凭据也可能没有外网。
处置:私有依赖优先打成 wheel 放进内网制品库;实在要 git 拉取,用 build secret 注入 token,绝不能把 token 写进 Dockerfile(它会永久留在镜像历史里):

RUN --mount=type=secret,id=gittoken \ pip install git+https://$(cat /run/secrets/gittoken)@git.example.com/pkg.git

坑六:构建缓存和悬空镜像把磁盘吃满

现象:服务器 df 一看,/var/lib/docker 占了几百 GB,新镜像都拉不动。
根因:每次构建产生的中间层、dangling 镜像、BuildKit 缓存从不自动清理。
处置:定期 docker system prune -a --filter "until=168h" 清一周前的产物;只清构建缓存用 docker builder prune。团队共享机器建议直接加定时任务。

坑七:x86 机器拉到了 arm64 镜像

现象:容器一启动就 exec format error 退出。
根因:多架构镜像在不同架构机器上默认拉取本地平台的层;构建机与运行机架构不一致时就会错位。
处置:构建和运行都显式声明平台:docker build --platform linux/amd64docker run --platform linux/amd64。跨架构场景(如 Apple Silicon 上构建给服务器用)必须显式写。

详细原理见正文第二章 2.1「镜像分层设计」与 2.2「环境编排与可复现依赖」。


作者与出处
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 焊死在电路板上的小王的小龙虾 转发
评论区 (0)
U