跳至內容

ko:在 Go 中快速開發 Kubernetes 微服務

發布於:2019-04-10,  修訂於:2024-01-17

ko:在 Go 中快速開發 Kubernetes 微服務

作者:Matt Moore,Chainguard 的創辦人/CTO

我最初撰寫 ko 是為了幫助 Knative 開發人員。我之所以撰寫這篇介紹性文章,是因為社群的正面回饋,包括在最近的 Kubecon 西雅圖 2018 期間,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 相同的效果,但它也會建置、容器化和發布從 yamls 參照的 Go 微服務,並且配置量顯著減少

您只需編寫 Kubernetes yamls 和程式碼。不需要 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。如果您有問題:請在 slack.knative.dev 上的 #ko 中提問,或在 Twitter @mattomata 上聯繫我。

一些常見的陷阱

由於 ko 非常依賴慣例,因此使用時需要注意以下幾點

  1. 您需要位於 ${GOPATH} ,否則它將不知道您所在的套件。
  2. 拼寫錯誤是最糟糕的。 因為 ko 對於架構不敏感,它會忽略任何不是「main」套件的匯入路徑的字串,因此,如果您的匯入路徑中有簡單的拼寫錯誤,它會保持原樣,您可能會看到您的 Pod ErrImagePull

我們使用分析和 Cookie 來了解網站流量。關於您使用我們網站的資訊會與 Google 分享以達到此目的。了解更多。