在用kubebuilder写一个k8s operator defaultvm,主要是串起ovn网络和虚机的创建,为用户提供默认可用的虚机。
Kubebuilder 是一个基于 CRD 来构建 Kubernetes API 的框架,可以使用 CRD 来构建 API、Controller 和 Admission Webhook。
代码里面调用了 kubevirt.io/client-go 定义的 virtualmachine,使用go mod进行依赖管理,默认引用了 kubevirt.io/client-go v0.23.0
,但在编译时就报错了,适中拉不到prometheus的包
go: github.com/prometheus/[email protected]+incompatible: unexpected status (https://goproxy.io/github.com/prometheus/prometheus/@v/v2.9.2+incompatible.info): 410 Gone
确认依赖问题
单独使用go mod download验证确实拉不到包。
[root@master01 queqiao]# go mod download github.com/prometheus/[email protected]+incompatible
go: finding github.com/prometheus/prometheus v2.9.2+incompatible
github.com/prometheus/[email protected]+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缺少对[email protected]+incompatible
的支持。可以将GOPROXY改成direct试试,export GOPROXY=direct
,不过由于国内的fgw,改成direct后,就卡死了,只能放弃。
切低版本kubevirt
[email protected]+incompatible
是kubevit的依赖,我们无法控制,我们只能控制kubevirt,从小伙伴哪儿的得知kubevit v0.19.0没有对prometheus v2.9.2+incompatible的依赖,
go mod edit -replace=kubevirt.io/[email protected]=kubevirt.io/[email protected]
使用go mod edit切换回kubevit v0.19.0,果然顺利编译通过了。不过可悲的是,调试运行一段时间后,触发了kubevirt新的bug,而这个bug在v0.23.0版本修复了
参考:https://github.com/kubevirt/k...
因此只能重新面对依赖这个问题
拉取kubevirt代码
为了不对kubevirt 依赖,我们决定直接抠出kubevirt 中对virtual machine这个cr的定义。这个方法确实行之有效,减去了对kubevirt的依赖,不过却造成了一系列我没预想到的包之间版本不匹配的问题
如:最开始遇到的报错
# 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 [email protected] 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/[email protected]
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/[email protected]",
"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