跳至内容

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 严重依赖约定,因此需要注意以下几点

  1. 您需要在 ${GOPATH} 中,否则它将不知道您所在的包。
  2. 错别字是最糟糕的。因为 ko 对模式不敏感,它会忽略任何不是“main”包的导入路径的字符串,因此如果您在导入路径中有一个简单的错别字,那么它将保持原样,并且您可能会看到您的 Pod ErrImagePull 错误。

我们使用分析和 Cookie 来了解网站流量。出于此目的,有关您使用我们网站的信息将与 Google 共享。 了解更多。