前面我们介绍的是标准的 DiscoveryClient,由于 GVR 信息变动很少,因此,可以将KubernetesAPIServer 返回的 GVR 信息缓存在本地,以此减轻 KubernetesAPIServer的压力,这里可以使用 Discover/Cached目录下的两个客户端:CachedDiscoveryClient和 memCacheClient,分别将 GVR 信息缓存到本地文件(~/.kube/cache和 ~/.kube/http-cache)和内存中。
Kubectl的 apiVersions命令就是利用 CachedDiscoveryClient来实现的, 如 API-VersionsOptions结构体中 discoveryClient 变量是 CachedDiscoveryInterface 类型,而CachedDiscoveryClient结构体实现了该接口,且在 APIVersionsOptions的 Complete方法中会将CachedDiscoveryClient客户端赋值到discoveryClient变量(见代码清单2-30)。
//APIVersionsOptionshavethedatarequiredforAPIversionstypeAPIVersionsOptionsstruct{
discoveryClientdiscovery.CachedDiscoveryInterface
genericclioptions.IOStreams
}
CachedDiscoveryClient获取Group、Version和 Resource的流程与 DiscoveryClient类似,只是在 ServerResourcesForGroupVersion 方法的实现上存在差异。
(1) CachedDiscoveryClient首先通过 getCachedFile 方法查找本地缓存。
(2) 如果信息不存在(未命中)或超时时才会通过 CachedDiscoveryClient结构体成员 delegate的 ServerResourcesForGroupVersion方法访问 KubernetesAPIServer,此时相当于通过DiscoveryClient访问(见代码清代2-31)。
typeCachedDiscoveryClientstruct{delegatediscovery.DiscoveryInterface
//...
}
(3) 最后通过 writeCachedFile方法将 KubernetesAPIServer 返回的数据存储在本地硬盘。
具体代码分析见代码清单 2-32。
func(d*CachedDiscoveryClient)ServerResourcesForGroupVersion(groupVersion
string)(*metav1.APIResourceList,error){
//查找本地缓存
filename:=filepath.Join(d.cacheDirectory,groupVersion,"serverresources.
json")
cachedBytes,err:=d.getCachedFile(filename)
//...
//利⽤ DiscoveryClient中的 RESTClient访问KubernetesAPIServer
liveResources,err:=d.delegate.ServerResourcesForGroupVersion(groupVersion)
//...
//将 KubernetesAPIServer响应的数据缓存到本地硬盘
iferr:=d.writeCachedFile(filename,liveResources);err!=nil{
//...
}
另一种实现方法 memCacheClient与之类似,只是将数据缓存在 map[string]*cacheEntry类型中。