ko:使用 Go 进行快速 Kubernetes 微服务开发 ¶
发布时间:2019-04-10,修订时间:2024-01-17
ko:使用 Go 进行快速 Kubernetes 微服务开发¶
作者:Matt Moore,Chainguard 创始人/CTO
我最初编写 ko
是为了帮助 Knative 开发人员。社区的积极反馈促使我撰写这篇介绍性文章,包括最近 2018 年西雅图 Kubecon 期间 IBM 展位上关于 ko
的演讲。我希望您能像我们一样享受使用 ko
,并期待您在 slack.knative.dev 上提供反馈。
在过去的几年里,容器受到了很多关注。Docker、Kubernetes 和相关技术席卷了公有云(双关语)。与此同时,随着软件项目变得越来越复杂,开发流程也变得越来越复杂。
从

迅速变成

诸如 skaffold 之类的工具可以为任意语言和 Dockerfile 包装此流程,使其更易于管理(并且更快),但您仍然需要编写 手工制作的 Dockerfile ,并且通常需要编写更多 yaml(或其他)来告诉工具如何编排此操作(例如,什么被推送到哪里?)。

ko
采用了一种不同的方法,它利用 Go 的惯例来消除配置。
Go 中的一个惯例是二进制文件通过“导入路径”进行引用;安装 Go 二进制文件的一种典型方法是
# e.g. installing ko itself
go get github.com/google/go-containerregistry/cmd/ko
开始使用 ko
不需要任何额外的配置文件,您只需将对容器镜像的引用替换为导入路径即可
# This example is based on:
# https://github.com/google/ko/blob/master/cmd/ko/test/test.yaml
apiVersion: v1
kind: Pod
metadata:
name: kodata
spec:
containers:
- name: test
# ko builds and publishes this Go binary, and replaces this
# with an image name.
image: github.com/google/go-containerregistry/cmd/ko/test
restartPolicy: Never
就是这样。
如何使用 ko
来使用它?
ko
还需要知道用户希望将镜像发布到哪里。这在 yaml 清单文件之外定义,因为通常团队中的每个开发人员都会使用自己的镜像仓库。
例如,在 Knative 上进行开发时,我在我的 .bashrc
文件中使用以下命令
export KO_DOCKER_REPO=gcr.io/mattmoor-private/ko
注意:对于 DockerHub 用户(以及可能的其他用户),这应该是: docker.io/username
,因为 DockerHub 不支持多级存储库名称。
之后,命令行界面模仿 kubectl
ko apply -f directory/ -f file.yaml
这将与 kubectl apply
具有相同的网络效果,但它还会构建、容器化并发布从 yaml 文件中引用的 Go 微服务,并且配置显著减少

您只需编写 Kubernetes yaml 文件和代码。无需 Dockerfile,无需 Makefile。您运行一个命令,您的最新代码就开始运行。
以下面的示例为例(已缩短):
~/go/src/github.com/google/go-containerregistry
$ ko apply -f cmd/ko/test/test.yaml
Using base .. for github.com/google/go-containerregistry/cmd/ko/test
Publishing gcr.io/mattmoor-public/test-01234abcd:latest
mounted blob: sha256:deadbeef
mounted blob: sha256:baadf00d
pushed blob sha256:deadf00d
pushed blob sha256:baadbeef
pushed blob sha256:beeff00d
gcr.io/mattmoor-public/test-01234abcd:latest: digest: ... size: 915
Published gcr.io/mattmoor-public/test-01234abcd@...
pod/kodata created
~/go/src/github.com/google/go-containerregistry$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kodata 0/1 Completed 0 1
仅镜像
ko
支持的最简单的技巧是简单地容器化和发布一个镜像。关于这一点,一个巧妙的地方在于它可以与大多数 Go 二进制文件一起使用,而无需了解 ko
。
例如(已缩短):
~/go/src/golang.org/x/tools
$ ko publish ./cmd/goimports/
Using base .. for golang.org/x/tools/cmd/goimports
Publishing gcr.io/mattmoor-public/goimports-01234:latest
mounted blob: sha256:deadbeef
mounted blob: sha256:baadf00d
mounted blob: sha256:deadf00d
pushed blob sha256:baadbeef
pushed blob sha256:beeff00d
gcr.io/mattmoor-public/goimports-01234:latest: digest: ... size: 914
Published gcr.io/mattmoor-public/goimports-01234@...
ko
也适用于发布!
您还可以使用 ko
发布可通过以下方式重新分发的内容:
# This does everything `apply` does except it pipes to
# stdout instead of kubectl
ko resolve -f config/ > release.yaml
# Later...
kubectl apply -f release.yaml
例如,我们使用它来发布所有 Knative 组件。
试试看,并告诉我们您的想法。
这仅仅触及了您可以使用 ko
执行的操作以及 ko
为您执行的操作的表面。有关更多信息,请查看 README.md。如果您有任何问题:#ko 在 slack.knative.dev,或在 Twitter @mattomata 上联系我。
一些常见的问题
由于 ko
严重依赖约定,因此需要注意以下几点
-
您需要在
${GOPATH}
中,否则它将不知道您所在的包。 -
错别字是最糟糕的。因为
ko
对模式不敏感,它会忽略任何不是“main”包的导入路径的字符串,因此如果您在导入路径中有一个简单的错别字,那么它将保持原样,并且您可能会看到您的 PodErrImagePull
错误。