在没有码头工人的情况下建造集装箱

2020-11-02 01:02:54

在这篇文章中,我将概述几种无需Docker本身即可构建容器的方法。我将使用OpenFaaS作为案例研究,它使用OCI格式的容器图像作为其工作负载。考虑OpenFaaS最简单的方式是将其作为Kubernetes的CaaS平台,它可以运行微服务,并免费添加FAAS和事件驱动工具。

帖子中的第一个选项将展示如何使用Docker的CLI的内置内置工具包选项,然后是独立构建工具包(仅限Linux),然后是谷歌的容器构建器Kaniko。

注意:这篇文章介绍了可以从Dockerfile构建映像的工具,因此任何将用户限制为只能使用Java或Go的工具都不在讨论范围之内。

然后我会把事情做个总结,让你知道如何获得建议,反馈,以及你自己关于容器工具的需求和需求的故事。

事实并非如此,Docker在armhf、arm64和x86_64上运行良好。主要的Docker CLI已经不仅仅是构建/装运/运行,而且还拖着几年的包袱,它现在捆绑了Docker Sarm和EE功能。

有一些努力试图将Dock带回它的组件,我们都爱上了最初的UX:

Docker-docker本身现在使用tainerd来运行容器,并支持使buildkit执行高效的缓存构建。

Podman和buildah的结合-RedHat/IBM的努力,使用他们自己的OSS工具链来生成OCI图像。Podman的市场定位是无守护程序和无根目录,但最终仍必须挂载覆盖文件系统并使用UNIX套接字。

邮袋-来自阿里巴巴的邮袋被标榜为高效的企业级集装箱引擎。它和Docker一样使用了tainerd,并且既支持runc的容器级隔离,也支持像runV这样的轻量级VM。也有更多的重点放在形象传播和强烈的隔离上。

独立的buildkit-buildkit是由Docker Inc的Tónis Tiigi启动的,它是一家全新的容器生成器,考虑到了缓存和并发性。Buildkit目前只作为守护进程运行,但您会听到人们的说法并非如此。他们分叉守护进程,然后在构建后将其杀死。

Img-img是由Jess Frazelle编写的,经常在这类指南中被引用,并且是构建工具包的包装器。这就是说,与提到的其他选择相比,我还没有看到它的吸引力。该项目在2018年底之前相当活跃,此后只收到了几个补丁。Img声称是无守护程序的,但它使用的是buildkit,所以很可能在那里做了一些诡计。我听说img提供了比buildkit自己的CLI buildctr更好的用户体验,但也应该注意到img只针对x86_64发布,并且没有针对armhf/arm64的二进制文件。

Img的一个替代方案是k3c,它还包括一个运行时组件,并计划支持ARM架构。

K3C-Rancher的最新实验,它使用容器和构建套件来重新创建原始的、经典的、香草的、轻便的原始Docker版本的体验。

在所有选项中,我认为我最喜欢k3c,但它非常新奇,将所有东西捆绑到一个二进制文件中,这可能会与其他软件冲突,目前它运行自己的嵌入式容器和构建工具包二进制文件。

注意:如果您是RedHat的客户并为支持付费,那么您真的应该使用他们的整个工具链来让您的钱物有所值。我查看了一些示例,看到其中一个使用了我关于多阶段构建的经典博客文章。自己看看您更喜欢buildah示例还是Dockerfile示例。

因此,由于我们这里的重点是构建部分,并且希望查看相对稳定的选项,因此我将介绍以下内容:

由于OpenFaaS CLI可以输出任何构建器都可以使用的标准构建上下文,因此现在可以实现以上所有功能。

让我们从Golang HTTP中间件开始,这是函数和微服务的结合,展示了OpenFaaS的多功能性。

./├──Build-测试│└──处理程序.go└──Build-test.yml1目录,2个文件。

处理程序看起来像这样,并且很容易修改。可以通过供应商或GO模块添加其他依赖项。

