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 非常依賴慣例,因此使用時需要注意以下幾點
-
您需要位於
${GOPATH}
,否則它將不知道您所在的套件。 -
拼寫錯誤是最糟糕的。 因為
ko
對於架構不敏感,它會忽略任何不是「main」套件的匯入路徑的字串,因此,如果您的匯入路徑中有簡單的拼寫錯誤,它會保持原樣,您可能會看到您的 PodErrImagePull
。