我用Buildah的那些“惊喜”:从期待到怀疑人生
编辑我用Buildah的那些“惊喜”:从期待到怀疑人生
作为一个常年跟容器打交道的开发,我对"无守护进程构建"的执念近乎偏执——毕竟谁也不想在CI服务器上天天跟Docker daemon的权限问题死磕。所以当听说Buildah能脱离daemon搞事情,还支持Rootless模式时,我仿佛看到了容器构建界的光。
直到我真的把它请进了生产环境。
性能:说好的轻量,怎么比Docker还磨洋工?
第一次用Buildah构建一个多阶段的Node.js项目时,我差点以为自己的服务器CPU被降频到了386时代。同样的Dockerfile,Docker BuildKit跑3分钟完事,Buildah硬是磨了12分钟——不是网络问题,就是纯纯的"卡"。
后来翻源码才发现,这货对多阶段构建的理解堪称"古早味":不管阶段之间有没有依赖,一律按顺序排队。前端npm install和后端go build明明可以并行,它偏要等前端装完所有node_modules,再慢悠悠开始处理后端。就像你点了汉堡和可乐,服务员非说"先做汉堡,做完再给你开可乐",理由是"流程规定"。
更绝的是缓存机制。Dockerfile里改个注释,BuildKit能聪明地跳过所有不变的步骤,Buildah却像被踩了尾巴的猫——"你动了文件!所有缓存全 invalid !重来!"有次我只是在COPY指令前加了个空行,结果整个项目从基础镜像开始重新构建,看着控制台滚动的"apt install",我怀疑它是故意报复我。
最离谱的是拉取基础镜像。同样的阿里云加速器,Docker拉个ubuntu镜像秒完,Buildah能卡在"Pulling layer"一动不动,进度条跟死机了一样。后来发现它默认不支持镜像分片下载,大镜像只能硬生生"单线程裸奔",在这个HTTP/3都普及的年代,这操作简直像在用拨号上网。
体验:为了"无守护进程",我付出了多少智商税?
Buildah的命令设计,总给我一种"为了不一样而不一样"的叛逆感。Docker用 build
,它偏要叫 bud
(Buildah Under Docker);Docker的 --tag
简化成 -t
,它偏要完整写 --tag
,还得加个 --format oci
才能生成标准镜像——每次写构建脚本都得翻文档,生怕少个参数前功尽弃。
集成到CI流水线时更是灾难。GitLab CI里跑Buildah,必须加 --storage-driver vfs
才能避免权限报错,而vfs这货性能差到离谱,原本3分钟的构建直接膨胀到20分钟。后来换成Rootless模式,以为能清净点,结果 buildah unshare
命令偶尔会抽风,把整个构建目录的权限搅成一锅粥,容器里的文件突然就"permission denied",排查两小时发现是Buildah的用户命名空间没同步好。
最反人类的是错误提示。一次构建失败,日志里只甩了句"error building at step {Env: SHELL=/bin/sh Command: [/bin/sh -c npm run build]}",至于npm到底报了什么错、哪行代码有问题,完全没说。不像Docker会把命令输出完整打出来,Buildah仿佛在说:"我知道错了,但我就不告诉你具体哪错了,你猜?"
结语:我还在等那个"理想型"Buildah
平心而论,Buildah的Rootless设计、OCI标准兼容这些理念是真的香,对于追求安全和标准化的场景来说,它的存在很有必要。但现在的体验,就像买了辆概念车——理念超前,却总在半路抛锚。
或许未来某一天,它能把BuildKit的并行构建学过来,把缓存机制优化得聪明点,再把命令行体验打磨得友好些。但至少现在,我在CI里又默默换回了Docker BuildKit——毕竟开发已经够苦了,谁也不想在构建工具上再渡劫。
Buildah,爱过,但下次还敢不敢再快点?
- 0
- 0
-
分享