Golang中如何导入KFServing客户端包

How to Import KFServing Client Package in Golang

我们正在我们的 kubernetes 集群中使用 KFServing。该项目在文件夹 pkg/.

中提供 InferenceService struct 和 clientset

如何在pkg/client下导入这些包?我的代码如下:

package main
import (
    "fmt"
    kfs 
   "github.com/kubeflow/kfserving/pkg/client/clientset/versioned"
)

func main() {
   var clientset   *kfs.Cientset
   clientset = kfs.NewForConfig(nil)
   fmt.Println(clientset)
}
           

尝试 go mod 整洁 我得到了(我需要指定版本 v0.5.1 上的开发):

    main imports
    github.com/kubeflow/kfserving/pkg/client/clientset/versioned 
    imports
    k8s.io/client-go/discovery imports
    github.com/googleapis/gnostic/OpenAPIv2: 
     module github.com/googleapis/gnostic@latest found (v0.5.5), 
     but does not contain package 
     github.com/googleapis/gnostic/OpenAPIv2
     main imports
    github.com/kubeflow/kfserving/pkg/client/clientset/versioned 
    imports
    ...

尝试编译我得到的这些代码:

  a lot of errors .....

之后得到github.com/kubeflow/kfserving我得到:

然后我更改了 go.mod 并将 kfseving 版本从 v0.6.0 重新配置为 v0.5.1 然后重新编译这些代码,仍然出现以下错误:

go build .
 go: github.com/kubeflow/kfserving@v0.5.1: missing go.sum entry; to add it:
    go mod download github.com/kubeflow/kfserving

go.mod 的内容:

module main

go 1.16

require github.com/kubeflow/kfserving v0.5.1 // indirect

更新
kfserving v0.4.0 一切正常

这似乎是一个模块缓存问题,因为 v0.5.1 包似乎在那里。执行以下操作:

  1. 清理 modcache go clean --modcache
  2. 通过 go get github.com/kubeflow/kfserving@v0.5.1
  3. 获得模块的好方法
  4. 运行 go mod tidy

更新

通过额外的输出,我可以看到您有来自依赖模块的导入错误。

github.com/kubeflow/kfserving/pkg/client/clientset/versioned 
    imports
    k8s.io/client-go/discovery imports
    github.com/googleapis/gnostic/OpenAPIv2:

所以版本 v0.5.1 导入了 k8s.io/client-go/discovery,导入了 github.com/googleapis/gnostic/OpenAPIv2,它在当前版本中不再存在(但它有 older 版本)。所以看起来您需要修复 client-go 中的导入版本以避免此问题。

查看 v0.5.1 处的 kfserving go.mod 文件,我看到 a big block of replace directives. By design, replace directives “仅适用于主模块的 go.mod 文件,在其他模块”,所以看起来 kfserving 在这里有一些技术债务,他们正在转嫁给你。

我从一个空的 go.mod 文件开始,然后粘贴了那些 replace 指令。那么:

$ go get -d github.com/kubeflow/kfserving/pkg/client/clientset/versioned@v0.5.1
go get: added github.com/PuerkitoBio/purell v1.1.1
…
go get: added sigs.k8s.io/yaml v1.2.0

.go 源文件需要一些拼写错误和不匹配类型的修复。我把它捏造成:

package main

import (
    "fmt"

    kfs "github.com/kubeflow/kfserving/pkg/client/clientset/versioned"
)

func main() {
    var clientset *kfs.Clientset
    clientset = kfs.NewForConfigOrDie(nil)
    fmt.Println(clientset)
}

然后 go build . 成功:

$ go build -o /dev/null .

现在我将 运行 go mod tidy 清理 go.modgo.sum 文件:

$ go mod tidy
go: downloading github.com/stretchr/testify v1.5.1
…
go: downloading github.com/jmespath/go-jmespath v0.3.0

但是等等!我仍然欠 kfserving/go.mod 所有的技术债——没有任何解释版本选择的评论! — 我正在将技术债务转嫁给任何下游用户。让我们看看我在这里是否可以改善这种情况。

Go 1.16 比以前的 Go 版本更好地处理 exclude 指令,所以也许我可以使用几个有针对性的 exclude 指令而不是(相当大的)replace 锤.

我将从提交到目前为止的修复开始。 (如果不出意外,我希望能够git diff 看看需求有什么变化。)

$ git add *.go go.mod go.sum

