client-go的使用及源码分析
本文个人博客地址:http://www.huweihuang.com/article/source-analysis/client-go-source-analysis/
1. client-go简介
1.1 client-go说明
client-go是一个调用kubernetes集群资源对象API的客户端,即通过client-go实现对kubernetes集群中资源对象(包括deployment、service、ingress、replicaSet、pod、namespace、node等)的增删改查等操作。大部分对kubernetes进行前置API封装的二次开发都通过client-go这个第三方包来实现。
client-go官方文档:https://github.com/kubernetes/client-go
1.2 示例代码
git clone https://github.com/huweihuang/client-go.git
cd client-go
#保证本地HOME目录有配置kubernetes集群的配置文件
go run client-go.gopackage main
import (
"flag"
"fmt"
"os"
"path/filepath"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
var kubeconfig *string
if home := homeDir(); home != "" {
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()
// uses the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
for {
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
time.Sleep(10 * time.Second)
}
}
func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE") // windows
}1.3 运行结果
2. client-go源码分析
client-go源码:https://github.com/kubernetes/client-go
client-go源码目录结构
The
kubernetespackage contains the clientset to access Kubernetes API.The
discoverypackage is used to discover APIs supported by a Kubernetes API server.The
dynamicpackage contains a dynamic client that can perform generic operations on arbitrary Kubernetes API objects.The
transportpackage is used to set up auth and start a connection.The
tools/cachepackage is useful for writing controllers.
2.1 kubeconfig
获取kubernetes配置文件kubeconfig的绝对路径。一般路径为$HOME/.kube/config。该文件主要用来配置本地连接的kubernetes集群。
config内容如下:
2.2 rest.config
通过参数(master的url或者kubeconfig路径)和BuildConfigFromFlags方法来获取rest.Config对象,一般是通过参数kubeconfig的路径。
BuildConfigFromFlags函数源码
k8s.io/client-go/tools/clientcmd/client_config.go
2.3 clientset
通过*rest.Config参数和NewForConfig方法来获取clientset对象,clientset是多个client的集合,每个client可能包含不同版本的方法调用。
2.3.1 NewForConfig
NewForConfig函数就是初始化clientset中的每个client。
k8s.io/client-go/kubernetes/clientset.go
2.3.2 clientset的结构体
k8s.io/client-go/kubernetes/clientset.go
2.3.3 clientset.Interface
clientset实现了以下的Interface,因此可以通过调用以下方法获得具体的client。例如:
clientset的方法集接口
k8s.io/client-go/kubernetes/clientset.go
2.4 CoreV1Client
我们以clientset中的CoreV1Client为例做分析。
通过传入的配置信息rest.Config初始化CoreV1Client对象。
k8s.io/client-go/kubernetes/clientset.go
2.4.1 corev1.NewForConfig
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
corev1.NewForConfig方法本质是调用了rest.RESTClientFor(&config)方法创建RESTClient对象,即CoreV1Client的本质就是一个RESTClient对象。
2.4.2 CoreV1Client结构体
以下是CoreV1Client结构体的定义:
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
CoreV1Client实现了CoreV1Interface的接口,即以下方法,从而对kubernetes的资源对象进行增删改查的操作。
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
2.4.3 CoreV1Interface
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
CoreV1Interface中包含了各种kubernetes对象的调用接口,例如PodsGetter是对kubernetes中pod对象增删改查操作的接口。ServicesGetter是对service对象的操作的接口。
2.4.4 PodsGetter
以下我们以PodsGetter接口为例分析CoreV1Client对pod对象的增删改查接口调用。
示例中的代码如下:
CoreV1().Pods()
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
newPods()
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
CoreV1().Pods()的方法实际上是调用了newPods()的方法,创建了一个pods对象,pods对象继承了rest.Interface接口,即最终的实现本质是RESTClient的HTTP调用。
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
pods对象实现了PodInterface接口。PodInterface定义了pods对象的增删改查等方法。
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
PodsGetter
PodsGetter继承了PodInterface的接口。
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
Pods().List()
pods.List()方法通过RESTClient的HTTP调用来实现对kubernetes的pod资源的获取。
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
以上分析了clientset.CoreV1().Pods("").List(metav1.ListOptions{})对pod资源获取的过程,最终是调用RESTClient的方法实现。
2.5 RESTClient
以下分析RESTClient的创建过程及作用。
RESTClient对象的创建同样是依赖传入的config信息。
k8s.io/client-go/kubernetes/typed/core/v1/core_client.go
2.5.1 rest.RESTClientFor
k8s.io/client-go/rest/config.go
RESTClientFor函数调用了NewRESTClient的初始化函数。
2.5.2 NewRESTClient
k8s.io/client-go/rest/client.go
2.5.3 RESTClient结构体
以下介绍RESTClient的结构体定义,RESTClient结构体中包含了http.Client,即本质上RESTClient就是一个http.Client的封装实现。
k8s.io/client-go/rest/client.go
2.5.4 RESTClient.Interface
RESTClient实现了以下的接口方法:
k8s.io/client-go/rest/client.go
在调用HTTP方法(Post(),Put(),Get(),Delete() )时,实际上调用了Verb(verb string)函数。
k8s.io/client-go/rest/client.go
Verb函数调用了NewRequest方法,最后调用Do()方法实现一个HTTP请求获取Result。
2.6 总结
client-go对kubernetes资源对象的调用,需要先获取kubernetes的配置信息,即$HOME/.kube/config。
整个调用的过程如下:
kubeconfig→rest.config→clientset→具体的client(CoreV1Client)→具体的资源对象(pod)→RESTClient→http.Client→HTTP请求的发送及响应
通过clientset中不同的client和client中不同资源对象的方法实现对kubernetes中资源对象的增删改查等操作,常用的client有CoreV1Client、AppsV1beta1Client、ExtensionsV1beta1Client等。
3. client-go对k8s资源的调用
创建clientset
3.1 deployment
3.2 service
3.3 ingress
3.4 replicaSet
新版的kubernetes中一般通过deployment来创建replicaSet,再通过replicaSet来控制pod。
3.5 pod
3.6 statefulset
通过以上对kubernetes的资源对象的操作函数可以看出,每个资源对象都有增删改查等方法,基本调用逻辑类似。一般二次开发只需要创建deployment、service、ingress三个资源对象即可,pod对象由deployment包含的replicaSet来控制创建和删除。函数调用的入参一般只有NAMESPACE和kubernetesObject两个参数,部分操作有Options的参数。在创建前,需要对资源对象构造数据,可以理解为编辑一个资源对象的yaml文件,然后通过kubectl create -f xxx.yaml来创建对象。
参考文档:
https://github.com/kubernetes/client-go
最后更新于
这有帮助吗?