利用Makisu构建容器镜像

2021年09月15日 阅读数:1
这篇文章主要向大家介绍利用Makisu构建容器镜像,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
本系列文章一共6篇,本文是该系列的第5篇文章,前4篇文章以下:


  1. 将来咱们如何构建容器镜像?docker

  2. 利用Podman和Buildah构建容器镜像缓存

  3. 利用Img构建容器镜像安全

  4. 利用Kaniko构建容器镜像app


本系列文章深刻研究了容器镜像构建的最新技术。咱们已经介绍了Podman和BuildahImgKaniko,而此次轮到Makisu了。
Makisu是另外一个开源镜像构建工具,由Uber的工程团队构思而成。像许多其余开源项目同样,Makisu也是基于其余相似技术的不足而开发的。Makisu尤为专一于优化镜像构建时间和大小。curl


使用Makisu分布式

利用Makisu构建容器镜像_容器镜像


相似Kaniko,Makisu不会调用容器并依据Dockerfile指令在容器中构建镜像。它既能够做为独立的二进制文件在本地运行,也能够做为沙箱运行在容器内。可是,因为它没法执行RUN Dockerfile指令,所以它做为独立二进制文件的用途受到限制。固然,你也不但愿Makisu经过RUN指令更改主机的本地文件系统内容!
实际上Makisu不容许更改本地文件;你须要指定标志--modifyfs = true,以容许使用命令对文件系统进行更改。但请注意,若是使用--modifyfs = true运行独立的Makisu二进制文件,最终将删除主机的许多rootfs。Makisu被设计为在容器中运行,在容器中更改文件系统内容是安全的。
实际上用于执行构建的Makisu自己的容器镜像不多。它是基于基本图像指令(scratch base image directive)构建的,仅包含Makisu二进制文件和根CA证书的文件。须要使用卷将构建上下文(包括Dockerfile)提供给容器。
Makisu提取Dockerfile中定义的基本镜像,并将其文件系统提取到其容器内。它还将此文件系统的副本存储在内存中。随后的构建步骤针对该文件系统的内容运行,而后对其进行扫描以查找更改。任何更改也会反映在“内存”的副本中,并建立一个包含更改的新“差别层”。“差别层”层缓存在目录中,以供未来的版本使用,前提是用于存储的卷已经被挂载。
Dockerfile中定义的构建步骤以这种方式执行到完成,而后Makisu将构建的镜像推送到容器镜像仓库(若是已指定)。若是将Docker用做Makisu的容器运行时,则可使用如下命令调用构建容器:
 
 

$ docker run --rm \
      -v $(pwd):/makisu-context \
      -v /tmp/makisu-storage:/makisu-storage \
      gcr.io/makisu-project/makisu:v0.1.12 build \
          --tag=mycorp/my-app:1d03df1 \
          --push=quay.io \
          --modifyfs=true \
          /makisu-contextide

若是你阅读了本系列的上一篇文章,你将已经得出结论,如Kaniko同样,Makisu将采用几乎相同的方法来构建镜像。你能够执行构建步骤而无需Docker守护程序,也无需运行嵌套容器所需的特权帐号。可是 Makisu的突出之处在于其构建缓存实现的方法。工具


缓存优化

利用Makisu构建容器镜像_容器镜像


一旦决定放弃Docker守护进程构建镜像,你将失去其固有的缓存功能。Docker守护程序提供的构建步骤缓存可能不像许多人所但愿的那样具备丰富的功能,可是缓存是镜像构建的基本功能。经过复用之前执行过的相同构建步骤所生成的内容,它有助于优化构建时间。对于Uber来讲,这是促使他们决定建立替代容器镜像构建工具的重要因素之一。那么,Makisu经过缓存功能提供了什么?


分布式缓存ui

利用Makisu构建容器镜像_容器镜像


在Kubernetes设置中,包含构建容器的Pod在理论上能够存在于集群内的任何节点上。
这带来了一个问题:构建容器如何才能利用先前构建迭代生成的缓存镜像层?
咱们能够尝试迫使Pod落在执行了先前构建迭代的节点上,但这会影响调度程序的做用和目的。相反,Makisu利用分布式缓存来解决此问题。
首先,Makisu提供了Dockerfile指令序列和diff层摘要之间的本地映射。这些映射保存在键值存储中,键值存储能够是文件,分布式Redis缓存或基于HTTP的通用缓存。重要的是缓存是分布式的,所以能够由任何有权访问缓存的Makisu构建容器引用。
缓存中的映射使Makisu可以肯定是否须要执行现有的构建步骤,或者是否可使用现有层的内容。若是在缓存中找到匹配项,则能够从Makisu管理的本地存储中解压缩该图层(若是它存在于本地存储中),或者从镜像仓库中提取该图层(若是已推送先前的构建)。
缓存中的密钥是从Dockerfile指令生成的,用于构建步骤并与先前构建步骤相关联。关联值是先前生成的镜像层内容的哈希值。若是构建步骤指令序列与缓存中的现有键匹配,则Makisu将使用摘要(做为键值保存)来定位diff层。
缓存具备可配置的生存时间(TTL),以确保缓存的图层不会过期。


选择性提交(Optional Commits)

利用Makisu构建容器镜像_容器镜像


在使用Docker守护程序进行镜像构建期间,将为新生构建或有更改内容的每一个构建步骤生成diff层。这致使建立images镜像很是臃肿。有时,能够经过合理地使用构建步骤在控制这些中间层,或将大量命令组合到一个Dockerfile指令中来控制这些中间层的数量。Makisu使用本身独特的技术来缓解此问题。
Makisu的Dockerfile指令解析器引入了一个指令,该指令控制在构建过程当中什么时候提交差别层。语法#!COMMIT注释的任何指令都被解析器解释为生成新层。那些没有该注释的将不会生成新的层。
 
 

FROM alpine
 
RUN apk add --no-cache wget
 
RUN apk add --no-cache curl #!COMMIT
<SNIP>

在上面的示例中,安装wget的RUN指令未提交为新层,而安装curl的则被提交。它建立了一个图层,其中包含自上一次提交以来或从构建阶段开始以来的全部新内容。
当为Makisu指定--commit = explicit标志时,显示缓存将为构建打开。没有它,#!COMMIT语法将被视为注释,就像Docker守护程序的解析器同样。这样,用于Makisu显式缓存的Dockerfile便与Docker守护程序保持兼容。
显式提交能够为镜像构建提供更大的灵活性;建立的层数更少,一般会使得图像更小,并改善了Dockerfile的可维护性。


结论

利用Makisu构建容器镜像_容器镜像


Makisu是一种很是强大的容器镜像构建工具,它是出于解决大型生产环境中存在的缺陷而产生的。它的方法消除了在容器构建期间对提高特权的需求(尽管构建是做为root用户执行的),而且它具备一种新颖的方法来构建缓存实现。
它没法解决Dockerfile指令顺序解析中固有的构建效率低下的问题。并且,构建执行并不老是能忠实地反映Docker镜像构建的预期行为。可是,Makisu来自著名的工程师团队,是新型容器镜像构建工具的又一个重要补充。
原文连接:https://www.giantswarm.io/blog/container-image-building-with-makisu