当前位置: 首页 > news >正文

使用 Buildah 创建小体积的容器

我最近加入了 Red Hat,在这之前我在另外一家科技公司工作了很多年。在我的上一份工作岗位上,我开发了不少不同类型的软件产品,这些产品是成功的,但都有版权保护。不仅法规限制了我们不能在公司外将软件共享,而且我们在公司内部也基本不进行共享。在那时,我觉得这很有道理:公司花费了时间、精力和预算用于开发软件,理应保护并要求软件涉及的利益。

时间如梭,去年我加入 Red Hat 并培养出一种完全不同的理念。Buildah 项目是我最早加入的项目之一,该项目用于构建 OCI (Open Container Initiative) 标准的镜像,特别擅长让你精简创建好的镜像的体积。那时 Buildah 还处于非常早期的阶段,包含一些瑕疵,不适合用于生产环境。

刚接触项目不久,我做了一些小变更,然后询问公司内部 git 仓库地址,以便提交我做的变更。收到的回答是:没有内部仓库,直接将变更提交到 GitHub 上。这让我感到困惑,将我的变更提交到 GitHub 意味着:任何人都可以查看这部分代码并在他们自己的项目中使用。况且代码还有一些瑕疵,这样做简直有悖常理。但作为一个新人,我只是惊讶地摇了摇头并提交了变更。

一年后,我终于相信了开源软件的力量和价值。我仍为 Buildah 项目工作,我们最近遇到的一个主题很形象地说明了这种力量和价值。这个标题为 Buildah 镜像体积并不小? 的工单由 Tim Dudgeon (@tdudgeon) 提出。简而言之,他发现使用 Buildah 创建的镜像比使用 Docker 创建的镜像体积更大,而且 Buildah 镜像中并不包含一些额外应用,但 Docker 镜像中却包含它们。

为了比较,他首先操作如下:

 
 
  1. $ docker pull centos:7
  2. $ docker images
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. docker.io/centos 7 2d194b392dd1 2 weeks ago 195 MB

他发现 Docker 镜像的体积为 195MB。Tim 接着使用 Buildah 创建了一个(基于 scratch 的)最小化镜像,仅仅将 coreutilsbash 软件包加入到镜像中,使用的脚本如下:

 
 
  1. $ cat ./buildah-base.sh
  2. #!/bin/bash
  3. set -x
  4. # build a minimal image
  5. newcontainer=$(buildah from scratch)
  6. scratchmnt=$(buildah mount $newcontainer)
  7. # install the packages
  8. yum install --installroot $scratchmnt bash coreutils --releasever 7 --setopt install_weak_deps=false -y
  9. yum clean all -y --installroot $scratchmnt --releasever 7
  10. sudo buildah config --cmd /bin/bash $newcontainer
  11. # set some config info
  12. buildah config --label name=centos-base $newcontainer
  13. # commit the image
  14. buildah unmount $newcontainer
  15. buildah commit $newcontainer centos-base
  16. $ sudo ./buildah-base.sh
  17. $ sudo buildah images
  18. IMAGE ID IMAGE NAME CREATED AT SIZE
  19. 8379315d3e3e docker.io/library/centos-base:latest Mar 25, 2018 17:08 212.1 MB

Tim 想知道为何 Buildah 镜像体积反而大 17MB,毕竟 pythonyum 软件包都没有安装到 Buildah 镜像中,而这些软件已经安装到 Docker 镜像中。这个结果并不符合预期,在 Github 的相关主题中引发了广泛的讨论。

不仅 Red Hat 的员工参与了讨论,还有不少公司外人士也加入了讨论,这很有意义。值得一提的是,GitHub 用户 @pixdrift 主导了很多重要的讨论并提出很多发现,他指出在这个 Buildah 镜像中文档和语言包就占据了比 100MB 略多一点的空间。Pixdrift 建议在 yum 安装器中强制指定语言,据此提出如下修改过的 buildah-bash.sh 脚本:

 
 
  1. #!/bin/bash
  2. set -x
  3. # build a minimal image
  4. newcontainer=$(buildah from scratch)
  5. scratchmnt=$(buildah mount $newcontainer)
  6. # install the packages
  7. yum install --installroot $scratchmnt bash coreutils --releasever 7 --setopt=install_weak_deps=false --setopt=tsflags=nodocs --setopt=override_install_langs=en_US.utf8 -y
  8. yum clean all -y --installroot $scratchmnt --releasever 7
  9. sudo buildah config --cmd /bin/bash $newcontainer
  10. # set some config info
  11. buildah config --label name=centos-base $newcontainer
  12. # commit the image
  13. buildah unmount $newcontainer
  14. buildah commit $newcontainer centos-base

