使用BuildKit构建容器镜像

2021年09月15日 阅读数:2
这篇文章主要向大家介绍使用BuildKit构建容器镜像,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
在本系列有关容器镜像构建的最后一篇文章中,咱们回到Docker的Moby项目,该项目有个名为BuildKit(https://github.com/moby/buildkit)的子项目。
BuildKit是源自Docker的Moby项目的第二代镜像构建工具,自Docker CE 18.09起可用。正如咱们在以前的文章中使用Img所看到的那样,BuildKit不限于仅与Docker一块儿使用。这是一种通用的镜像构建工具,能够做为独立的二进制文件(以守护程序或无守护程序模式使用)也能够做为库来使用。实际上,它能够将构建步骤转换成其低级构建器(LLB)表示形式,BuildKit可用于构建任何工件(artifact)而不只仅是容器镜像。咱们主要在这里关注容器镜像的构建,所以让咱们来看看BuildKit能给咱们带来些什么。


构建步骤优化前端

使用BuildKit构建容器镜像_容器镜像


Docker自己提供的构建常常会让人感到沮丧的一个缘由是Dockerfile指令执行构建步骤的顺序性。引入多阶段构建以后,即可以将同一Dockerfile中的构建步骤按逻辑分组进行。
有时,这些构建彼此彻底独立,这意味着它们能够并行执行-或根本不须要执行。不幸的是,传统的Docker镜像构建没法知足这种灵活性,有时会在不须要时执行构建步骤。这意味着构建时间一般会更长。
相反,BuildKit会建立一个构建步骤之间的依赖关系图,并使用它来决定构建中的哪些步骤省略,哪些能够并行执行;哪些须要顺序执行。这提供了更有效的构建执过程,这对于迭代其应用程序进行镜像构建的开发人员来讲是有价值的。


高效灵活的缓存linux

使用BuildKit构建容器镜像_容器镜像_02


尽管在旧版Docker镜像构建中对构建步骤进行缓存很是有用,但效率却不如预期。经过对构建后端的重写,BuildKit进行了改进,并提供了更快,更准确的缓存机制。它使用为镜像构建生成的依赖关系图,而且基于指令定义和构建步骤内容。
BuildKit提供的另外一个巨大优点来自构建缓存导入和导出的形式。正如Kaniko和Makisu容许将构建缓存推送到远程镜像仓库同样,BuildKit也是如此。可是,BuildKit使你能够灵活地将缓存嵌入到镜像中(内联)并将它们一块儿推送(尽管并不是每一个镜像仓库都支持),或者能够将它们单独推送。缓存也能够导出到本地目录以供之后使用。
当从零开始创建构建环境而没有先前的构建历史可受益时,导入构建缓存的功能将发挥做用。导入可让缓存“热身”,这对于临时CI/CD环境特别有用。


Build Artifactsgit

使用BuildKit构建容器镜像_容器镜像_02


使用旧版Docker构建器构建时,将生成的镜像添加到Docker守护程序管理的本地镜像缓存中。须要单独的docker push将镜像上载到远程镜像仓库。新型镜像构建工具容许你在构建调用时指定镜像推送,从而加强了体验。BuildKit也不例外,它还容许以几种不一样格式输出镜像。本地目录中的文件,本地tarball,本地OCI镜像tarball,Docker镜像tarball,存储在本地缓存中的Docker镜像以及推送到镜像仓库的Docker镜像。格式不少!


扩展语法github

使用BuildKit构建容器镜像_容器镜像


对于Docker构建体验而言,往复出现的众多功能性请求之一就是安全的处理镜像构建过程。Moby项目多年来一直抵制此呼吁。可是,借助BuildKit灵活的“前端”定义,实验性的扩展了Dockerfile语法。扩展语法为RUN Dockerfile指令提供了新的功能,其中包括安全功能。
RUN --mount=type=secret,id=top-secret-passwd my_command

引用实验性前端的Dockerfile能够临时为RUN指令添加secret参数。secret使用docker build的--secret标志实现。一样,使用SSH挂载可启用SSH代理链接的转发,以进行安全的SSH身份验证。
可以以这种方式扩展Dockerfile的语法是BuildKit独有的功能。docker


Consuming BuildKit后端

使用BuildKit构建容器镜像_容器镜像_02


BuildKit具备许多其余功能,这些功能大大改善了构建容器镜像的技术。若是它是适用于许多不一样环境的通用工具,那么如何使用它呢?
根据工做环境的不一样,这个问题的答案也有所不一样。咱们来看一下。


Docker缓存

使用BuildKit构建容器镜像_容器镜像_02


鉴于BuildKit是Moby项目,所以能够将它用做Docker(v18.09 +)的首选构建后端不足为奇了。但它不是默认的后端,由于Windows平台不支持它,而在Linux上构建镜像时很方便使用。
只需设置环境变量(DOCKER_BUILDKIT = 1)便可完成此工做,或将如下键/值对添加到守护程序的配置文件中以永久使用;“features”:{“ buildkit”:true}。
因为Docker守护进程中的某些限制,Docker并未充分发挥BuildKit的所有功能。所以,对Docker客户端CLI进行了扩展以提供插件框架,该框架容许使用插件来扩展可用的CLI功能。一个名为Buildx的实验性插件会绕过守护程序中的旧版构建函数,它使用BuildKit后端进行全部构建。该工具提供了全部熟悉的镜像构建命令和功能,但经过一些特定于BuildKit的附加功能对其进行了扩充。
BuildKit(经过Buildx扩展)支持多个构建器实例。这是一项重要功能,其余镜像构建工具中没有相似功能。它实际上意味着能够出于构建目的共享一组构建器实例。也可能为一个项目分配了一组构建器实例,而另外一个项目则分配了另外一组。
 
 

$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker                  
  default default         running linux/amd64, linux/386安全

默认状况下,Buildx插件以Docker驱动程序为目标,该驱动程序使用Docker守护程序提供的BuildKit库,但存在其固有的局限性。另外一个驱动程序是docker-container,它透明地在容器内启动BuildKit来执行构建。它能够提供BuildKit所有功能。第三个用于Kubernetes的驱动程序可让BuildKit实例以Pod的方式在Kubernetes中运行。这特别有趣,由于它能够启动在Kubernetes中运行的BuildKit的构建——所有来自Docker CLI。这是不是理想的工做流程,这彻底取决于我的或公司的选择。app


Kubernetes框架

使用BuildKit构建容器镜像_容器镜像_02


组织愈来愈多地在临时基础结构之上实现其应用程序工做流,其中包括Kubernetes,一般会在CI/CD工做流程中看到在容器中生成容器镜像。在Kubernetes中运行BuildKit实例时,有许多不一样的配置可用。每种部署策略都有其优势和缺点,而且每种适合不一样的目的。

使用BuildKit构建容器镜像_BuildKit_08


除了使用Docker CLI为BuildKit启动的面向开发人员的构建以外,构建还能够由多种CI/CD工具触发。例如,使用BuildKit镜像构建能够由Tekton Pipeline Task执行。


结论

使用BuildKit构建容器镜像_BuildKit_09


本文没有足够的篇幅介绍BuildKit提供的其余功能,例如多平台镜像和无管理员权限构建。可是,这篇文章介绍了BuildKit在容器镜像构建方面带来的许多重要改进。
尽管许多新一代的构建工具都在寻求解决传统构建过程的弊端,可是BuildKit则试图走得更远而且进行创新。
固然,BuildKit尚处于起步阶段,一些功能须要随着在社区的普及而成熟和发展。受制于足够长但不完善的容器镜像构建经验已有很长时间,面对当今可用的选择,这可能会有些使人困惑。有些人将不可避免地基于从属关系作出选择。适用于Red Hat的Buildah,适用于Google的Kaniko或适用于Docker的BuildKit。可是,能够确定地说,经过当今可用的各类选项,容器镜像的构建工做将变得更加容易。
原文连接:https://www.giantswarm.io/blog/container-image-building-with-buildkit