记录 k8s 中,使用 kaniko 遇到的坑。

46 天前
 justdoit123
最近在折腾用 argo workflow 搭建 CI 。在处理 kaniko build 镜像的那一步,感觉遇到了几个坑。简单记录一下,以供参考。

1. kaniko build 很慢。因为每次都要从上游 pull 镜像。
2. Dockerfile 里有 VOLUME 指令,会导致对应的目录被 ignored 。
3. COPY 命令不会自己解软链。


后两个都没什么好说的。知道了就能避坑。主要讲讲第一个问题。


kaniko 的 build 感觉比 docker 慢很多。除了这个 issue https://github.com/GoogleContainerTools/kaniko/issues/875 里提到的优化参数可以使用外,最主要的一点是节点与 registry 之间的网络要非常非常的好。

因为 kaniko 的 build 不像你在本地使用 docker 那样会加载本地已经存在的 base 镜像。kaniko 可以理解为没有 “本地” 这个概念,每一次的 build 都要从 registry 拉取 base 镜像。企业使用 AWS 之类的这些云服务,他们的节点与各大 registry 之间的网络通常都非常好,所以使用他们这些服务的人自然感受不到每次拉取 base 镜像带来的影响。自建的 k8s 集群要解决这个问题,有两种方案:

1). 自己缓存镜像到一个 pv 上,每次使用 /kaniko/warmer 命令预热。首次预热,会把镜像存储到 pv 上,后续预热都会跳过。不过这个方案存在一个 OCI 兼容性 bug ,官方至今未解决。见 issue https://github.com/GoogleContainerTools/kaniko/issues/2423

2). 在集群内,自建一个 registry 镜像服务。kaniko 有映射 registry 的参数,把各大 registry 的地址都映射到这个自建的镜像服务上。这样,首次构建后由于镜像服务上已经有了 base 镜像,下次在构建的时候就会快很多。虽然 kaniko 每次 build 还是要重新 pull 镜像。但是由于两个 “节点” 都在同一个区域集群里,他们的通讯非常快。影响也就很小。
1386 次点击
所在节点    Kubernetes
9 条回复
perfectlife
46 天前
ci 里 kaniko 和 buildkit 都用过 ,我是在 k8s 里面做的 ci 构建,运行时是 containerd ,实际感受 速度都不多,算上 pod 的调度创建时间,kaniko 这一步一般花费一分钟以内,ci 中注意基础镜像从公司内部的镜像仓库下载,产物也是 push 到公司的镜像仓库里,如果用弹性容器啥的,还可以设置缓存镜像的列表,避免基础镜像每次都重新拉取,
jackge0323
46 天前
至今都没明白为什么在 Dockerfile 中使用 RUN go install 安装的执行文件,在接下来运行的时候提示命令找不到,就感觉 kaniko 是个只读文件系统。
justdoit123
46 天前
@perfectlife 嗯,最主要的就是从基础镜像要跟 ci 在一个区域。


@jackge0323 会不会也是被 ignore 了?可以加上 --verbosity=trace 参数看看更详细的日志信息。
jackge0323
46 天前
@justdoit123 感谢,回头我排查下,现在的解决方案是我自己 build 了一个 kaniko 的镜像,把这些工具直接打包进去了。
homolabby
46 天前
还有不支持 --mount 这个 dockerfile 命令,导致缓存很难受
BeautifulSoap
46 天前
lz 还没提到 kaniko 的另一个问题,kaniko 无法构建多平台镜像(对应 docker buildx )
kaniko 的多平台镜像构建是让你分别在不同平台的 k8s 节点上构建对应平台的镜像分别 push 到 registry ,然后再用 Manifest 工具手动合并。当我看到这个问题的时候就直接放弃 kaniko 乖乖 DInD 了。在我个人的集群上花这时间折腾这方面实在没意义,又不是工作,DInD 性能差点就差点吧又不是不能跑
justdoit123
44 天前
@BeautifulSoap 我感觉这玩意主要是给企业用户使用的,个人用 DInD 省心多了。一些需求,对企业用户来说感觉不迫切,反正有的是资源,所以也没动力去做。

我之前也是使用 DInD ,之所以折腾这玩意,只是为了实践公司的工具链。
justdoit123
44 天前
@BeautifulSoap 说到交叉 build 。我之前遇到一个镜像架构的问题,一个感受是这方便的定义貌似比较混乱。不知道这样感觉对不对,有的用 tag 区分,有的定义在 manifest 里。docker pull 有个 --platform 参数,但是自己试了没用。

感觉遇到“镜像标准”相关的问题的时候,比较摸黑,解决起来没太多思路。镜像的标准应该怎么学?读 https://github.com/opencontainers/distribution-spec/blob/main/spec.md 这玩意吗?
guanzhangzhang
35 天前
@jackge0323 #2 kaniko 是解开 rootfs 进去执行的,自己实现了一个解析器去搞的,所以必须要 root 权限

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/1095739

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX