go mod 依賴管理的心路歷程

在用kubebuilder寫一個k8s operator defaultvm,主要是串起ovn網絡和虛機的建立,爲用戶提供默承認用的虛機。git

Kubebuilder 是一個基於 CRD 來構建 Kubernetes API 的框架,能夠使用 CRD 來構建 API、Controller 和 Admission Webhook。

代碼裏面調用了 kubevirt.io/client-go 定義的 virtualmachine,使用go mod進行依賴管理,默認引用了 kubevirt.io/client-go v0.23.0,但在編譯時就報錯了,適中拉不到prometheus的包github

go: github.com/prometheus/prometheus@v2.9.2+incompatible: unexpected status (https://goproxy.io/github.com/prometheus/prometheus/@v/v2.9.2+incompatible.info): 410 Gone

確認依賴問題

單獨使用go mod download驗證確實拉不到包。json

[root@master01 queqiao]# go mod download github.com/prometheus/prometheus@v2.9.2+incompatible
go: finding github.com/prometheus/prometheus v2.9.2+incompatible
github.com/prometheus/prometheus@v2.9.2+incompatible: reading https://goproxy.io/github.com/prometheus/prometheus/@v/v2.9.2+incompatible.info: 410 Gone

google找到一種說法,由於國內牆的緣由,只能使用export GOPROXY=https://goproxy.io && export GO111MODULE=on,而後goproxy.io缺乏對prometheus@v2.9.2+incompatible的支持。能夠將GOPROXY改爲direct試試,export GOPROXY=direct,不過因爲國內的fgw,改爲direct後,就卡死了,只能放棄。api

切低版本kubevirt

prometheus@v2.9.2+incompatible是kubevit的依賴,咱們沒法控制,咱們只能控制kubevirt,從小夥伴哪兒的得知kubevit v0.19.0沒有對prometheus v2.9.2+incompatible的依賴,網絡

go mod edit -replace=kubevirt.io/client-go@v0.23.0=kubevirt.io/client-go@v0.19.0

使用go mod edit切換回kubevit v0.19.0,果真順利編譯經過了。不過可悲的是,調試運行一段時間後,觸發了kubevirt新的bug,而這個bug在v0.23.0版本修復了框架

參考:https://github.com/kubevirt/k...ui

所以只能從新面對依賴這個問題google

拉取kubevirt代碼

爲了避免對kubevirt 依賴,咱們決定直接摳出kubevirt 中對virtual machine這個cr的定義。這個方法確實行之有效,減去了對kubevirt的依賴,不過卻形成了一系列我沒預想到的包之間版本不匹配的問題調試

如:最開始遇到的報錯rest

# k8s.io/client-go/rest
vendor/k8s.io/client-go/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
    have (*versioned.Decoder)
    want (watch.Decoder, watch.Reporter)

go的依賴庫都是用go mod進行自動管理的,沒想到會有依賴庫之間版本不匹配的問題。

匹配依賴庫版本

既然go mod管理有問題,那隻能從問題入手,人工匹配正確的依賴庫版本。

參考: https://github.com/kubernetes...

That apimachinery change is in the master branch, and the call you linked to is updated in client-go on master.

The client-go@v11.0.0 tag works with the release-1.14 branch of apimachinery, which still has the signature that matches client-go v11.0.0:

https://github.com/kubernetes/apimachinery/blob/release-1.14/pkg/watch/streamwatcher.go#L51-L52

Ensure you are using the release-1.14 branch of apimachinery.

根據大佬的提示,使用release-1.14版本的apimachinery,

[root@master01 queqiao]# go mod download -json k8s.io/apimachinery@release-1.14
go: finding k8s.io/apimachinery release-1.14
go: finding k8s.io/apimachinery latest
{
    "Path": "k8s.io/apimachinery",
    "Version": "v0.0.0-20191004074956-c5d2f014d689",
    "Info": "/root/go/pkg/mod/cache/download/k8s.io/apimachinery/@v/v0.0.0-20191004074956-c5d2f014d689.info",
    "GoMod": "/root/go/pkg/mod/cache/download/k8s.io/apimachinery/@v/v0.0.0-20191004074956-c5d2f014d689.mod",
    "Zip": "/root/go/pkg/mod/cache/download/k8s.io/apimachinery/@v/v0.0.0-20191004074956-c5d2f014d689.zip",
    "Dir": "/root/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20191004074956-c5d2f014d689",
    "Sum": "h1:q9CWH+mCm21qUeXH537D0Q9K1jdEkreNSRU5E7jh+QM=",
    "GoModSum": "h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0="
}

確實解決了以前的報錯。可是依然有新的報錯,排查是哪一個依賴庫調用的報錯,而後採用相似的辦法,切換到release-1.14,最終go.mod中手動配置的依賴庫版本爲:

replace (
    k8s.io/api => k8s.io/api v0.0.0-20191004102349-159aefb8556b
    k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191004105649-b14e3c49469a
    k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191004074956-c5d2f014d689
    sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.3.0
)

最後提一下sigs.k8s.io/controller-runtime ,查看了它的全部版本,而後一次次嘗試,才發現v0.3.0能夠編譯經過。

感慨

這個依賴庫問題花了我近兩天的時間,期間搜了不少方法,踩了不少的坑,遠比文中描述的糟心。正由於糟心,才寫下來,一方面加深本身的體會,另外一方面,以但願可以幫助到一樣遇到這個問題的小夥伴。

in the peace

相關文章
相關標籤/搜索