简化Golang多体系结构容器构建
#go #docker #drone #containerapps

随着基于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

  • 对于此演示,我们将使用一个名为ttl.sh的简短命名的容器注册表来推动和拉动演示应用程序image。

  • 下载和Drone CLI到您的路径。

注意:欢迎您使用自己的注册表。请检查有关如何配置usernamepassword的额外参数的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/arm64linux/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直接运行此演示或任何其他无人机管道。如果您有分钟,请尝试一下,让我知道您的宝贵反馈/改进。