问题描述
当我使用client-go从api获取kubernetes资源,但是在响应中找不到apiversion和kind,apiversion和kind为空。如何获取资源的apiversion和种类?
下面是我的代码:
package main
import (
"flag"
"k8s.io/client-go/tools/clientcmd"
"log"
"k8s.io/client-go/kubernetes"
Metav1 "k8s.io/apimachinery/pkg/apis/Meta/v1"
"fmt"
)
var clientset *kubernetes.Clientset
func main() {
k8sconfig := flag.String("k8sconfig","./k8sconfig","kubernetes config file path")
flag.Parse()
config,err := clientcmd.BuildConfigFromFlags("",*k8sconfig)
if err != nil {
log.Println(err)
}
clientset,err = kubernetes.NewForConfig(config)
if err != nil {
log.Fatalln(err)
} else {
fmt.Println("connect k8s success")
}
pods,err := clientset.CoreV1().Pods("").List(Metav1.ListOptions{})
if err != nil {
log.Println(err.Error())
}
for _,pod := range pods.Items{
fmt.Println("apiversion: ",pod.APIVersion,"kind: ",pod.Kind)
}
}
The output:
apiversion: kind:
apiversion: kind:
apiversion: kind:
apiversion: kind:
apiversion: kind:
apiversion: kind:
apiversion: kind:
apiversion: kind:
......
......
解决方法
我认为问题在于您使用 List()
API 获取 pod 列表,因此它不是您期望的 pod,并且没有 Kind
字段。
您需要遍历 pod 列表以访问单个 pod:
for _,pod := range pods.Items {
fmt.Printf("%s %s\n",pod.GetName(),pod.GetCreationTimestamp())
}
Kind
字段是 Pod's Metadata
的一部分,可以使用 pod.ObjectMeta.Kind
访问。
您没有得到 APIVersion
和 Kind
,因为它被代码忽略了。
如果您查看 API 服务器 JSON response,它将类似于以下内容:
{
"kind":"PodList","apiVersion":"v1","metadata":{
"resourceVersion":"2397"
},"items":[
{
... ... ...
因此响应确实包含 APIVersion
和 Kind
。但是当响应被解码为 k8s 对象时,here
out,_,err := r.decoder.Decode(r.body,nil,obj)
这里可以看到忽略了第二个输出参数,即 schema.GroupVersionKind
。
func (c *Something) Decode([]byte,*schema.GroupVersionKind,runtime.Object) (runtime.Object,error) {
}
注意:当您使用 client-go(动态客户端除外)进行 API 调用时,您已经知道 APIVersion(即 CoreV1()
)和 Kind(即List()
).