首页
Preview

使用ko构建并发布轻量级Go二进制文件到容器镜像中

在开发云原生应用时,从源代码到容器镜像发布的构建周期可能会随着时间的推移而变长。本文介绍了来自 Google 的开源容器镜像构建工具 ko,它可以快速将你的 Go 二进制文件构建成轻量级容器化镜像并将其发布到你喜欢的仓库。

想了解有关项目 ko 的更多信息,请单击此处

ko 提供了一个简单的命令行工具,可以快速将你的 Go 二进制文件构建为容器。当你的 Go 项目编译成静态二进制文件(没有操作系统依赖项,比如 CGO_ENABLED=0)时,你可以使用 ko 构建超轻量级容器镜像,而不会产生数百兆字节的操作系统冗余。

安装 ko

有几种方法可以安装 ko

使用 Go:

go install github.com/google/ko@latest

Homebrew:

brew install ko

ko 还提供了一个 GitHub Action 设置,可以将其集成到你的 CI/CD 流程中:

steps:
- uses: imjasonh/setup-ko@v0.6

构建和发布镜像

ko build 命令包装了 go build 命令,用于编译 Go 代码,自动生成容器镜像,并将镜像推送到本地或远程仓库。

本文将为以下名为 timeapp 的 Go 程序编译和构建一个镜像,该程序简单地打印当前时间:

package main

import (
  "fmt"
  "time"
)

func main() {
  fmt.Println(time.Now())
}

配置你的仓库

在构建之前,让我们配置 ko 设置镜像发布的位置。通常,ko 使用环境变量 KO_DOCKER_REPO 来设置 OCI 镜像将要发布的仓库。

例如,以下配置 ko 使用 GitHub 容器仓库:

KO_DOCKER_REPO=ghcr.io/vladimirvivien/services ko build .

本地发布

如果你在本地运行了 Docker 守护程序,则可以使用 KO_DOCKER_REPO=ko.local(或指定 --local-L 标志)构建和发布你的镜像,如下所示:

KO_DOCKER_REPO=ko.local ko build .

# equivalent to
ko build --local .

请注意,ko build 命令与 go build 命令相同,使用包的导入路径(在本例中为当前路径“.”)方式。当命令执行完毕后,你将在 Docker 守护程序中看到你的新镜像,如下所示:

$> docker images

REPOSITORY                         TAG      IMAGE ID       CREATED        SIZE
ko.local/timeapp-fc793bb2a14c1eb1  latest   47c3a0cf49d7   11 hours ago   3.1MB

ko 自动生成一个镜像名称,使用程序的包名称和构建哈希。后面我们将会看到这种行为(以及其他行为)可以进行配置。

启动镜像容器

可以使用你喜欢的 OCI 运行时工具来启动镜像。下面的代码片段显示了使用 Docker 启动 ko 构建的容器:

$> docker run --rm ko.local/timeapp-fc793bb2a14c1eb1:latest

2022-01-11 15:18:57.111766885 

默认情况下,ko 将入口点设置为容器的 /ko-app/<main-package-name>。下面的示例演示了如何使用默认入口点启动容器:

$> docker run --rm ko.local/timeapp-fc793bb2a14c1eb1:latest /ko-app/timeapp

2022-01-11 15:20:51.158882465

发布到远程仓库

如果你正在使用 Docker,并且已经通过 docker login 进行了身份验证,则可以构建/推送 ko 生成的镜像。如果你没有使用 Docker,则可以使用 ko login 命令设置你的用户名和密码身份验证,以发布到远程仓库:

ko login ghcr.com -u mine -p craft

或者,使用存储在环境变量中的令牌进行身份验证:

echo $GITHUB_PAT | grep ko login ghcr.com -u mine --password-stdin

验证后,ko 将自动将生成的镜像发布到指定的远程仓库。例如,以下命令将构建并发布 Go 程序二进制文件(前面提到的)到我在 GitHub Container Registry(ghcr.io)帐户的 services 命名空间中:

KO_DOCKER_REPO=ghcr.io/vladimirvivien/services ko build .

发布到正在运行的 kind 集群

