1 代码结构

git clone https://github.com/kubernetes/client-go.git

git tag # 查看tag
# 以tag kubernetes-1.23.17 创建一个分支
git co -b kubernetes-1.23.17 kubernetes-1.23.17
# 或
git co -b v0.23.17 v0.23.17
 tree -L 1
.
├── rest
├── kubernetes
├── dynamic
├── discovery
├── informers
├── listers
├── applyconfigurations
├── metadata
├── pkg
├── plugin
├── restmapper
├── scale
├── testing
├── third_party
├── tools
├── transport
└── util

2 RESTClient

Tip

RESTClient是最基础的客户端
其他的ClientSet、DynamicClient及DiscoveryClient都是基于RESTClient实现的
RESTClient 对HTTP Request进行了封装,实现了RESTful风格的API

package main

import (
    "context"
    "flag"
    "fmt"
    "path/filepath"

    corev1 "k8s.io/api/core/v1"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes/scheme"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
)

func main() {
    var kubeconfig *string
    if home := homedir.HomeDir(); home != "" {
        // ~/.kube/config 确保你家目录下有k8s的配置文件
        // 你本地可以用kubectl get po 进行查询.
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    // 使用指定的kubeconfig文件创建一个Config对象
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    // 由于后面我们请求的是pod ,是核心资源, /api 这样
    config.APIPath = "api"
    // 前面我们说过, 核心资源 的group 是空, 点进去会看到是group是空的.
    config.GroupVersion = &corev1.SchemeGroupVersion
    config.NegotiatedSerializer = scheme.Codecs

    restClient, err := rest.RESTClientFor(config)
    if err != nil {
        panic(err.Error())
    }

    // k get po -n default
    // 最终 变成 http请求 localhost:8001/api/v1/namespaces/default/pods?limit=5
    podList := &corev1.PodList{}
    err = restClient.Get().
        Namespace("default").
        Resource("pods").
        VersionedParams(
            &metav1.ListOptions{Limit: 5},
            scheme.ParameterCodec).
        Do(context.TODO()).
        Into(podList)
    if err != nil {
        panic(err)
    }
    for _, item := range podList.Items {
        fmt.Println(item.Name)
    }

}
Back to top