随着基于ARM64的笔记本电脑变得非常受欢迎,它已成为集装箱开发人员构建多架构图像的需求。在ARM64机器上构建AMD64。
就我而言,我使用Apple M1,作为我的日常工作的一部分,我构建,测试和部署容器应用程序;默认情况下,我的MacBook生产 linux/arm64 图像。如果我需要将相同的图像部署到任何云服务,例如Google Cloud Run或Google Kubernetes引擎,然后我还需要拥有 linux/amd64 图像。
对于此类用例,我们通常为每个体系结构,清单文件等编写多个Dockerfile,该方法没有错,但是很快它会变得太难维护。
所以我们需要的是一个可以,
的工具链-
具有相同的过程来在本地构建图像以及云使用情况。我发现GoReleaser适合此要求。
-
是声明性的,通常映射到标准步骤,这些步骤将成为构建Golang应用程序的一部分,即测试,构建和推送图像到容器注册表。 Drone帮助以声明性的方式设置构建管道,并为所有主要工具/平台提供插件,包括Goreleaser。
-
构建多体系结构图像。 Buildx帮助我们使用标准Docker构建语义来构建多体系结构图像。添加到我们的工具中,有一个无人机插件无人机buildx插件,它可以将其插入管道中。
此博客文章的端到端演示可在我的GitHub Repo上找到。
克隆到您的笔记本电脑以供快速参考,
git clone https://github.com/kameshsampath/go-hello-world.git \
&& cd "$(basename "$_" .git)"
export DEMO_HOME="$PWD"
在其余的帖子中,我们将把这个克隆的文件夹称为$DEMO_HOME
。
注意:欢迎您使用自己的注册表。请检查有关如何配置
。username
和password
的额外参数的Drone Buildx Plugin文档。
让我们设置一些我们将使用的环境变量作为演示的一部分
# a unique uid as image identifier, it needs to be in the lowercase
export IMAGE_NAME=$(uuidgen | tr '[:upper:]' '[:lower:]')
# short lived image for 10 mins
export IMAGE_TAG=10m
,为方便起见,我们将将这些值保存到â.env
文件中
envsubst < "$DEMO_HOME/.env.example" | tee "$DEMO_HOME/.env"
注意:上面的示例使用envsubst更新文件。如果您没有安装EnvSubst,则可以手动更新
.env
文件。
让我们检查我们拥有的无人机管道.drone.yml
,
这是非常简单的无人机管道,它具有三个步骤
- 测试运行Golang测试
- 构建使用goreleaser构建Golang应用程序
- 推送将应用程序推向我们之前配置的容器注册表。
推动步骤还指定了平台linux/arm64
和linux/amd64
,该平台指示 docker buildx 构建以执行多体架构构建,该构建将产生与各自平台兼容的容器映像。
推动步骤使用上面的Dockerfile执行构建。
几乎没有重要的事情要注意,
-
评论
# syntax=docker/dockerfile:1.4
指示docker构建使用docker/dockerfile的buildx dockerfile语义:1.4。尽管在我们的情况下它没有很大的意义,但我们确保我们使用buildx执行构建。 buildx是Docker v18.x及以上的默认值。 -
ARG TARGETARCH
允许Docker构建知道为例如AMD64或ARM64等, -
基本图像
gcr.io/distroless/base
允许使用我们的应用程序的二进制构建一个微小的图像:)。
这几乎需要构建我们的多体系结构Golang应用程序,运行以下无人机命令来启动该管道,该管道将将图像构建为容器注册表。
drone exec --trusted --env-file=.env
构建完成后,运行以下命令以本地启动构建容器,
docker-compose up
对http://localhost:8080做一个简单的curl
,应该说“你好世界”。
最后,使用goreleaser时的小警告。 GoreLeaser,当交叉编译代码时,在 dist 文件夹下创建了诸如linux_arm64和linux_amd64_v1
之类的发行文件夹,其中保存了平台的构建二进制文件(linux/arm64
and linux/amd64
)。
文件夹名称遵循像<platform>_<arch>_<version>
这样的模式,而version
是可选的。对于amd64
goreleaser创建了一个像linux_amd64_v1
这样的二进制文件夹,这使得很难通过从dockerfile内使用arg TARGETARCH
选择二进制文件;因为TARGETARCH
仅返回没有版本的拱名。在我们的情况下,只有amd64
。
作为解决方法,我们需要编写goreleaser build oft hook脚本,如下所示,将linux_amd64_v1
重命名为linux_amd64
,然后允许我们使用TARGETARCH
,
COPY server_linux_${TARGETARCH}/server /bin/server
注意特别感谢我的儿子Rithul Kamesh,他自愿为我写那个小剧本。
总结我们所做的事情,
- 使用Buildx构建多架构容器图像
- 利用Drone管道定义声明性构建
- 使用GoReleaser具有标准配置来构建Golang应用程序
- 最终通过无人驾驶插件杠杆化的goreleaser,以执行可再现的多架构构建
我还编写了Drone CI Docker Extension,它允许您从Docker直接运行此演示或任何其他无人机管道。如果您有分钟,请尝试一下,让我知道您的宝贵反馈/改进。