构建容器时减少磁盘数据重复占用的方法咨询
兄弟,我太懂你面对40G超大镜像文件构建容器时,磁盘被反复复制占满的崩溃感了——毕竟这么大的文件多拷贝一次,都够心疼半天的!结合你的场景,除了你已经用到的--layers=false和TMPDIR设置,还有几个实用的方法可以试试,帮你把磁盘占用压到最低:
换成
podman import替代podman build:你当前用Dockerfile+ADD的方式,Podman在构建过程中会经历好几轮文件复制(比如把镜像文件拷贝到构建上下文、处理镜像层时再复制一次等),自然会产生多份临时数据。而podman import是直接把你的.img文件转换成容器镜像,中间几乎没有多余的复制步骤,理论上最终只会保留镜像里的一份文件。具体命令可以这么写:cat VM_2024-05-15_win11.img | podman import - gitlab.example.com:5050/ci-windows:win11vm-2024-05-15这应该最接近你想要的“直接把img放进容器只存一份”的理想状态。
检查并切换到高效的存储驱动:如果你的Podman当前用的是
vfs存储驱动,那麻烦可大了——它会为每个镜像层做完整的文件复制,完全没有复用机制,40G的文件肯定会被复制好几次。建议换成overlay2驱动(绝大多数现代Linux发行版都支持),它采用写时复制(CoW)技术,相同的数据只会存储一次,能大幅减少重复占用。你可以用podman info | grep Storage Driver查看当前驱动,要是不是overlay2,按照Podman的配置文档切换就行(切换前记得备份一下现有镜像哦)。把镜像文件转成稀疏格式:如果你的
VM_2024-05-15_win11.img还不是稀疏文件,里面那些未被使用的“空洞”部分也会占用实际磁盘空间,Podman处理的时候也会把这些空洞当成真实数据复制。你可以用这个命令把它转成稀疏文件:cp --sparse=always VM_2024-05-15_win11.img sparse_win11.img之后用这个稀疏版的文件来构建或导入,能省下不少无效的磁盘占用。
同分区下用硬链接“偷个懒”:如果你的镜像文件和Podman的存储目录(默认是
/var/lib/containers/storage)在同一个磁盘分区里,可以试试用硬链接代替复制。简单来说,就是在Podman会用到的临时目录里给你的img文件创建一个硬链接,这样Podman读取的时候直接用原文件的磁盘块,不会再复制一份。不过这个方法有点“hacky”,需要你对Podman的存储结构有一定了解,要是前两个方法能解决问题,优先用前两个更稳妥。
备注:内容来源于stack exchange,提问作者LordAro