包函数import(";fmt";";io/ioutil";";net/http";)函数句柄(w http.ResponseWriter,r*http.Request){var input[]byte if r.Body!=nil{defer r.Body.Close()Body,_:=ioutil.ReadAll(r.Body)input=body}w.WriteHeader(http.StatusOK)w.Write([]byte(fmt.Sprintf(&34;Hello world,输入为:%s";,String(输入)}。

稍等片刻,你就完成了,现在我们当地的图书馆里有了这张照片。

这是所有更改中最容易进行的,而且构建速度也很快。

我们将看到,使用这种方法,Docker守护进程会自动关闭buildkit的构建器。

如果可能,请先运行后面的指令-即,甚至在SDK层中的构建完成之前下载运行时映像。

使用buildkit,可以一次将所有基本映像放入我们的本地库中,因为FROM(下载)命令不是按顺序执行的。

即使在Mac上也可以使用此选项,因为buildkit是通过虚拟机中运行的Docker守护进程代理的。

要在独立设置中使用Buildkit进行构建,我们需要在Linux主机上单独运行Buildkit,因此我们不能使用Mac。

Faas-cli build通常会执行或派生docker,因为命令只是一个包装器。因此,要绕过此行为,我们应该写出构建上下文,这可以通过以下命令实现:

Faas-cli build-f build-test.yml--reshrap[0]>;Building build-test.清除临时构建文件夹:./build/build-test/preparing./build-test/./build/build-test//function Building:alexellis2/build-test:最新的Golang中间件模板。请稍候..生成测试收缩包装到./build/build-test/[0]<;生成生成-测试在0.00s内完成。[0]个工作人员完成。总生成时间:0.00。

我们的上下文现在位于./build/build-test/文件夹中,其中包含我们的函数代码以及模板及其入口点和Dockerfile。

./BUILD/BUILD-TEST/├──Dockerfile├──Function│└──Handler.go├──go.mod├──main.go└──template.yml1目录,5个文件

现在我们需要运行buildkit,我们可以从源代码构建,或者获取上游二进制文件。

如果您查看发行版页面,您还会发现适用于armhf和arm64的构建工具包,这对于多拱门非常有用。

SUDO buildkitd warn[0000]使用主机网络作为默认信息[0000]找到Worker";l1ltft74h0ek1718gitwghjxy";,labels=map[org.mobyproject.buildkit.worker.executor:oci org.mobyproject.buildkit.worker.hostname:nuc org.mobyproject.buildkit.worker.snapshotter:overlayfs],Platforms=[Linux/AMD64Linux/386]warn[0000]正在跳过容器d Worker,因为";/Run/Containerd/Containerd.sock";不存在信息[0000]找到1个Worker,默认值=";l1ltft74ek0gitwghjxy";WARN[0000]目前,只能使用默认工人。INFO[0000]在/run/buildkit/buildkitd.sock上运行服务器。

现在,让我们开始一个构建,将收缩包装的位置作为构建上下文传入。我们需要的命令是buildctl,buildctl是守护进程的客户端,它将配置如何构建映像以及完成后要执行的操作,例如导出tar、忽略构建或将其推送到注册表。

Buildctl build--help名称:buildctl build-buildUSAGE:使用Dockerfile构建和推送映像:$buildctl build--front dockerfile.v0--opt target=foo--opt build-arg:foo=bar--local context=。--本地dockerfile=。--output type=image,name=docker.io/username/image,ush=true选项:--output value,-o value定义构建结果的导出,例如--output type=image,name=docker.io/username/image,ush=true--进度值设置进度类型(auto、Plan、tty)。使用PLAN显示容器输出(默认值:";auto";)--跟踪文件的跟踪值路径。默认为无跟踪。--本地值允许构建访问本地目录--前端值定义用于构建的前端--opt值定义前端的自定义选项,例如--opt target=foo--opt build-arg:foo=bar--no-cache禁用所有顶点的缓存--export-cache值导出构建缓存,例如--export-cache type=register,ref=example.com/foo/bar,或-export-cache type=local,est=path/to/dir-import-cache value Import build cache,例如-import-cache type=Registry,ref=example.com/foo/bar,或者--import-cache type=local,src=path/to/dir--向构建公开的保密值Secret值。Format id=Secretname,src=filepath--allow值允许额外的特权授权,例如network.host、security.insecure--ssh值允许将SSH代理转发到构建器。格式化default|<;id>;[=<;socket>;|<;key>;[,<;键>;]]。

下面是我运行以获取带有DOKER_BUILDKIT覆盖的DOKER命令的等价物:

SUDO-E buildctl build--前端dockerfile.v0\--本地上下文=./build/build-test/\--local dockerfile=./build/build-test/\--output type=image,name=docker.io/alexellis2/build-test:Latest,Push=true。

在运行此命令之前,您需要运行docker login,或者使用一组有效的未加密凭据创建$HOME/.docker/config.json`。

因为我从来没有用过img和apper,也没有听说过它在团队中经常被使用,而不是更常见的选择,我想我会试一试的。

第一印象是,多拱不是优先考虑的,考虑到项目的年龄,可能不太可能落地。没有用于ARMF或ARM64的二进制文件。

对于x86_64,最新版本是2019年5月7日发布的v0.5.7,使用GO 1.11构建,GO 1.13是当前版本:

Img build--help用法:img build[Options]PATH从Dockerfile构建映像。标志:-b,--快照后端([auto ative overlayfs])(默认值:AUTO)--build-arg设置构建时间变量(默认值:[])-d,--debug enable debug log(默认值:false)-f,--Dockerfile的文件名(默认值为';path/Dockerfile&39;)(默认值:<;None>;)--映像的标签集元数据(默认值:[])--no-缓存在构建映像时不使用缓存(默认值:false)--no-控制台使用非控制台进度UI(默认值:false)--应为其构建映像的平台设置平台(默认值:[])-s,--保存全局状态的状态目录(默认值:/home/alex/.local/share/img)-t,--标记名和'中的标记(可选);名称:tag';Format(默认值:[])--target将目标构建阶段设置为Build(默认值:<;None>;)。

现在,由于这样或那样的原因,img实际上未能成功构建。这可能是由于尝试以非root用户身份运行的一些优化所致。

致命错误:运行时执行期间出现意外信号[信号SIGSEGV:分段违规代码=0x1Addr=0xe5 pc=0x7f84d067c420]运行时堆栈:runtime.jo(0xfa127f,0x2a)/home/travis/.gimme/versions/go1.11.10.linux.amd64/src/runtime/panic.go:608+0x72runtime.sigPanic()/home/travis/.gimme/versions/go1.11.10.linux.amd64/src/runtime/signal_unix.go:374+0x2f2goroutine529[syscall]:runtime.cgocall(0xc9d980,0xc00072d7d8,0x29)/home/travis/.gimme/versions/go1.11.10.linux.amd64/src/runtime/cgocall.go:128+0x5e fp=0xc00072d7a0 sp=0xc00072d768 pc=0x4039eeos/user._cfunc_mygetgrgid_r(0x2a,0xc000232260,0x7f84a40008c0,0x400,0xc0004ba198,0xc000000000)。

Kaniko是Google的容器建造者,其目标是沙箱容器构建。您可以将其用作一次性容器,也可以用作独立的二进制文件。

Docker run-v$pwd/build/build-test:/workspace\-v~/.docker/config.json:/kaniko/config.json\--env docker_config=/kaniko\gcr.io/kaniko-project/Executor:Latest\-d alexellis2/build-test:Latest

V标志将当前目录绑定挂载到Kaniko容器中,它还会添加您的config.json文件以推送到远程注册表。

Kaniko中有一些对缓存的支持,但它需要手动管理和保存,因为Kaniko以一次性模式运行,而不是像Buildkit那样以守护方式运行。

安装Docker可能会很繁重,并且会给您的系统添加比预期更多的内容。建筑工人年纪最大,速度最慢,但却能完成工作。注意Docker安装的网桥,它可能会与使用相同内网网段的其他内网冲突。

这是最快的选择,也是最少的改动。只需为命令DOKER_BUILDKIT=1添加前缀即可启用它。

此选项对于群集内构建或不需要Docker的系统(如CI Box或Runner)非常有用。它确实需要一台Linux主机,而且在MacOS上使用它没有很好的体验,也许是通过运行额外的虚拟机或主机并通过TCP访问?

我还想加入[Akihiro Suda](https://twitter.com/@AkihiroSuda/)的演示文稿,他是来自日本ntt的构建工具包维护员。此信息已有2年的历史,但提供了2018年比较下一代容器映像构建工具的另一个高级概述。

对于faasd用户来说,这是最好的选择,因为他们只依赖tainerd和cni,而不是docker或kubernetes。

我们使用Kaniko的方式仍然需要安装Docker,但提供了另一种选择。

您可以将普通容器构建器与OpenFaaS一起使用,也可以使用faas-cli build--definsprap并将构建上下文传递给您的首选工具。

在OpenFaaS云中。我们使用本文中概述的包络处理方法和buildkit守护程序提供完全不干预的CI/CD体验。对于所有其他用户,我建议使用Docker,或者使用Docker with buildkit。对于faasd,使用buildkit daemonized。

在这篇文章中,我们确实遗漏了工作流的一个重要部分,即部署。任何OCI容器都可以部署到Kubernetes之上的OpenFaaS控制平面,只要它符合无服务器工作负载定义。如果您想了解构建、推送和部署的完整体验,请访问OpenFaaS研讨会。

在twitter@alexellisuk上让我知道你对这篇帖子的看法,以及你在2020年最感兴趣的工具是什么。

聘用我购买Cloud Native/Docker/Go/CI&;CD或Kubernetes。

你是否需要一些帮助来解决一个难题,一个新想法或项目的外部观点?也许您想在进行更多投资之前建立一个技术概念验证?请通过[email protected]与我联系,或在calendly.com/alexellis上预订与我的会议。