4. DiscoveryClient
RESTClient、DynamicClient、DiscoveryClient 都是面向资源对象的(例如,Deployment、Pod、CRD等),而DiscoveryClient则聚焦资源,用于查看当前Kubernetes集群支持哪些资源组(Group)、资源版本(Version)、资源信息(Resource)。
DiscoveryClient代码示例见代码清单2-23。
packagemain
import(
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema""k8s.io/client-go/discovery""k8s.io/client-go/tools/clientcmd"
)
funcmain(){
//加载 kubeconfig⽂件,⽣成 config对象
config,err:=clientcmd.BuildConfigFromFlags("","/root/.kube/config")
iferr!=nil{
panic(err)
}
//通过 config实例化 DiscoveryClient对象
discoveryClient,err:=discovery.NewDiscoveryClientForConfig(config)
iferr!=nil{
panic(err)
}
//返回 KubernetesAPIServer所⽀持的资源组、资源版本和资源信息
_,APIResourceList,err:=discoveryClient.ServerGroupsAndResources()iferr!=nil{
panic(err)
}
//输出所有资源信息
for_,list:=rangeAPIResourceList{
gv,err:=schema.ParseGroupVersion(list.GroupVersion)iferr!=nil{
panic(err)
}
for_,resource:=rangelist.APIResources{
fmt.Printf("NAME:%v,GROUP:%v,VERSION:%v\n",resource.
Name,gv.Group,gv.Version)
}
}
}
运行以上代码会获得 KubernetesAPIServer支持的 GVR 等相关信息,部分信息打印
输出见代码清单 2-24。
# 运⾏输出
NAME:bindings,GROUP:,VERSION:v1
NAME:componentstatuses,GROUP:,VERSION:v1
NAME:configmaps,GROUP:,VERSION:v1
...
DiscoveryClient发起请求的过程见代码清单 2-25。
NewDiscoveryClientForConfig获取客户端对象,其中 DiscoveryClient中封装了REST-Client类型的客户端, 且赋值 LegacyPrefix为 /api, 该变量在之后请求KubernetesAPIServer时会被用到。
funcNewDiscoveryClientForConfig(c*restclient.Config)(*DiscoveryClient,error){
//...
client,err:=restclient.UnversionedRESTClientFor(&config)
return&DiscoveryClient{restClient:client,LegacyPrefix:"/api"},err
}
ServerGroupsAndResources方法中会调用 ServerGroupsAndResources函数,该函数主要关注ServerGroups方法和fetchGroupVersionResources函数(见代码清单2-26)。
funcServerGroupsAndResources(dDiscoveryInterface)([]*metav1.APIGroup,[]*metav1.APIResourceList,error){
sgs,err:=d.ServerGroups()
//...
groupVersionResources,failedGroups:=fetchGroupVersionResources(d,sgs)
//...
}
ServerGroups方法通过 RESTClient来访问 KubernetesAPIServer的 /api接口
(d.LegacyPrefix)和/apis接口,获得其所支持的Group和Version信息(见代码清单2-27)。
func(d*DiscoveryClient)ServerGroups()(apiGroupList*metav1.APIGroupList,errerror){
//GetthegroupVersionsexposedat/api
v:=&metav1.APIVersions{}
err=d.restClient.Get().AbsPath(d.LegacyPrefix).Do(context.TODO()).Into(v)
//...
//GetthegroupVersionsexposedat/apisapiGroupList=&metav1.APIGroupList{}
err=d.restClient.Get().AbsPath("/apis").Do(context.TODO()).Into(apiGroupList)
//...
}
fetchGroupVersionResources函数调用 ServerResourcesForGroupVersion 方法,同样通过 RESTClient获取特定 Group和 Version中所包含的所有 Resource(见代码清单2-28)。
func(d*DiscoveryClient)ServerResourcesForGroupVersion(groupVersionstring)
(resources*metav1.APIResourceList,errerror){
//...
iflen(d.LegacyPrefix)>0&&groupVersion=="v1"{url.Path=d.LegacyPrefix+"/"+groupVersion
}else{
url.Path="/apis/"+groupVersion
}
resources=&metav1.APIResourceList{GroupVersion:groupVersion,
}
err=d.restClient.Get().AbsPath(url.String()).Do(context.TODO()).Into(resources)
//...}