$ git commit -m 'fixed kfserving build'
[main fd93b1d] fixed kfserving build
 3 files changed, 1643 insertions(+), 2 deletions(-)
 create mode 100644 go.sum

我注意到所有 replace 指令都适用于 k8s.io 路径,因此我将列出这些路径的当前版本以查看需要修复的内容:

$ go list -m k8s.io/...
k8s.io/api v0.19.2 => k8s.io/api v0.19.2
k8s.io/apiextensions-apiserver v0.19.2 => k8s.io/apiextensions-apiserver v0.19.2
k8s.io/apimachinery v0.19.2 => k8s.io/apimachinery v0.19.2
k8s.io/apiserver v0.19.2 => k8s.io/apiserver v0.19.2
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible => k8s.io/client-go v0.19.2
k8s.io/cloud-provider v0.19.2 => k8s.io/cloud-provider v0.19.2
k8s.io/code-generator v0.19.2 => k8s.io/code-generator v0.19.2
k8s.io/component-base v0.19.2 => k8s.io/component-base v0.19.2
k8s.io/csi-translation-lib v0.19.2 => k8s.io/csi-translation-lib v0.19.2
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14
k8s.io/klog v1.0.0 => k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.2.0
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6
k8s.io/legacy-cloud-providers v0.17.4 => k8s.io/legacy-cloud-providers v0.19.2
k8s.io/test-infra v0.0.0-20200803112140-d8aa4e063646 => k8s.io/test-infra v0.0.0-20200803112140-d8aa4e063646
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89

大多数看起来不错,但有三个不匹配的版本:

k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible => k8s.io/client-go v0.19.2
…
k8s.io/legacy-cloud-providers v0.17.4 => k8s.io/legacy-cloud-providers v0.19.2
…
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89

legacy-cloud-providers 只需要升级,所以用 go get 修复应该很容易——但它与这个包无关,所以我可以让它浮动到它结束的任何版本到。我将把 replace 指令减少到剩下的两个模块,看看我能走多远:

replace (
    k8s.io/client-go => k8s.io/client-go v0.19.2
    k8s.io/utils => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
)

现在:

$ go mod tidy

$ go build -o /dev/null .

好的,所以构建仍然很好——我已经取得了渐进的进展,所以我会把它锁定在:

$ git add go.mod go.sum

$ git commit -m 'go.mod: remove irrelevant replacements'
[main cdbc1db] go.mod: remove irrelevant replacements
 3 files changed, 456 insertions(+), 43 deletions(-)
 rewrite go.mod (85%)
 create mode 100755 m

现在让我们尝试使用 exclude 指令去除错误的 client-go 版本:

$ go mod edit -exclude=k8s.io/client-go@v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible

$ go list -m k8s.io/client-go
k8s.io/client-go v9.0.0+incompatible => k8s.io/client-go v0.19.2

$ go mod edit -exclude=k8s.io/client-go@v9.0.0+incompatible

$ go list -m k8s.io/client-go
k8s.io/client-go v0.19.2 => k8s.io/client-go v0.19.2

现在我处于我需要的 client-go 版本,所以我可以删除 replace 指令:

$ go mod edit -dropreplace=k8s.io/client-go

$ go mod tidy

$ go build -o /dev/null .

再次锁定:

$ git add go.mod go.sum

$ git commit -m 'go.mod: use exclude instead of replace to notch out unwanted client-go versions'
[main de69965] go.mod: use exclude instead of replace to notch out unwanted client-go versions
 2 files changed, 21 insertions(+), 3 deletions(-)

现在让我们看看这个 k8s.io/utils 替换发生了什么。我怀疑它并不是真正需要的——版本会升级一点,但我敢打赌它不会破坏构建。而且,确实,它似乎很好:

$ go list -m k8s.io/utils
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89

$ go mod edit -dropreplace=k8s.io/utils

$ go mod tidy

$ go build -o /dev/null .

$ go list -m k8s.io/utils
k8s.io/utils v0.0.0-20200912215256-4140de9c8800

所以现在我已经成功地将 replace 指令的大巢从 kfserving 减少到仅针对 k8s.io/client-go 的缩回版本的几个 exclude 指令。这是我在此过程结束时的整个 go.mod 文件:

module example.com/m

go 1.16

exclude (
    k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
    k8s.io/client-go v9.0.0+incompatible
)

require github.com/kubeflow/kfserving v0.5.1