Tim 运行这个新脚本,得到的镜像体积缩减至 92MB,相比之前的 Buildah 镜像体积减少了 120MB,这比较接近我们的预期;然而,出于工程师的天性,56% 的体积缩减不能让他们满足。讨论继续深入下去,涉及如何移除个人语言包以节省更多空间。如果想了解讨论细节,点击 Buildah 镜像体积并不小? 这个链接。说不定你也能给出有帮助的点子,甚至更进一步成为 Buildah 项目的贡献者。这个主题的解决从一个侧面告诉我们,Buildah 软件可以多么快速和容易地创建体积最小化的容器,该容器仅包含你高效运行任务所需的软件。额外的好处是,你无需运行一个守护进程。

这个镜像体积缩减的主题让我意识到开源软件的力量。来自不同公司的大量开发者,在一天多的时间内,以开放讨论的形式进行合作解决问题。虽然解决这个具体问题并没有修改已有代码,但 Red Hat 公司外开发者对 Buildah 做了很多代码贡献,进而帮助项目变得更好。这些贡献也吸引了更多人才关注项目代码;如果像之前那样,代码作为版权保护软件的一部分放置在私有 git 仓库中,不会获得上述好处。我只用了一年的时间就转向拥抱 开源方式,而且可能不会再转回去了。


原文发布时间为:2018-06-6

本文作者:Tom Sweeney

本文来自云栖社区合作伙伴“Linux中国开源社区”,了解相关信息可以关注“Linux中国开源社区”。

相关文章:

  • Linux-office办公的另外之选
  • Service Mesh服务网格:8种方式简化微服务部署
  • 【Sensors】环境传感器(5)
  • Spring Data 之 Repository 接口
  • 完整性的约束
  • 前端小白入门区块链系列01
  • 关于Visual Studio 2019的前期详情
  • 【AudioVideo】音频应用概述(5)
  • JSON方式封装通信接口
  • 组托管服务帐户(Group Managed Service Accounts,即gMSAs)
  • webpack配置(第四步:html篇(进阶篇))
  • 关于音频文件的上传
  • 技术工坊|解密区块链DApp的代码逻辑,从请求到数据存储都要经历什么?(上海)...
  • bzoj 3670 [Noi2014]动物园
  • 开源PaaS Rainbond v3.6.0正式发布,Service Mesh开箱即用
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • CSS3 变换
  • es6(二):字符串的扩展
  • JS 面试题总结
  • Vue2 SSR 的优化之旅
  • 翻译:Hystrix - How To Use
  • 分布式事物理论与实践
  • 将回调地狱按在地上摩擦的Promise
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 项目管理碎碎念系列之一:干系人管理
  • 学习笔记:对象,原型和继承(1)
  • 一文看透浏览器架构
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 白色的风信子
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • k8s使用glusterfs实现动态持久化存储
  • postgresql行列转换函数
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #pragma预处理命令
  • (145)光线追踪距离场柔和阴影
  • (附源码)计算机毕业设计大学生兼职系统
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (一)appium-desktop定位元素原理
  • (转)shell调试方法
  • (转)Unity3DUnity3D在android下调试
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET 动态调用WebService + WSE + UsernameToken
  • .Net的DataSet直接与SQL2005交互
  • /proc/vmstat 详解
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • [《百万宝贝》观后]To be or not to be?
  • [2023年]-hadoop面试真题(一)
  • [Angular 基础] - 自定义指令,深入学习 directive
  • [Assignment] C++1
  • [fsevents@^2.1.2] optional install error: Package require os(darwin) not compatible with your platfo
  • [Go WebSocket] 多房间的聊天室(三)自动清理无人房间