k8s的client-go的使用
<p>学习地址:https://github.com/kubernetes/client-go<br>如果你要安装最新的需要的环境是: go1.16+ ,使用下面的命令安装:</p>
<pre><code class="language-shell">go get k8s.io/client-go@latest
</code></pre>
<p> client-go 是用 Golang 语言编写的官方编程式交互客户端库,提供对 Kubernetes API server 服务的交互访问。它是 Kubernetes 的核心处理框架,k8s源码中已经集成了client-go的源码,无需单独下载。源码路径为:vendor/k8s.io/client-go。</p>
<p> k8s开发者使用client-go做二次开发,所以应该熟练掌握。</p>
<h4 id="1client-go源码结构">1、client-go源码结构</h4>
<p>其源码目录结构如下:</p>
<ol>
<li>
<p><strong>discovery</strong>: 提供 DiscoveryClient 发现客户端。</p>
</li>
<li>
<p><strong>dynamic</strong>: 提供 DynamicClient 动态客户端。</p>
</li>
<li>
<p><strong>informers</strong>: 每种 K8S 资源的 Informer 实现。</p>
</li>
<li>
<p><strong>kubernetes</strong>: 提供 ClientSet 客户端。</p>
</li>
<li>
<p><strong>listers</strong>: 为每一个 K8S 资源提供 Lister 功能,该功能对 Get 和 List 请求提供只读的缓存数据。</p>
</li>
<li>
<p><strong>plugin</strong>: 提供 OpenStack,GCP 和 Azure 等云服务商授权插件。</p>
</li>
<li>
<p><strong>rest</strong>: 提供 RESTClient 客户端,对 K8S API Server 执行 RESTful 操作。</p>
</li>
<li>
<p><strong>scale</strong>: 提供 ScaleClient 客户端,用于扩容或缩容 Deployment, Replicaset, Replication Controller 等资源对象。</p>
</li>
<li>
<p><strong>tools</strong>: 提供常用工具,例如 SharedInformer, Relector, DealtFIFO 及 Indexers。 提供 Client 查询和缓存机制,以减少想 kube-apiserver 发起的请求数等。主要子目录为 /tools/cache。</p>
</li>
<li>
<p><strong>transport</strong>: 提供安全的 TCP 连接,支持 HTTP Stream,某些操作需要在客户端和容器之间传输二进制流,例如 exec,attach 等操作。该功能由内部的 SPDY 包提供支持。</p>
</li>
<li>
<p><strong>util</strong>: 提供常用方法。例如 WorkQueue 工作队列,Certificate 证书管理等。</p>
</li>
</ol>
<p>这章我们只简单介绍下RESTClient、DiscoveryClient、DynamicClient、ClientSet这4中客户端。</p>
<h4 id="2client客户端对象">2、Client客户端对象</h4>
<p>client-go 支持4种Client客户端对象 与 k8s api server 交互的方式,Client交互对象如下图所示:<br>
<img src="https://img2022.cnblogs.com/blog/2828750/202204/2828750-20220404213955273-752107809.png"><br>
RESTClient 是最基础的客户端。RESTClient 对 HTTP Request 进行了封装,实现了RESTful风格的api。ClientSet、DynamicClient及DiscoveryClient客户端都是基于RESTClient 实现的。</p>
<ul>
<li>
<p><strong>RESTClient 客户端</strong></p>
<p> RESTful Client 是最基础的客户端,它主要是对 HTTP 请求进行了封装,并且支持 JSON 和 Protobuf 格式数据。</p>
</li>
<li>
<p><strong>DynamicClient 客户端</strong></p>
<p> DynamicClient 与 ClientSet 最大的不同之处是,ClientSet 仅能访问k8s自带的资源,不能直接访问CRD自定义资源。DynamicClient 能处理k8s中的所有的资源对象,包括内置资源与CRD自定义资源。</p>
</li>
<li>
<p><strong>ClientSet 客户端</strong></p>
<p> ClientSet 客户端在 RESTClient 的基础上封装了对<strong>资源</strong>(Resource)和<strong>版本</strong>(Version)的管理方法。每个<strong>资源</strong>(Resource)可以理解为一个客户端,而 ClientSet 则是多个客户端的集合,每一个<strong>资源</strong>(Resource)和<strong>版本</strong>(Version)都以函数的方式暴露给开发者。ClientSet 只能处理k8s内置资源。</p>
</li>
<li>
<p><strong>DiscoveryClient 客户端</strong></p>
<p> DiscoveryClient 发现客户端,用于发现 kube-apiserver 所支持的资源组、资源版本、资源信息(即Group、Versions、Resources)</p>
</li>
</ul>
<p> 以上4种客户端:RESTClient 、DynamicClient 、ClientSet 、DiscoveryClient 都可以通过kubeconfig配置信息连接到指定的 kubernetes api server。</p>
<h4 id="3kubeconfig配置管理">3、kubeconfig配置管理</h4>
<p>kubeconfig 用于管理访问 kube-apiserver 的配置信息,k8s的其他组件都使用 kubeconfig 配置信息来连接 kube-apiserver组件,例如:kubectl 访问 kube-apiserver 时,会默认加载 kubeconfig 配置信息。</p>
<p> kubeconfig 中存储了集群、用户、命名空间和身份验证等信息,在默认情况下,kubeconfig 存在在$HOME/.kube/config路径下。配置信息如下:</p>
<pre><code class="language-yaml">apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1URXhOakE0TXpJeU5Gb1hEVE14TVRFeE5EQTRNekl5TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS0krClAyV3A1RDlTSk1NZllTNU1QMnFsQWx0MTh3OVptSkhjUlRxQ3R5Mms1NVloaVNrTzBXYzFaVEd2ZHZId0FqWjMKWnRFUVRwUFp0bXBaL3BUUEtNUkx5U1ZObU9PMjZhb2d0dTZJclpKbzMrQzVhTk9zQzVtTUZIUDRCcGE2aUk4Mwp0VWlORVRCRjhBbTlGdW9SVGhkZlVTelVNdUF6ZlJ5ZXU4L0NKcW4rVXJ5UjRhSE9ncHJxNmptNXZubDVqbUxoCnVMQjN5VTRMRVJUZDBmRWJIa09uRnR3cG42OEpOVnZLck1vajc3aHJ3RGdaTEVQQ0dQU0dxNEJ5dkRKQjhIWEoKb3JhUFBJVWNiNDlFcmx2TzJHOXFnODZDUWV4NEpBWEpSTldjcjlsblJtaEdoTkJwc1VXZ3VFRm1iMUxINjREdwpsMWVqbENURXJqblNqNjRZLzJzQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFJbDhJaStKWW1YOWdlVjVxaDUvWStIRFRhbjAKR2VldldQamtvdnFza0dReW1PT0hIak4rRHdPK2dZemVodGNUSUtPWVQvczhjOFlEUm1GTng4ZUI4RWVTRkJNaQpBWnMzaUE4b0NFTkdQUGF3QWdDbEFBTGp0SmNLOXR4RHdGdm5WcUsrUGk3bW52cmJtUVhxQzJRS1JRcEQ1VnlpCjZFeWRQdGlFZWRvSm93ZC9rdHh2UVlDSitGZFRBZHl3VVlxQzk1UDBLczhUanpEUDNaRVZnYkJER05kT0hIWVcKUXNOeG5DaDB0ZlpEbkl6ZCtCZ25SSDNLL1c0bWVCOXpYTzFrWVNLK2NGbFduWG40OUo1QmlEMkI3ZHk3eWt1Kwo0MUdvdGVrSjc3NXIySFlyR2dmaG9mYWtCenZnZEV2U1J0Y243OVkwTkZ6dmhUeFZIRWp5VExqTEY4TT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://127.0.0.1:16443
name: cluster-10.9.244.32
contexts:
- context:
cluster: cluster-10.9.244.32
user: kubernetes-admin
name: kubernetes-admin@cluster-10.9.244.32
current-context: kubernetes-admin@cluster-10.9.244.32
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQ3p5OXR6SzhhclV3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRFeE1UWXdPRE15TWpSYUZ3MHlNakV4TVRZd09ETXlNalphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXZ2UnhDaHVzblo1MU1zYU0KN01FZkVaUzdFb3ZlZUZTRTJ2MVZtOWt2U3dpVzVUclhqOG1LdWFjVWszZVdBMDdmVHdjMkJ3ZjNjVEFNazAxTQpHbU41bzEvcFdkam40TjdsdmxkeEZKclVVVkZGK3k4SUxySkVVdUhWdEtLUHZkM29jakxBTktwbGRCcWtrTTZVCmlKL0JKa3lvOXpPUWpBN0dUVmtBdTlQaFNDRktQUVhibjZHUUIrZW1LN1cxTFRkM1diQ2tacGE2NjVpUWhLRzMKKzhRMXJlMHFzcm9kQzNnV0Vna0N5TjNRUzIwRGowa0drMzJvWkp3Zkx5cUJOaUFNVzZ2azRpVjJqaEFTWDRYSwpEZ3pQVUNOUDFSSFkxZitkTEtBNzhoNXMremhTUi93VkxXajVPUlIvZ1hhcFRtZG80dy84NEpKbExwTWVScXJGCjQ0Y1Rhd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKNWZQMHVScWJhbkJLTnl5eVErVzVmaExQejYzK0hEVGNiTgptUTlKdFlNUk1MN3hkWkxRVXM1T1N1cWo4QWNiMWNXSXFNNkRhUmJVc2dlTFh6SEg3WDJjUzF5T1gvSFJ5L0ZPClBKdFcwRlhkbVhWWE1PbU5JWldwVWRmT08vYkx2eURhY2N4RkZ6alFkVksvdmg5Q2VqNkYvWnpVWXdkVlQ1eXQKenVYZ2llV2VxTFpzT1hZMlhyWmN5Vzg4Ky9VYUVaczdYR01xVEhSYjlUQi9iTTlxL0FnWHRscThlZEZvS1JkZwpYd2hFY0RzOWZuS2RwSG13QlVkV1lDcDFNNmVzamtObk9mMVU4Rk9OeXdUNm5xVG52VkgzQ1UzTkQxMSs5Y2IyCm1qSmVXK0QrRUd1VXZTR2tSamdLY1VYS1NCWXhwVWFoOWFWWGN3RjNnakhxa1RaaHZ0VT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBdnZSeENodXNuWjUxTXNhTTdNRWZFWlM3RW92ZWVGU0UydjFWbTlrdlN3aVc1VHJYCmo4bUt1YWNVazNlV0EwN2ZUd2MyQndmM2NUQU1rMDFNR21ONW8xL3BXZGpuNE43bHZsZHhGSnJVVVZGRit5OEkKTHJKRVV1SFZ0S0tQdmQzb2NqTEFOS3BsZEJxa2tNNlVpSi9CSmt5bzl6T1FqQTdHVFZrQXU5UGhTQ0ZLUFFYYgpuNkdRQitlbUs3VzFMVGQzV2JDa1pwYTY2NWlRaEtHMys4UTFyZTBxc3JvZEMzZ1dFZ2tDeU4zUVMyMERqMGtHCmszMm9aSndmTHlxQk5pQU1XNnZrNGlWMmpoQVNYNFhLRGd6UFVDTlAxUkhZMWYrZExLQTc4aDVzK3poU1Ivd1YKTFdqNU9SUi9nWGFwVG1kbzR3Lzg0SkpsTHBNZVJxckY0NGNUYXdJREFRQUJBb0lCQUdKYURwclJOREFldkdpQgpvWFlUNWdldEhrbG9KeGE5R1l5ZGJPbVBqRzlPSmtJODgyZ0l1MTN4ODRRYzFQUXhQSTA4dnBRU2cxMFdEWFFWCkhQeCtmZGtxL2txYmtKcmUwMkFkTTQ0VVRRVHhJbVZFalNkWUJCN1lXTFRvQWJjZVE2b0YvNzlnZ0U2enBrMDcKU1greElNKzBMbGJjaFRmT0tFOFFaM05XcHpMNXBWTEh2eEFyYWNNMWg0K1d4NDZnNHJRN3JwS1BUa2VFa1loYwo3amE2TWl6UjEvZDFUNERqa2JGUnU3SVNSNVpvWithL0o2dGkzSStoc0lqaU0yeE5sQ0Y0MXVZa0lDSkhnMkZYCnlyZkYwZm1YS2c1T1oweWFHTUhTdUNpbE9UUUlnYndMN3RMMWR0bU5YaTBvTzdZbXF5MHFaSVdlV1BRVitJUWkKOXREdXFVa0NnWUVBOXg2TzJCaVBqdzAyUENYQ0xhcHZpVHNCeFRmNVFCbVpkZlEvNFJubGY1T3IwZ2ZmdmgzbApNUDBYYUZraWdaUW83NmJvZlFRd0VNZWdnRkFXNkhFSkVOQTd4Z2NsVlFxTHVST2pUTVNkRVUraUl1eXZ0VFZmClJZYTUxODdCTEFwWThnRHQzQjhjVlN6RGQvdlIrVmJ4MFNJVGdTbVFGSUdtdC9TWmdnMFp4cjhDZ1lFQXhkRXUKeXIwaUxHNWtyRHN3VmxVc3RsU2lHQmxBZEhOMld1eEFncmw5UTdSWEt0V3B0allqTnhMdVJoU1dLOEYzYjBlQwoyaUQxWTljMkgyNmJYelA1OEorTkZyMmNzYmJKdFNmWi9xcXE3Q3V0K2liUng1Q0IyQm1UZDVpWWhqWTNRUjQzCnlOWFhhR2dzUzFQQWt6Q1dVcmVuVHh6bzFBNzRnN05PZjhLVGFsVUNnWUFOaDNyQ2tmV3FHMHNRMS9CZGw2c3IKbEROd25MUGtzb0lZVnhyNE0vYkFtVkVhMnB1QlNSbTNLT1FUTG00Wk1nZGJ0NE9hOUpPOUYzRE9GWlJyZldURgpxdURhNHFGRW1xTXpxc09SL0dHdEJQTVhmbVhRUWUvSldxcnFDY1BCcVg5ZElIZmxTVDYvMndlSWxoelV6ZEhIClpWbzBCQmFEU09YYnhHUnpIa3grK1FLQmdDeXZOL2FzQ3BBbXo2N29IOThnbGwwSmVTUWdjQ0xlQWhvL3k4SzcKeThRRGRMMUVUblhPZk4zdjlNcjMwNFJHeTRmamkzZGlnb3Z2RFZiRVVXeUwvU1dScFBsQ0U2ZEJOd2NvM1dGZApoQWFkUjB0K2dWeW5FKzJRdVhNR2tVMmY2Wk5ZRkJuVjFEYk5jVlFDc3ptTWZDaHJPK3Z2QjlqL0dMd0hRUEF6Ckw4R1JBb0dCQVBVSnZ5NHlsRG1TdkJheFZrdGdXRjRYc096cytCR0sweFI0VEdZa0JNODhRTHFLTVU1RFZCV3MKdjVQQ2xFMVcxOHVJWkZMTzdGUXd5U1ZwZ0cwZ3NOcVBDRjdwVVZmRjg0VkFiWmxCdGJNSWdCcFRIMjU0M2FHegpQMGZNdnFEaU91bksxa0VaWDh4YkdMTHFXZjBBTGgwUkVmbDBTL3pmZ1RDUDBzTTZtKzdJCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
</code></pre>
<p>kubeconfig配置信息通常包含3个部分,分别介绍如下:</p>
<ul>
<li>clusters:定义kubernetes集群信息,例如kube-apiserver 的服务地址及集群的证书信息等。</li>
<li>users:定义kubernetes集群用户身份验证的客户端凭据,例如 client-certificate、client-key等信息。</li>
<li>contexts:定义kubernetes集群用户信息和命名空间等,用于将请求发送到指定的集群。</li>
</ul>
<p>client-go会读取 kubeconfig 配置信息并生成config对象,用于与kube-apiserver通讯,代码如下:</p>
<pre><code class="language-golang">config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
if err != nil {
panic(err.Error())
}
</code></pre>
<p>在上述代码中,clientcmd.BuildConfigFromFlags 函数会读取kubeconfig配置信息并实例化 rest.Config 对象。</p>
<h4 id="4restclient客户端">4、RESTClient客户端</h4>
<p>RESTClient是最基础的客户端,其他的客户端都是基于它实现的。RESTClient对HTTP Request 进行了封装,实现了Restful 风格的api。</p>
<p> 类似于kubectl命令,通过RESTClient列出所有运行pod资源对象,代码如下:</p>
<pre><code class="language-golang">package main
import (
"flag"
"fmt"
"context"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
"k8s.io/client-go/kubernetes/scheme"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
config.APIPath = "api"
config.GroupVersion = &corev1.SchemeGroupVersion
config.NegotiatedSerializer = scheme.Codecs
restClient, err := rest.RESTClientFor(config)
if err != nil {
panic(err.Error())
}
result := &corev1.PodList{}
err = restClient.Get().
Namespace("whalebase").
Resource("pods").
VersionedParams(&metav1.ListOptions{Limit: 500}, scheme.ParameterCodec).
Do(context.TODO()).
Into(result)
for _, d := range result.Items {
fmt.Printf("namespace:%v \t name:%v \t status:%+v\n", d.Namespace, d.Name, d.Status.Phase)
}
}
</code></pre>
<p>运行以上代码,列出 whalebase 命名空间下所有 pod 资源对象的相关信息。首先加载 kubeconfig 配置信息,并设置 config.APIPath 请求的 HTTP 路径。然后设置 config.GroupVersion 请求的资源组/资源版本。最后设置 config.NegotiatedSerializer 数据的编解码器。</p>
<p> rest.RESTClientFor 函数通过 kubeconfig 配置信息实例化 RESTClient 对象,RESTClient 对象构建 HTTP 请求参数,例如GET函数设置请求方法为get操作,它还支持post、put、delete、patch 等请求方法。Namespace 函数设置命名空间。 Resource 函数设置请求的资源名称。VersionedParams 函数将一些查询选项(如limit、TimeoutSeconds等)添加到请求参数中。通过Do函数执行该请求,并将 kube-apiserver 返回的结果(Result对象)解析到 corev1.PodList 对象中。最终格式化输出结果。</p>
<h4 id="5clientset-客户端">5、ClientSet 客户端</h4>
<p>RESTClient 最基础的客户端,使用时需要指定 Resource 和 Version 等信息,编写代码时需要提前知道 Resource 所在的 Group 和对应的 Version 信息。相比 RESTClient ,ClientSet 使用起来更加便捷,一般情况下,开发者对kubernetes进行二次开发时通常使用 ClientSet。</p>
<p>ClientSet 在 RESTClient 的基础上封装了对 Resource 和 Version 的管理方法。每一个 Resource 可以理解为一个客户端, 而ClientSet 则是多个客户端的集合,每一个 Resource 和 Version 都以函数的形式暴露给开发者。例如 ClientSet 提供的 RbacV1、CoreV1、NetworkingV1 等接口函数,多个 ClientSet 多资源集合如下图:<br>
<img src="https://img2022.cnblogs.com/blog/2828750/202204/2828750-20220404214222353-1098186604.png"><br>
与 api-server 交互,示例代码如下:</p>
<pre><code class="language-golang">package main
import (
"context"
"flag"
"fmt"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
// 获取mysql的pod
namespace := "whalebase"
pod := "mysql-0"
mysqlPod, err := clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod, metav1.GetOptions{})
if errors.IsNotFound(err) {
fmt.Printf("Pod %s in namespace %s not found\n", pod, namespace)
} else if statusError, isStatus := err.(*errors.StatusError); isStatus {
fmt.Printf("Error getting pod %s in namespace %s: %v\n",
pod, namespace, statusError.ErrStatus.Message)
} else if err != nil {
panic(err.Error())
} else {
fmt.Printf("Found pod %s in namespace %s\n", pod, namespace)
bytes, _ := json.Marshal(mysqlPod)
fmt.Println("pod信息:",string(bytes))
}
fmt.Println("--------------------------------")
// 获取mysql的StatefulSets
sts, _ := clientset.AppsV1().StatefulSets(namespace).Get(context.TODO(), "mysql", metav1.GetOptions{})
bytes, _ := json.Marshal(sts)
fmt.Println("sts信息:",string(bytes))
fmt.Println("--------------------------------")
//创建pod
var nginxPod *v1.Pod = &v1.Pod {
TypeMeta: metav1.TypeMeta{Kind:"Pod",APIVersion:"v1"},
ObjectMeta: metav1.ObjectMeta{Name:"nginx-pod"},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "nginx",
Image: "nginx:1.8",
},
},
},
}
_, err = clientset.CoreV1().Pods("default").Create(context.TODO(), nginxPod, metav1.CreateOptions{})
if err != nil {
fmt.Println(err)
}
}
</code></pre>
<h4 id="6dynamicclient-客户端">6、DynamicClient 客户端</h4>
<p>DynamicClient 是一种动态客户端,它可以与任意 kubernetes 资源进行 RESTful 操作,包括 CRD 自定义资源。DynamicClient 与 ClientSet 操作类似,同样封装了RESTClient,同样提供了Create、Update、Get、List、Watch、Patch 等方法。</p>
<p> DynamicClient 与 ClientSet 最大的不同之处是,ClientSet 仅能访问 kubernetes 自带的资源,不能访问 CRD 自定义资源。 ClientSet 需要预先 实现每种 Resource、Version 的操作,其内部都是结构化数据(即已知数据结构)。而 DynamicClient 内部实现了 Unstructured,用于处理非结构化数据结构(即无法预先提前预知数据结构),这也是 DynamicClient 能够处理CRD自定义资源的关键。</p>
<p> DynamicClient 的处理过程将 Resource (例如PodList)转换成 Unstructured 结构类型, kubernetes 的所有 Resource 都可以转化成该结构类型。处理完成后,再将 Unstructured 转换成 PodList 。整个过程类似于Go语言的interface{}断言转换过程,另外, Unstructured 结构类型是通过 mapinterface{} 转换的。</p>
<pre><code class="language-golang">package main
import (
"context"
"flag"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/clientcmd"
"path/filepath"
"k8s.io/client-go/util/homedir"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
panic(err.Error())
}
gvr := schema.GroupVersionResource{Version: "v1",Resource: "pods"}
unstructuredList, err := dynamicClient.Resource(gvr).Namespace("whalebase").List(context.TODO(), metav1.ListOptions{Limit: 500})
if err != nil {
panic(err.Error())
}
podList := &corev1.PodList{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredList.UnstructuredContent(),podList)
if err != nil {
panic(err.Error())
}
for _, d := range podList.Items {
fmt.Printf("namespace:%v \t name:%v \t status:%+v\n", d.Namespace, d.Name, d.Status.Phase)
}
}
</code></pre>
<p>dynamicClient.Resource(gvr) 函数用于设置请求的资源组、资源版本、资源名称。Namespace 函数用于设置请求的命名空间。List 函数用于获取 pod 列表。得到的pod列表为 unstructured.UnstructuredList 指针类型,然后通过 runtime.DefaultUnstructuredConverter 函数将 unstructured.UnstructuredList 转换成 PodList 类型。</p>
<h4 id="7discoveryclient客户端">7、DiscoveryClient客户端</h4>
<p>DiscoveryClient 是发现客户端,它主要用于发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息,开发者在开发过程中很难记住所有的信息,此时可以通过 DiscoveryClient 查看所支持的资源组、资源版本、资源信息。</p>
<p> kubectl api-versions 和 api-resources 命令输出也是通过 DiscoveryClient 实现的。另外, DiscoveryClient 同样在 RESTClient 的基础上进行了封装。</p>
<p> DiscoveryClient 除了可以发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息,还可以将这些信息存储到本地,用于本地缓存(Cache),以减轻对 Kubernetes API Server 访问的压力。在运行 Kubernetes 组件的机器删,缓存信息默认存储于~/.kube/cache 和 ~/.kube/http-cache 下。</p>
<p> 类似于kubectl命令,通过 DiscoveryClient 列出 Kubernetes API Server 所支持的资源组、资源版本、资源信息,代码如下:</p>
<pre><code class="language-golang">package main
import (
"flag"
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
panic(err.Error())
}
_, APIResourceList, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
panic(err.Error())
}
for _, list := range APIResourceList{
gv, err := schema.ParseGroupVersion(list.GroupVersion)
if err != nil {
panic(err.Error())
}
for _, resource := range list.APIResources {
fmt.Printf("name: %v, group: %v, version: %v\n", resource.Name, gv.Group, gv.Version)
}
}
}
</code></pre>
<p>运行以上代码,列出 Kubernetes API Server 所支持的资源组、资源版本、资源信息。首先加载 kubeconfig 配置信息,discovery.NewDiscoveryClientForConfig 通过 kubeconfig 配置信息实例化 discoveryclient 对象,该对象是用于发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息的客户端。</p>
<p> discoveryClient.ServerGroupsAndResources 函数会返回 Kubernetes API Server 所支持的 资源组、资源版本、资源信息(即APIResourceList),通过遍历 APIResourceList 输出信息。</p><br><br>
来源:https://www.cnblogs.com/liweiboy/p/16100627.html
頁:
[1]