带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(四)

(3)r.request方法首先检查是否设置 httpclient,如果没有,则使用 net/http默认的DefaultClient、r.URL.String方法根据配置的请求参数生成请求的 RESTfulURL,示例中生成的请求  URL 应该为  https://xxx/api/v1/namespaces/default/pods?limit=100之后用 net/http标准库构建 req请求并发送该请求,最终fn函数变量对 APIServer返回值进行解析(见代码清单2-14

func(r*Request)request(ctxcontext.Context,fnfunc(*http.Request,*http.Response))error{

  

//...

 

client:=r.c.Clientifclient==nil{

client=http.DefaultClient

}

 

//...for{

 

url:=r.URL().String()

req,err:=http.NewRequest(r.verb,url,r.body)

 

//...

resp,err:=client.Do(req)

 

//...

done:=func()bool{

//...

 


 

 

}()

//...

}

}


fn(req,resp)returntrue


 

总结:KubernetesAPIServer  有很多操作资源的接口,而RESTClient就是对访问这些 API 的封装。

1. ClientSet

 

虽然 RESTClient可以访问 Kubernetes 的任意资源对象,但在使用时需要配置的参数过于烦琐,为了更为优雅地处理,需要进一步封装。ClientSet继承自 RESTClient,使用预生成的 API对象与 APIServer进行交互,方便开发者二次开发。

ClientSet 是一组资源客户端的集合,比如操作Pods、Services、Secrets资源的CoreV1Client,操作 Deployments、ReplicaSets、DaemonSets资源的ExtensionsV1beta1Client等,如图2-5所示,直接通过这些客户端提供的操作方法即可对Kubernetes内置的原生资源进行 Create、Update、Get、List、Delete等多种操作。


 

 

带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(四)

 

图 2—5CientSet 交互图

 

ClientSet的使用方式在前面已有讲解,这里不再赘述。下面分析核心代码clientset.

CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})的执行流程。

ClientSet包含众多资源客户端,CoreV1方法负责返回 CoreV1Client(见代码清单2-15)。

typeClientsetstruct{

*discovery.DiscoveryClient

//...

coreV1                          *corev1.CoreV1Client

 

//...

}

//...

 

//CoreV1retrievestheCoreV1Client

func(c*Clientset)CoreV1()corev1.CoreV1Interface{returnc.coreV1


}

Pods方法的参数用于设定 Namespace, 内部调用 newPods函数, 该函数返回实现PodInterface的对象(见代码清单2-16)。

func(c*CoreV1Client)Pods(namespacestring)PodInterface{returnnewPods(c,namespace)

}

 

可以看到 PodInterface 包含了操作 Pods 资源的全部方法,newPods 函数构造的 Pods对象内部包含 RESTClient,在 Pods对象的List 方法中,我们看到了熟悉的 RESTClient操作资源的调用流程(见代码清单2-17)。

typePodInterfaceinterface{

Create(ctxcontext.Context,pod*v1.Pod,optsmetav1.CreateOptions)(*v1.Pod,error)

Update(ctxcontext.Context,pod*v1.Pod,optsmetav1.UpdateOptions)(*v1.Pod,error)

UpdateStatus(ctxcontext.Context,pod*v1.Pod,optsmetav1.

UpdateOptions)(*v1.Pod,error)

Delete(ctxcontext.Context,namestring,optsmetav1.DeleteOptions)

error

DeleteCollection(ctxcontext.Context,optsmetav1.DeleteOptions,

listOptsmetav1.ListOptions)error

Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Pod, error)List(ctxcontext.Context,optsmetav1.ListOptions)(*v1.PodList,error)

//...

}

 

funcnewPods(c*CoreV1Client,namespacestring)*pods{return&pods{

client:c.RESTClient(),ns:namespace,

}

}

 

//...

 

func(c*pods)List(ctxcontext.Context,optsmetav1.ListOptions)(result

*v1.PodList,errerror){

//...

 

result=&v1.PodList{}err=c.client.Get().

Namespace(c.ns).


 

Resource("pods").

VersionedParams(&opts,scheme.ParameterCodec).Timeout(timeout).

Do(ctx).

Into(result)

return

}

上一篇:带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(六)


下一篇:关于django的url的namespace和view写法