Jenkins并发docker构建报错:failed to set parent
我司发布平台的docker打包是基于jenkins执行的,可以想象多个构建任务并发在jenkins机器上执行docker build命令。
问题
然而在很偶然的情况下,会出现某个构建任务失败的情况,发现其报错如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
Step 1/7 : ARG BASE_IMAGE Step 2/7 : FROM ${BASE_IMAGE} ---> 6a852d261d52 Step 3/7 : ARG DEPLOY_ROOT ---> Using cache ---> 1a9230ca8aff Step 4/7 : WORKDIR /root ---> Using cache ---> 5b8a7e510841 Step 5/7 : COPY app.tar.gz nginx.tar.gz ./ failed to export image: failed to set parent sha256:_5b8a7e51084_15d5bff7f375c7ccfc605fa9aab9c46630410cc0949c337ea397f: unknown parent image ID sha256:5b8a7e5108415d5bff7f375c7ccfc605fa9aab9c46630410cc0949c337ea397f |
显然这是docker build的过程中失败,构建第5层的时候发现第4个临时层不见了。
分析
简单思考后,我意识到可能与我推送完harbor后执行docker rmi删除本地image有关。
当多个docker build并行时,它们的中间层因为是一样会被复用,中间层就是磁盘上一个目录而已。
然而当A镜像构建结束的时候,B镜像正处在第5步(希望取第4步缓存的中间层),此时我docker rmi删除了A镜像,该rmi命令默认行为是删除A镜像自身以及其所有没有被其他镜像引用的父镜像。
因为B镜像是构建过程中,它其实还没有明确的产生对中间层5b8a7e510841的依赖关系,所以该层会随着A的删除而删除,导致B接下来找不到该中间层。
解决思路
之前push harbor后立即删除本地镜像是为了尽可能节省jenkins机器磁盘,然而实际运行中发现磁盘空间非常富裕,所以为了避免该错误的偶然出现影响用户体验,决定push后不做rmi删除。
而是由运维定时根据磁盘容量,执行docker自带的镜像清理命令(作为定时任务可以加-f参数跳过人工确认):
docker system prune
它会删除没有运行中容器使用的所有镜像,从而释放出磁盘空间,所以可以放在某个凌晨的时候进行清理即可。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~

你的思路完美的解决了我环境中出现的问题