如何使用REST接口从Kubernetes APIServer获得“友好”响应

ygya80vv  于 2023-02-21  发布在  Kubernetes
关注(0)|答案(1)|浏览(108)

我使用Golang client-go库在REST GET、POST级别与Kubernetes API服务器通信,收到的响应不是格式良好的JSON结构,也不是“kind”API对象。
程序片段为:

kubeconfig := filepath.Join(
         os.Getenv("HOME"), ".kube", "config",
    )
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        log.Fatal(err)
    }
    config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()

    groupVersion, _ := schema.ParseGroupVersion("api/v1")
    config.GroupVersion = &groupVersion
    config.ContentType = "application/json"

    config.AcceptContentTypes = "application/json"
    
    exampleRestClient, err := rest.RESTClientFor(config)
    if err != nil {
        panic(err)
    }
    
    var statusCode int
    var contentType string

    response, err := exampleRestClient.
        Get().
        Resource("nodes").
        Do(context.Background()).
        StatusCode(&statusCode).
        ContentType(&contentType).
        Get()
    
    if err != nil {
        panic(err)
    }

    fmt.Printf("Content-type is %s\n", contentType)
    fmt.Printf("Status Code is %d\n", statusCode)

    fmt.Printf("Received response %v\n", response)

响应开始为:

Status Code is 200
Received response &NodeList{ListMeta:{ 17299  <nil>},Items:[]Node{Node{ObjectMeta:{dev-cluster-control-plane    7fe038c9-8be6-41a9-9f3f-5900abb0e34b 16922 0 2023-02-19 16:32:44 +0530 IST <nil> <nil> map[beta.kubernetes.io/arch:amd64 beta.kubernetes.io/os:linux kubernetes.io/arch:amd64 kubernetes.io/hostname:dev-cluster-control-plane kubernetes.io/os:linux node-role.kubernetes.io/control-plane: node.kubernetes.io/exclude-from-external-load-balancers:] map[kubeadm.alpha.kubernetes.io/cri-socket:unix:///run/containerd/containerd.sock node.alpha.kubernetes.io/ttl:0 volumes.kubernetes.io/controller-managed-attach-detach:true] [] [] ...

我希望输出与以下命令返回的内容类似:

$ kubectl get --raw /api/v1/nodes
{"kind":"NodeList","apiVersion":"v1","metadata":{"resourceVersion":"17481"},"items":[{"metadata":{"name":"dev-cluster-control-plane","uid":"7fe038c9-8be6-41a9-9f3f-5900abb0e34b","resourceVersion":"17351","creationTimestamp":"2023-02-19T11:02:44Z","labels":{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"dev-cluster-control-plane","kubernetes.io/os":"linux","node-role.kubernetes.io/control-plane":"","node.kubernetes.io/exclude-from-external-load-balancers":""},"annotations":{"kubeadm.alpha.kubernetes.io/cri-socket":"unix:///run/containerd/containerd.sock","node.alpha.kubernetes.io/ttl":"0" ...
xdnvmnnf

xdnvmnnf1#

收到的响应不是格式正确的JSON结构
我想您对client-go模块的操作方式感到困惑。
来自REST API的响应绝对是一个格式良好的JSON响应,但它被解组到Go语言的数据结构中(如下图所示)。
如果想访问返回的节点,可以使用标准Go语言语法与结果交互:

response, err := exampleRestClient.
  Get().
  Resource("nodes").
  Do(context.Background()).
  StatusCode(&statusCode).
  ContentType(&contentType).
  Get()

if err != nil {
  panic(err)
}

nodes := response.(*v1.NodeList)
for _, node := range nodes.Items {
  fmt.Printf("name: %s\n", node.ObjectMeta.GetName())
  fmt.Printf("addresses:\n")
  for _, addr := range node.Status.Addresses {
    fmt.Printf("  %s: %s\n", addr.Type, addr.Address)
  }
}

我希望输出与以下命令返回的内容类似:
为什么?client-go绑定返回的数据对Go语言代码很有用,如果你想生成JSON输出,你需要显式地将资源封送为JSON格式:

response, err := exampleRestClient.
  Get().
  Resource("nodes").
  Do(context.Background()).
  StatusCode(&statusCode).
  ContentType(&contentType).
  Get()

if err != nil {
  panic(err)
}

out, err := json.Marshal(response)
fmt.Print(string(out))

相关问题