72f是什么意思,7f表示什么

  

  在本文中,我将介绍几种不用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支持高效的缓存构建。Podman buildah-RedHat/IBM组合使用他们自己的OSS工具链来生成OCI映像。Man是无守护、无根的,但最后还是要挂载文件系统,使用UNIX套接字。邮袋――来自阿里巴巴,被标榜为“高效的企业容器引擎”。和Docker一样,它使用containerd,支持容器级隔离(runc)和“轻量级虚拟机”(如runV)。Build Kit的独立版本——Build 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。写(字节(fmt。Sprintf('Hello world,Input :% s ',string(Input))}使用通用的方式构建这个应用程序,通用的方式如下:   

  

  FAAS-CLI build-fbuild-test . yml ./template/golang-middleware/Dockerfile包含模板和docker file的本地缓存。   

  

  这个构建拉了三面镜子:   

  

  来自打开FAAS/of-watchdog :0。7 .3来自golang :1.13-alpine 3.11来自alpine :   

3.12如果使用传统的构建器,将按顺序拉取每个镜像。

  

等一会儿构建就完成了,现在本地库中就有了构建的镜像。

  

我们还可以使用 faas-cli push -f build-test.yml将镜像推到注册表中。

  

  

使用 buildkit 和 Docker 构建这是最简单的做法,构建起来也很快。

  

DOCKER_BUILDKIT=1 faas-cli build -f build-test.yml我们可以看到,Docker 守护进程会自动切换到 buildkit 构建器。

  

Buildkit 有很多优点:

  

更复杂的缓存;如果可能的话,可以先运行后面的指令――也就是说,可以在“sdk”层的构建完成之前,下载“runtime”镜像;在第二次构建时速度超级快。有了 buildkit,所有的基础镜像都可以一次性被拉取到本地库中,因为 FROM(下载)命令不是按顺序执行的。

  

FROM openfaas/of-watchdog:0.7.3 as watchdogFROM golang:1.13-alpine3.11 as buildFROM alpine:3.11这个在 Mac 上也可以使用,因为 buildkit 是由运行在 VM 中 Docker 守护进程负责代理的。

  

  

使用单独的 buildkit 构建要单独使用 buildkit 进行镜像构建,我们需要在 Linux 主机上单独运行 buildkit,因此不能使用 Mac。

  

faas-cli build通常会运行或分叉出 docker,因为这个命令实际上只是一个包装器。因此,为了绕过这种行为,我们需要创建一个构建上下文,类似下面这样:

  

faas-cli build -f build-test.yml --shrinkwrap<0> > Building build-test.Clearing temporary build folder: ./build/build-test/Preparing ./build-test/ ./build/build-test//functionBuilding: alexellis2/build-test:latest with golang-middleware template. Please wait..build-test shrink-wrapped to ./build/build-test/<0> < Building build-test done in 0.00s.<0> Worker done.Total build time: 0.00这个上下文可以在./build/build-test/文件夹中找到,其中包含了函数代码和模板及其入口点和 Dockerfile。

  

./build/build-test/├── Dockerfile├── function│ └── handler.go├── go.mod├── main.go└── template.yml1 directory, 5 files现在我们需要运行 buildkit,可以从源代码开始构建,或者从上游获取二进制文件。

  

curl -sSLf https://github.com/moby/buildkit/releases/download/v0.6.3/buildkit-v0.6.3.linux-amd64.tar.gz | sudo tar -xz -C /usr/local/bin/ --strip-components=1如果你仔细看一下发布页,你会发现 buildkit 也支持 armhf 和 arm64。

  

在新窗口中运行 buildkit 守护进程:

  

sudo buildkitd WARN<0000> using host network as the default INFO<0000> found worker "l1ltft74h0ek1718gitwghjxy", labels=map, platforms= WARN<0000> skipping containerd worker, as "/run/containerd/containerd.sock" does not exist INFO<0000> found 1 workers, default="l1ltft74h0ek1718gitwghjxy" WARN<0000> currently, only the default worker can be used. INFO<0000> running server on /run/buildkit/buildkitd.sock 现在我们开始构建,并将配置文件的位置作为构建上下文传给它。我们需要 buildctl 命令,buildctl 是守护进程的一个客户端,它将指定如何构建镜像以及在构建完成后应该做什么,比如导成 tar、忽略构建或将其推送到注册表。

  

buildctl build --helpNAME: buildctl build - buildUSAGE: To build and push an image using Dockerfile: $ buildctl build --frontend dockerfile.v0 --opt target=foo --opt build-arg:foo=bar --local context=. --local dockerfile=. --output type=image,name=docker.io/username/image,push=true OPTIONS: --output value, -o value Define exports for build result, e.g. --output type=image,name=docker.io/username/image,push=true --progress value Set type of progress (auto, plain, tty). Use plain to show container output (default: "auto") --trace value Path to trace file. Defaults to no tracing. --local value Allow build access to the local directory --frontend value Define frontend used for build --opt value Define custom options for frontend, e.g. --opt target=foo --opt build-arg:foo=bar --no-cache Disable cache for all the vertices --export-cache value Export build cache, e.g. --export-cache type=registry,ref=example.com/foo/bar, or --export-cache type=local,dest=path/to/dir --import-cache value Import build cache, e.g. --import-cache type=registry,ref=example.com/foo/bar, or --import-cache type=local,src=path/to/dir --secret value Secret value exposed to the build. Format id=secretname,src=filepath --allow value Allow extra privileged entitlement, e.g. network.host, security.insecure --ssh value Allow forwarding SSH agent to the builder. Format default|<id><=<socket>|<key><,<key>>>我使用下面的命令获得与 Docker 命令等价的效果:

  

sudo -E buildctl build --frontend dockerfile.v0 \ --local context=./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 和 buildkit 构建由于我从未使用过 img,也没有听说有团队在大规模使用它,所以我想要尝试一下。

  

首先它不支持多平台架构,armhf 和 ARM64 平台没有对应的二进制文件,而且项目年龄不算短了,所以不太可能会提供多平台支持。

  

x86_64平台的最新版本是 2019 年 5 月 7 号的 v0.5.7,使用 Go 1.11 构建:

  

sudo curl -fSL "https://github.com/genuinetools/img/releases/download/v0.5.7/img-linux-amd64" -o "/usr/local/bin/img" \&& sudo chmod a+x "/usr/local/bin/img"它的构建选项就像是 buildctl 的一个子集

  

img build --helpUsage: img build PATHBuild an image from a Dockerfile.Flags: -b, --backend backend for snapshots () (default: auto) --build-arg Set build-time variables (default: <>) -d, --debug enable debug logging (default: false) -f, --file Name of the Dockerfile (Default is 'PATH/Dockerfile') (default: <none>) --label Set metadata for an image (default: <>) --no-cache Do not use cache when building the image (default: false) --no-console Use non-console progress UI (default: false) --platform Set platforms for which the image should be built (default: <>) -s, --state directory to hold the global state (default: /home/alex/.local/share/img) -t, --tag Name and optionally a tag in the 'name:tag' format (default: <>) --target Set the target build stage to build (default: <none>)要构建一个镜像需要做这些事情:

  

sudo img build -f ./build/build-test/Dockerfile -t alexellis2/build-test:latest ./build/build-test/由于这样或那样的原因,img 实际上没能构建成功。可能是因为试图以非 root 用户身份进行一些优化。

  

  

fatal error: unexpected signal during runtime executionruntime stack:runtime.throw(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 +0x2f2goroutine 529 :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 构建Kaniko 是谷歌的容器构建器,旨在为容器构建提供沙箱。你可以将其作为一次性容器,也可以将其作为独立的二进制文件。

  

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-d指定在成功构建后应该将镜像放在哪里。-v将当前目录挂载到Kaniko容器中,还添加了config.json配置文件,指定将镜像推送到哪个远程注册表。

  

Kaniko 提供了缓存支持,但需要手动管理和保存,因为 Kaniko 是在一次性模式下运行的,不像 Buildkit 那样是守护进程。

  

以上各种工具的总结Docker――传统的构建器安装 Docker 是个“大工程”,可能会给你的系统带来比预想的要多得多的东西。Docker 构建器是最古老的,也是最慢的。要注意在安装 Docker 时附带安装的网桥,它可能会与使用相同私有 IP 段的其他私有网络发生冲突。

  

Docker――与buildkit一起这是最快的工具选择,改动最少,只需要加个DOCKER_BUILDKIT=1就可以启用。

  

单独的buildkit这个选项非常适合集群内构建,或者不需要 Docker 的系统(如 CI 或执行器)。它需要 Linux 主机,在 MacOS 上的使用体验太差,或许可以运行一个额外的 VM 或主机,然后通过 TCP 来访问?

  

Kaniko使用 Kaniko 仍然需要安装 Docker,但不管怎样,它毕竟提供了另一种选择。

  

全文总结你可以在 OpenFaaS 中使用普通的容器构建器,也可以使用 faas-cli build --shrinkwrap,并将构建上下文传给首选工具。

  

下面是使用相应工具构建 OpenFaaS 容器的示例:

  

谷歌云构建GitHub ActionsJenkinsGitLab CI在 OpenFaaS 云上,我们使用本文介绍的上下文传递方法和 buildkit 守护进程提供了完全不需要人工干预的 CI/CD 构建体验。对于其他用户,我建议使用 Docker,或者带有 buildkit 的 Docker。

  

你可以使用 GitHub 或 GitLab 集成构建自托管的 OpenFaaS 云环境。

  

对于 faasd 用户,你的主机上只安装了 containerd,而没有安装 docker,所以最好的选择是下载 buildkit。

  

原文链接:

  

https://blog.alexellis.io/building-containers-without-docker/

  

延伸阅读:

  

Docker 的第二次死亡-InfoQ

  

关注我并转发此篇文章,私信我“领取资料”,即可免费获得InfoQ价值4999元迷你书,点击文末「了解更多」,即可移步InfoQ官网,获取最新资讯~

相关文章