在本文中,我将介绍几种不用Docker构建容器的方法。我将使用OpenFaaS作为参考案例,其工作负载使用OCI格式的容器映像。OpenFaaS是Kubernetes的一个CaaS平台,可以运行微服务,可以添加FaaS和事件驱动工具。第一个例子将展示如何使用Docker CLI的内置buildkit选项,然后单独使用buildkit,最后是Google的容器生成器Kaniko。本文涉及的工具都是基于Dockerfile文件来构建映像的。因此,任何限制用户只能使用Java (jib)或Go (ko)的工具都不在讨论范围之内。
Docker怎么了?Docker在armhf、arm64和x86_64平台上运行良好。Docker CLI不仅用于构建/发布/运行映像,这些年来它背负了太多的东西,现在又捆绑了Docker Swarm和Docker EE特性。
docker之外的选择有一些项目试图让“Docker”回归其最初的组件身份,这是我们一开始都很喜欢的用户体验:
Docker——Docker现在使用containerd来运行容器,并使用buildkit支持高效的缓存构建。RedHat/IBM使用Podman buildah 3354的组合来使用他们自己的OSS工具链生成OCI映像。Man是无守护、无根的,但最后还是要挂载文件系统,使用UNIX套接字。Pouch——来自阿里巴巴,标榜为“高效的企业容器引擎”。和Docker一样,它使用containerd,支持容器级隔离(runc)和“轻量级虚拟机”(如runV)。buildkit——buildkit Kit的独立版本是由Docker公司的Tonis Tiigi创建的,这是一个全新的容器生成器,具有缓存和并发支持。Buildkit目前只作为守护进程运行,但你可能会听到有人说不是这样。事实上,它派生了守护进程,然后在构建完成后终止它。Img——img由Jess Frazelle开发,封装了buildkit。与其他工具相比,它并不更有吸引力。这个项目一直活跃到2018年下半年,但之后只发布了几个补丁。Img号称是无守护进程的,但是它用的是buildkit,所以这里有讨论的地方。听说img提供了比buildkit的CLI buildctr更好的用户体验,但是需要注意的是img只发布x86_64平台的二进制文件,不支持armhf/arm64。K3c——利用containerd和buildkit来重建最初Docker的原始、经典、朴素、轻量的体验。在所有选项中,我最喜欢k3c,但是用起来比较繁琐。它把所有东西都打包在一个二进制文件中,这很可能会与其他软件冲突。它运行自己的嵌入式containerd和buildkit二进制文件。因为我们关注“构建”部分和相对稳定的选项,所以我们将关注:
Docker的buildkit;单独的构建工具包;kaniko .由于OpenFaaS CLI可以输出任何构建器都可以使用的标准“构建上下文”,所以以上都可以实现。
要构建一个测试应用程序,让我们从一个Golang HTTP中间件开始,并展示OpenFaaS的多功能性。
– lang指定构建模板;Build-test是函数的名称;-前缀是Docker Hub用户名,用于推送我们的OCI图片。我们将得到以下内容:/-build-test -handler.Go -build-test.yml1目录,2files handler易于修改,其他依赖项可以通过供应商或Go模块添加。
package function import(‘ fmt ‘ ‘ io/io util ‘ ‘ net/http ‘)func Handle(w http。ResponseWriter。request){ var input[]byteif r . Body!=nil {defer r.Body.Close()body,_ :=ioutil。ReadAll(r . Body)input=Body } w . write header(http。status ok)w . Write([]字节(fmt。Sprintf(‘Hello world,Input :% s ‘,string(Input))}使用通用的方式构建这个应用程序,通用的方式如下:
FAAS-CLI build-fbuild-test . yml ./template/golang-middleware/Dockerfile包含模板和docker file的本地缓存。这个构建拉了三面镜子:
来自open FAAS/of-watchdog 33600 . 7 . 3 as watchdog from golang 33601.13-alpine 3.11 as build from alpine 33603.12如果使用传统的构建器,则会按顺序拉取每个图像。过一会儿,构建就完成了,现在本地库中已经有一个构建好的映像了。我们还可以使用faas-cli push -f build-test.yml将图像推送到注册表中。
用buildkit和Docker构建是最简单的方法,而且构建起来也很快。
Docker _ build kit=1 FAAS-CLI build-fbuild-test . yml我们可以看到Docker守护进程会自动切换到buildkit builder。套件有许多优点:
更复杂的缓存;如果可能的话,可以先运行下面的指令3354,即可以在“sdk”层构建之前下载“运行时”镜像;在第二个版本中速度非常快。使用buildkit,所有的基本映像都可以一次拉到本地库,因为FROM (download)命令不是按顺序执行的。
open FAAS/of-watchdog 33600 . 7 . 3 as watchdog from golang 33601.13-alpine 3.11 as build from alpine 33603.11也可以在Mac上使用,因为buildkit是由运行在VM中的Docker守护进程表示的。
用单独的buildkit构建要用单独的buildkit构建镜像,我们需要在Linux主机上单独运行buildkit,所以不能用Mac。Faas-cli build通常在docker之外运行或分叉,因为这个命令实际上只是一个包装器。因此,为了避免这种行为,我们需要创建一个构建上下文,如下所示:
FAAS-CLI build-f build-test . yml-shrink wrap[0]build build-test。正在清除临时生成文件夹:/build/build-test/正在准备。/build-test/。/build/build-test//function building : alexellis 2/build-test : latest with golang-middleware模板。请稍候.构建测试收缩包装到。/build/build-test/[0]生成生成测试在0.00秒内完成。[0]工作线程完成。总构建时间: 0.00此上下文可以在。/build/build-test/folder,其中包含函数代码和模板、它们的入口点和Dockerfile。/build/build-test/-Docker档案-Function -Handler.加油-Go.国防部-Main.加油-Template.YML1目录,现在我们需要运行5个文件
curl-sslf https://github . com/莫比/buildkit/releases/download/v 0 . 6 . 3/build kit-v 0 . 6 . 3 . Linux-amd64 . tar . gz | sudotar-xz-c/usr/local/bin/-strip在新窗口中运行build kit守护进程:
sudo buildkitd WARN[0000]使用主机网络作为默认信息[0000]找到worker ‘ L1 ltft 74h 0 ek 1718 gitwhgjxy ‘,labels=map[org . Moby project . build kit . worker . executor : org . Moby project . build kit . worker . hostname : nuc org . Moby project . build kit . worker . snapshott er : overlayfs],platforms=[linux/amd64 linux/我们需要buildctl命令,它是守护进程的一个客户端。它将指定如何构建映像,以及在构建完成后应该做什么,比如引导到tar,忽略构建或将其推送到注册表。
构建CTL构建-帮助名称:构建CTL构建-构建用法:使用docker文件: $ build CTL build-前端docker文件。v 0-opt target=foo-opt build-arg : foo=bar-local context=.-本地dockerfile=.-输出类型=图像,名称=docker . io/用户名/图像,推送=真选项:-输出值,-o值定义构建结果的导出,例如- output type=image,name=docker.io/username/image,push=true -进度值设置进度类型(自动,普通,tty).使用平原显示容器输出(默认:“自动”)—跟踪文件的跟踪值路径。默认为不跟踪10.1-本地值允许构建访问本地目录-前端值定义用于构建的前端- opt值定义前端的自定义选项,例如-opt target=foo-opt build-arg : foo=bar-no-cache禁用所有顶点的缓存-导出-缓存值导出构建缓存,例如- export-cache type=registry,ref=example.com/foo/bar,或- export-cache type=local,dest=path/to/dir – import-cache值导入构建缓存,例如-导入-缓存格式id=secretname,src=filepath – allow值允许额外的特权权限,例如网络.主机,安全。不安全-ssh值允许将嘘代理转发到构建器。格式默认值|[=|[,]]我使用下面的命令获得与码头工人命令等价的效果:
sudo-E构建CTL构建-前端docker文件。v 0 \-本地上下文=。/build/build-test/\-local docker file=./build/build-test/\-输出类型=image,名称=docker。io/alexellis 2/build-test :最新,push=true在运行这个命令之前,你需要先运行码头工人登录,或者使用一组有效的未加密凭证来创建$HOME/.docker/config.json文件。
使用图片和构建工具包构建由于我从未使用过img,也没有听说有团队在大规模使用它,所以我想要尝试一下。首先它不支持多平台架构,armhf和ARM64平台没有对应的二进制文件,而且项目年龄不算短了,所以不太可能会提供多平台支持x86_64平台的最新版本是2019 年5月七号的v0.5.7,使用Go 1.11构建:
sudo curl-fSL ‘ https://github。com/正版工具/img/releases/download/v 0。5 .7/img-Linux-amd64 ‘-o ‘/usr/local/bin/img ‘ \ sudo chmod a x ‘/usr/local/bin/img ‘它的构建选项就像是buildctl的一个子集
img构建-帮助用法: img构建[选项]路径从构建文件构建映像标志: -b,-快照的后端后端([auto native overlayfs])(默认为: auto)-build-arg设置构建时变量(默认值: []) -d,-调试启用调试日志记录(default: false) -f,-docker文件的文件名(默认为路径/docker文件’)(默认为:)-映像的标签集元数据(默认值: []) -无缓存构建映像时不使用缓存(默认本地/共享/img) -t,-标记名和一个可选的”名称:标签”格式的标记(默认为:[])-目标将目标构建阶段设置为构建(默认为:)要构建一个镜像需要做这些事情:
sudo img build-f ./build/build-test/docker file-t alexellis 2/build-test :最新版./生成/生成-测试/由于这样或那样的原因,img实际上没能构建成功。可能是因为试图以非根用户身份进行一些优化。
致命错误:运行时执行期间出现意外信号[signal SIGSEGV:分段违规代码=0x 1 addr=0xe 5 PC=0x7f 84d 067 c 420]运行时堆栈:runtime.throw(0xfa127f,0x2a)/home/travis/。gimme/versions/go 1 . 11 . 10 . Linux . amd64/src/runtime/panic . go :6080x 72 runtime . sigpanic()/home/Travis/。gimme/versions/go 1 . 11 . 10 . Linux . amd64/src/runtime/signal _ UNIX . go :3740x 2 F2 go routine 529[syscall]: runtime . CGO call(0xc9d 980,0xc00072d7d8,0x29)/home/travis/。gimme/versions/go 1 . 11 . 10 . Linux . amd64/src/runtime/CGO call . go :1280x5e FP=0xc 00072 D7 a 0 sp=0xc 00072d 768 PC=0x 4039 eeos/User。_ cfunc _ mygetgrgid _ r (0x2a,0xc00023260,0x7F84a40008c0,0x400,0xc0004ba198,0xc0000000)好像有三个类似的问题。
使用Kaniko构建Kaniko是Google的容器构建器,旨在为容器构建提供沙盒。您可以将其用作一次性容器或单独的二进制文件。
docker run-v $ PWD/build/build-test :/workspace \-v ~/。DOCKER/CONFIG . JSON :/Kan iko/CONFIG . JSON \-env DOCKER _ CONFIG=/Kan iko \ Gcr.io/kaniko-project/executor:latest \-d alexells 2/build-test 3360 latest-d指定在成功构建后应该放置映像的位置。-v将当前目录挂载到Kaniko容器中,并添加config.json配置文件来指定将映像推送到哪个远程注册表。Kaniko提供了缓存支持,但需要手动管理和保存,因为Kaniko以一次性模式运行,不像Buildkit是一个守护进程。
以上工具总结Docker——传统的builder安装Docker是一个“大工程”,可能会给你的系统带来比预期多得多的东西。Docker builder是最老最慢的。安装Docker时要注意安装的网桥,可能会与使用相同私有IP段的其他私有网络冲突。
Docker——是变化最少的最快工具选择。您只需要添加一个DOCKER_BUILDKIT=1来启用它。
这个选项非常适合集群中的buildkit或者不需要Docker的系统(比如CI或者actuators)。需要Linux主机,在MacOS上体验太差。也许它可以运行一个额外的虚拟机或主机,并通过TCP访问它?
Kaniko仍然需要安装Docker才能使用Kaniko,但不管怎样,它提供了另一种选择。
总之,您可以使用OpenFaaS中的通用容器构建器,或者faas-cli build – shrinkwrap,并将构建上下文传递给首选工具。以下是使用相应工具构建OpenFaaS容器的示例:
Google在OpenFaaS的云中构建GitHub ActionsJenkinsGitLab CI,我们使用上下文转移的方法和本文介绍的buildkit守护进程来提供完全不需要人工干预的CI/CD构建体验。对于其他用户,我建议使用Docker,或者Docker with buildkit。您可以使用GitHub或GitLab集成来构建自托管的OpenFaaS云环境。对于faasd用户,您的主机上只安装了containerd,而没有docker,所以最好的选择是下载buildkit。原文链接:https://blog.alexellis.io/building-containers-without-docker/
延伸阅读:
Docker的第二次死亡——InfoQ关注我,转发本文。如果你给我发私信“获取信息”,就可以免费获得InfoQ价值4999元的迷你本。点击文末“了解更多”移步InfoQ官网获取最新资讯~