ko 的一个功能是能够自动构建镜像并将容器加载到正在运行的 kind 集群中:

KO_DOCKER_REPO=kind.local ko build .

加载后,你可以使用 kubectl 应用使用该镜像的 YAML:

kubectl apply -f some-file-referecing-image.ymal

镜像配置

ko 提供了几个设置,可以影响容器镜像的构建和发布。如前所述,ko 将基于程序的主包后跟 ko 生成的 MD5 哈希后缀生成默认名称:

$> docker images

REPOSITORY                         TAG      IMAGE ID       CREATED        SIZE
ko.local/timeapp-fc793bb...6804e   latest   47c3a0cf49d7   11 hours ago   3.1MB

有几个命令行参数可以控制如何生成镜像名称。

--preserve-import-paths

标志 --preserve-import-paths(或 -P)使用整个程序的导入路径生成名称:

KO_DOCKER_REPO=ko.local ko build --preserve-import-paths .

镜像列表显示的镜像名称是主包的完整导入路径:

$> docker images

REPOSITORY                                   TAG        IMAGE ID       CREATED        SIZE
ko.local/github.com/vladimirvivien/timeapp   latest     f650668c3d74   18 hours ago   3.33MB

--base-import-paths

--base-import-paths(或 -B)标志仅在生成镜像名称时使用注册表路径和包名称,如下所示:

$> KO_DOCKER_REPO=ko.local ko build --base-import-paths .

$> docker images
REPOSITORY          TAG       IMAGE ID       CREATED        SIZE
ko.local/timeapp    latest    f650668c3d74   18 hours ago   3.33MB

--bare

--bare 标志仅在名称中包含仓库路径,不包括主包:

$> KO_DOCKER_REPO=ko.local ko build --bare .

$> docker images
REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
ko.local       latest    f650668c3d74   18 hours ago   3.33MB

.ko.yaml 配置文件

另一种 ko 可以通过 .ko.yaml 配置文件进行配置,当将其放置在构建目录中时(或使用环境变量 KO_CONFIG_PATH 指定其位置)。以下代码片段显示了带有构建指令的 Go 代码的配置文件:

builds:
- id: timeapp
  main: ./timeapp
  env:
  - CGO_ENABLED=0
  ldflags:
  - -s -w
  - -extldflags "-static"

多平台镜像

ko 具有使用 --platform 标志构建和发布多个平台镜像的功能。例如,下面的示例将自动为所有受支持的平台(对于 ko 基础镜像)交叉编译代码,然后生成镜像:

$> KO_DOCKER_REPO=ko.local ko build -B --platform=all .

13:29:31 Building github.com/vladimirvivien/timeapp for linux/amd64
13:29:31 Building github.com/vladimirvivien/timeapp for linux/arm64
13:29:31 Building github.com/vladimirvivien/timeapp for linux/arm/v6
13:29:31 Building github.com/vladimirvivien/timeapp for linux/ppc64le
13:29:31 Building github.com/vladimirvivien/timeapp for linux/s390x
13:29:31 Building github.com/vladimirvivien/timeapp for linux/arm/v7
13:29:31 Building github.com/vladimirvivien/timeapp for linux/386
13:29:31 Building github.com/vladimirvivien/timeapp for linux/riscv64

你可以针对特定的平台进行定位,如下所示:

KO_DOCKER_REPO=ko.local ko build -B --platform=linux/amd64,linux/arm64 .

如果你使用 .ko.yaml,可以包括 defaultPlatforms: 部分以指定构建目标平台:

defaultPlatforms:
- linux/arm64
- linux/amd64

结论

如果你的 Go 开发构建周期涉及创建容器镜像,那么毫无疑问,你会欢迎工作流程中的速度提高。本文展示了如何使用 ko 快速将 Go 程序构建为容器化构件,并将其自动推送到本地或远程仓库,从而提高生产力。这里介绍的功能只是 ko 可能实现的一小部分。如果你对该项目感兴趣并希望开始使用它,请访问其文档网站 https://ko.build/** 🎉**。

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
菜鸟一只
你就是个黄焖鸡,又黄又闷又垃圾。

评论(0)

添加评论