在开发云原生应用时,从源代码到容器镜像发布的构建周期可能会随着时间的推移而变长。本文介绍了来自 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/** 🎉**。
评论(0)