docker image 分层的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
guoguobaba
V2EX    Linux

docker image 分层的问题

  •  
  •   guoguobaba 2023-07-14 12:00:43 +08:00 2303 次点击
    这是一个创建于 896 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不知道有人碰到过没有

    就是 gitlab ci 的时候,会 build docker image ,再 push 到 registry 上,我用的是公有云 的容器镜像服务,所以希望每次 push 都能做到尽可能小的增量

    project 是 java springboot 的工程,每次都会生成一个 jar 包,这个 jar 包大概 200m ,如果 用类似 COPY xxxx.jar /app

    这样的 Dockerfile ,每次 jar 这一层就要上传 200m+

    所以采用了 jar 包分层的技术,用 $ java -Djarmode=layertools -jar target/xxx.jar extract 得到四个目录,

    Step 7/11 : COPY dependencies/ /app ---> 9831e5b6f9ae Step 8/11 : COPY spring-boot-loader/ /app ---> 82f47422bade Step 9/11 : COPY snapshot-dependencies/ /app ---> 24658da80ea8 Step 10/11 : COPY application/ /app ---> 6d47ede4decb 

    这样每次 ci 的时候,前三个目录基本没有变化,这样生成 docker image 的 layer 是不变的 ,每次 push 只会 push step 10 之后的内容

    这种方法在本地没有问题 mvn clean package... docker build -t ..., docker push ...显示只需要 push 最后一个 layer

    e44c9b0a313a: Pushed 5732f7831cbe: Layer already exists 48d1ef8e0017: Layer already exists 025a15bbce04: Layer already exists 8460ea9541f4: Layer already exists de24004afe49: Layer already exists a52fcbff5465: Layer already exists 767f936afb51: Layer already exists 

    然后在 gitlab ci 里,显示每次还是要 push 多个 layer

    看了一下日志,每次 gitlab ci 里 build 的时候,

    Status: Downloaded newer image for ccr.ccs.tencentyun.com/.../xx:latest ---> 08909e73839f Step 2/11 : ENV AppName xxx-system ---> Running in b66bf82ba02d 

    Step1 的 hash 值是一样的,但是 Step 2 的 hash 值就发生变化了,理论上相同的操作应该产 生相同的 hash 值

    10 条回复    2023-09-28 17:49:54 +08:00
    sadfQED2
        1
    sadfQED2  
       2023-07-14 12:06:56 +08:00 via Android
    分阶段编译?
    Lax
        2
    Lax  
       2023-07-14 12:13:24 +08:00
    "理论上相同的操作应该产 生相同的 hash 值" --- 这句话,是那个文档里说的?
    ziwen1943
        3
    ziwen1943  
       2023-07-14 12:23:35 +08:00   1
    分层逻辑失败变成全量 docker 构建的原因主要有两个,第一是编译用基础镜像每次都会重新下载或者变动,那么第一层就变动了,后续也要重新来,第二种就是删除了历史的 image ,导致分层的逻辑没办法命中历史的缓存层。
    结合你上面的情况,我认为是 gitlab-ci 每次编译的时候都启用了一个新环境(可能是 docker 模式的 gitlab-runner )导致编译都是全新编译,但是上传的时候缓存层在 hub 里面存在,然后出现全新打包,缓存上传的局面了。
    ( ps 如果是 shell 模式的 gitlab-runner ,你需要看一下.gitlab-ci.yaml 文件里面是不是加了 docker rm 的命令删除旧的镜像,因为我就是这么干的,为了节约磁盘空间,为了全新打包避免遗漏)
    liantian
        4
    liantian  
       2023-07-14 12:30:15 +08:00 via iPhone   1
    别用 docker build…换 buildah 就是啦…

    buildah 一次 build 是一层,多余文件清理掉就好。
    iBugOne
        5
    iBugOne  
       2023-07-14 13:05:23 +08:00 via Android   1
    docker build --cache-from 拉下来的镜像

    docker 默认不会复用拉下来的镜像里的层,所以每次都等于全新 build ,需要用 cache-from 钦点 docker 去尽量复用已有的层
    newaccount
        6
    newaccount  
       2023-07-14 13:08:52 +08:00
    baseimage 不要使用 latest ,固定版本试一下呢?
    xiaobai1213
        7
    xiaobai1213  
       2023-07-14 13:36:40 +08:00
    看一下 gitlab-ci 使用的 runner 模式,有的 runner 模式是不会存储之前的工作空间的,这样就会无法命中缓存层,导致每一次都是全量构建

    "理论上相同的操作应该产 生相同的 hash 值" 这个是在官方文档里面看到的吗? 之前有试验过 同样命令同一份代码同一个 maven 打出来的两个 jar 最后算出来的 sha1 都是不一样的......
    Masoud2023
        8
    Masoud2023  
       2023-07-14 13:44:18 +08:00
    你 Gitlab 里的 docker 根本没配置缓存吧?

    不过看这帖子也学习到了,原来 jar 包还能这么拆开。。
    guoguobaba
        9
    guoguobaba  
    OP
       2023-07-14 13:51:11 +08:00
    @iBugOne best solution
    每次 gitlab runner 起的是一个新环境,所以 ci 脚本增加下面的就完美解决了
    ```
    - docker pull $IMAGE || echo "no image"
    - docker build --cache-from $IMAGE -t $IMAGE .
    ```

    看了一下 job 的运行时间,从 109s 下降到 29s

    特别是我可以开启我之前购买的屮蛋的天翼云主机做 runner 服务器了,他只有 1m 的带宽,用完成 jar 包的 image 上传要 25 分钟以上,现在每次 ci ,只需要 2-3 分钟了。
    guoguobaba
        10
    guoguobaba  
    OP
       2023-09-28 17:49:54 +08:00
    汇报一下,这个问题主要是 gitlab ci 是 docker:dind 对应的/var/lib/docker 目录都从
    内存中生成导致每次都需要重新下载 image
    所以设置一个 pvc ,缓存/var/lib/cache 就可以了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3856 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 04:12 PVG 12:12 LAX 20:12 JFK 23:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86