在本文,我将介绍几种不用 Docker 就可以构建容器的方法。我将以 OpenFaaS 作为参考案例,它的工作负载使用了 OCI 格式的容器镜像。OpenFaaS 是 Kubernetes 的一个 CaaS 平台,可以运行微服务和添加 FaaS 及事件驱动工具。
第一个示例将展示如何使用 Docker CLI 内置的 buildkit 选项,然后是单独使用buildkit,最后是谷歌的容器构建器Kaniko。
本文涉及的工具都是基于 Dockerfile 文件来构建镜像的,因此,任何限制用户只能使用 Java (jib)或 Go (ko)的工具都不在讨论范围之内。
Docker 有什么问题?
x86_64Docker 之外的选择
有一些项目试图让“docker”回到它原本的组件身份,也就是我们最初都喜爱的用户体验:
x86_64在所有的选项中,我最喜欢 k3c,但它使用起来比较繁琐,它把所有东西都捆绑在一个二进制文件中,这很可能会与其他软件发生冲突。它运行的是自己的嵌入式 containerd 和 buildkit 二进制文件。
由于我们关注的是“构建”部分以及相对稳定的选项,所以我们将着重看一下:
- Docker的buildkit;
- 单独的buildkit;
- kaniko。
由于 OpenFaaS CLI 可以输出任意构建器都可以使用的标准“构建上下文”,所以上述的所有东西都可以实现。
构建一个测试应用程序
让我们从一个 Golang HTTP 中间件开始,并借此来展示 OpenFaaS 的通用性。
--langbuild-test--prefix我们将获得以下这些内容:
处理程序修改起来很容易,还可以通过 vendoring 或 Go 模块来添加其他依赖项。
使用一般的方式构建
构建这个应用程序的一般方式是这样的:
./template/golang-middleware/Dockerfile这次构建拉取了三个镜像:
如果使用传统的构建器,将按顺序拉取每个镜像。
等一会儿构建就完成了,现在本地库中就有了构建的镜像。
aas-cli push -f build-test.yml使用 buildkit 和 Docker 构建
这是最简单的做法,构建起来也很快。
我们可以看到,Docker 守护进程会自动切换到 buildkit 构建器。
Buildkit 有很多优点:
- 更复杂的缓存;
- 如果可能的话,可以先运行后面的指令——也就是说,可以在“sdk”层的构建完成之前,下载“runtime”镜像;
- 在第二次构建时速度超级快。
有了 buildkit,所有的基础镜像都可以一次性被拉取到本地库中,因为 FROM(下载)命令不是按顺序执行的。
这个在 Mac 上也可以使用,因为 buildkit 是由运行在 VM 中 Docker 守护进程负责代理的。
使用单独的 buildkit 构建
要单独使用 buildkit 进行镜像构建,我们需要在 Linux 主机上单独运行 buildkit,因此不能使用 Mac。
faas-cli build./build/build-test/现在我们需要运行 buildkit,可以从源代码开始构建,或者从上游获取二进制文件。
如果你仔细看一下发布页,你会发现 buildkit 也支持 armhf 和 arm64。
在新窗口中运行 buildkit 守护进程:
现在我们开始构建,并将配置文件的位置作为构建上下文传给它。我们需要 buildctl 命令,buildctl 是守护进程的一个客户端,它将指定如何构建镜像以及在构建完成后应该做什么,比如导成 tar、忽略构建或将其推送到注册表。
我使用下面的命令获得与 Docker 命令等价的效果:
在运行这个命令之前,你需要先运行 docker login,或者使用一组有效的未加密凭证来创建 $HOME/.docker/config.json 文件。
使用 img 和 buildkit 构建
由于我从未使用过 img,也没有听说有团队在大规模使用它,所以我想要尝试一下。
首先它不支持多平台架构,armhf 和 ARM64 平台没有对应的二进制文件,而且项目年龄不算短了,所以不太可能会提供多平台支持。
x86_64它的构建选项就像是 buildctl 的一个子集:
要构建一个镜像需要做这些事情:
由于这样或那样的原因,img 实际上没能构建成功。可能是因为试图以非 root 用户身份进行一些优化。
似乎已经存在三个类似的问题。
使用 Kaniko 构建
Kaniko 是谷歌的容器构建器,旨在为容器构建提供沙箱。你可以将其作为一次性容器,也可以将其作为独立的二进制文件。
- -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 容器的示例:
在 OpenFaaS 云上,我们使用本文介绍的上下文传递方法和 buildkit 守护进程提供了完全不需要人工干预的 CI/CD 构建体验。对于其他用户,我建议使用 Docker,或者带有 buildkit 的 Docker。
你可以使用 GitHub 或 GitLab 集成构建自托管的 OpenFaaS 云环境。
对于 faasd 用户,你的主机上只安装了 containerd,而没有安装 docker,所以最好的选择是下载 buildkit。
原文链接: