背景

最近在看client-go源码最基础的部分,client-go的四类客户端,RestClient、ClientSet、DynamicClient、DiscoveryClient。其中RestClient是最基础的客户端,它对Http进行了封装,支持JSONprotobuf格式数据。其它三类客户端都是通过在REStClient基础上再次封装而得来。不过我对ClientSetDynamicClient傻傻分不清,虽然很多资料上说它两最大区别是,ClientSet能够使用预先生成的ApiApiServer进行通信;而DynamicClient更加强大,不仅仅能够调用预先生成的Api,还能够对一些CRD资源通过结构化嵌套类型跟ApiServer进行通信。意思大致明白前者能够调用Kubernetes本地资源类型,后者还可以调用一些自定资源,那么他们究竟是如何跟ApiServer进行交互、Pod的增删改查呢?

本文通过分析ClientSet代码和client-go客户端调用Kubernetes集群的方式来演示下整个交互过程。

准备工作

已经安装Kubernetes集群和配置本地IDE环境

  1. 根据kubernetes集群版本选择clone client-go到本地:https://github.com/kubernetes/client-go/tree/release-14.0

  2. 导入到IDE

  3. 运行 examples/create-update-delete-deployment/main.go 正常情况下会提示如下错误:

panic: CreateFile C:\Users\shj\.kube\config: The system cannot find the path specified.

错误信息提示很清楚,没有找到本地文件夹下的config文件,处理方式也很简单,只需要把你Kubernetes集群中$HOME/.kube/config复制到本地即可;仔细阅读代码可以发现,也可以通过自行配置客户端连接信息(生产环境慎用)。

4、运行main函数即可进行Pod增删改查操作。

client-go连接ApiServer进行Pod的增删改查

  1. 获取APIserver连接地址、认证配置等信息
var kubeconfig *string //获取当前用户home文件夹,并获取kubeconfig配置 if home := homedir.HomeDir(); home != "" {  kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") } else {//如果没有获取到,则需要自行配置kubeconfig  kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") } //把用户传递的命令行参数,解析为响应变量的值 flag.Parse() //加载kubeconfig中的apiserver地址、证书配置等信息 config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

debug信息

2、创建Clientset客户端

//NewForConfig为给定的配置创建一个新的Clientset(如下图所示包含所有的api-versions,这样做的目的是便于其它//资源类型对这个Pod进行管理和控制?)。clientset, err := kubernetes.NewForConfig(config)

debug信息

3、创建deployment客户端

//这个过程中会把包含RESTClient配置信息、命名空间信息赋值到deploymentsClient中,具体如下图信息。deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault) //构造deployment deployment := &appsv1.Deployment{  ObjectMeta: metav1.ObjectMeta{   Name: "demo-deployment",  },  Spec: appsv1.DeploymentSpec{   Replicas: int32Ptr(2),   Selector: &metav1.LabelSelector{    MatchLabels: map[string]string{     "app": "demo",    },   },   Template: apiv1.PodTemplateSpec{    ObjectMeta: metav1.ObjectMeta{     Labels: map[string]string{      "app": "demo",     },    },    Spec: apiv1.PodSpec{     Containers: []apiv1.Container{      {       Name:  "web",       Image: "nginx:1.12",       Ports: []apiv1.ContainerPort{        {         Name:          "http",         Protocol:      apiv1.ProtocolTCP,         ContainerPort: 80,        },       },      },     },    },   },  }, }

看到这里之后,ClientSet之所以只能处理预先声明的原生资源类型,是因为对象都是使用的内置元数据类型,不存在的自然没有办法使用了,这时我们在看下DynamicClient,部分代码如下所示,它使用unstructured.Unstructured表示来自 API Server的所有对象值。Unstructured类型是一个嵌套的map[string]inferface{} 值的集合来创建一个内部结构,通过这种方式,可以表示自定义资源CRD资源对象。具体示例,请参考:examples/dynamic-create-update-delete-deployment/main.go

deployment := &unstructured.Unstructured{  Object: map[string]interface{}{   "apiVersion": "apps/v1",   "kind":       "Deployment",   "metadata": map[string]interface{}{    "name": "demo-deployment",   },   "spec": map[string]interface{}{    "replicas": 2,    "selector": map[string]interface{}{     "matchLabels": map[string]interface{}{      "app": "demo",     },    },    "template": map[string]interface{}{     "metadata": map[string]interface{}{      "labels": map[string]interface{}{       "app": "demo",      },     },

     "spec": map[string]interface{}{      "containers": []map[string]interface{}{       {        "name":  "web",        "image": "nginx:1.12",        "ports": []map[string]interface{}{         {          "name":          "http",          "protocol":      "TCP",          "containerPort": 80,         },        },       },      },     },    },   },  }, }

4、发送Post请求

//发送Post请求到Kubernetes集群result, err := deploymentsClient.Create(deployment)

执行下kubectl get pod发现Kubernetes 集群中Pod已经创建。

5、更新Pod

  //尝试更新资源 retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {  //获取Get()返回的“result”  result, getErr := deploymentsClient.Get("demo-deployment", metav1.GetOptions{})  if getErr != nil {   panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))  }  //replica数量降低到1  result.Spec.Replicas = int32Ptr(1)  //修改nginx镜像  result.Spec.Template.Spec.Containers[0].Image = "nginx:1.13"  //更新(result)  _, updateErr := deploymentsClient.Update(result)  return updateErr })

更新模板信息

RetryOnConflict用于需要考虑更新冲突的情况下对资源进行更新,出现这种场景,大多因为存在其它客户端但或者代码同一时间内操作该资源对象。如果update函数返回冲突错误,RetryOnConflict将按指定策略等待一段时间退后,再次尝试更新。

6、查询操作

//发送http get请求获取pod列表list, err := deploymentsClient.List(metav1.ListOptions{})

其内部查询接口如下图所示:

其中c.client读取配置实例化RESTClient对象和ns,其中deployments这个对象是在这行deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)进行初始化; Get()通过Get请求,同样支持POST PUT DELETE PATCH;Resource设置请求的资源名称;VersionedParams 设置查询选项,例如:TimeoutSeconds;Do()执行请求,结果IntoResult

7、删除操作

//指定删除策略deletePolicy := metav1.DeletePropagationForeground//针对特定deployment进行删除操作 if err := deploymentsClient.Delete("demo-deployment", &metav1.DeleteOptions{  PropagationPolicy: &deletePolicy, });

Kubernetes控制器的删除有3种模式:

  • Foreground: 删除控制器之前,先删除控制器所管理的资源对象删除。
  • Background:删除控制器后,控制器所管理的资源对象由GC在后台进行删除。
  • Orphan:只删除控制器,不删除控制器所管理的资源对象(举个例子,比如你删除了deployment,那么对应的Pod不会被删除)。

8、观察Pod变化

[root@k8s-m1 ~]# kubectl get pod  --watchNAME                               READY   STATUS    RESTARTS   AGEdemo-deployment-5fc8ffdb68-8xdcx   1/1     Running   0          26sdemo-deployment-5fc8ffdb68-w555g   1/1     Running   0          26sdemo-deployment-5fc8ffdb68-w555g   1/1     Terminating   0          42sdemo-deployment-5cb6f65f77-tn5bn   0/1     Pending       0          0sdemo-deployment-5cb6f65f77-tn5bn   0/1     Pending       0          0sdemo-deployment-5cb6f65f77-tn5bn   0/1     ContainerCreating   0          0sdemo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          43sdemo-deployment-5cb6f65f77-tn5bn   1/1     Running             0          2sdemo-deployment-5fc8ffdb68-8xdcx   1/1     Terminating         0          44sdemo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          45sdemo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          48sdemo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          48sdemo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          51sdemo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          51sdemo-deployment-5cb6f65f77-tn5bn   1/1     Terminating         0          52sdemo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          53sdemo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          56sdemo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          56s

总结

本文主要通过在本地运行client-go/ClientSet客户端对Pod的增删改查,并解释了代码的执行过程。同时加深了对ClientSet客户端的理解。如有疑问,请关注公众号、加我微信,一起讨论; 希望能够帮助到大家,谢谢!

推荐


让我们一起揭开Etcd背后Raft算法的面纱

Kubernetes入门培训(内含PPT)

白话K8S核心组件概念


原创不易,随手关注或者”在看“,诚挚感谢!

element ui tree增删改查_clientgo连接K8s集群进行pod的增删改查相关推荐

  1. jenkins 连接k8s 集群

    参考 https://blog.csdn.net/myy1066883508/article/details/106235504 1.jenkins 添加kubernetes plugin 2.点击系 ...

  2. sqlplus远程连接k8s集群部署的oracle

    sqlplus system/oracle@//192.168.101.119:32333/EE.oracle.docker

  3. client-go入门之1:创建连接Kubernetes集群的客户端

    文章目录 简介 使用 简介 我们可以使用Dashboard或kubectl来访问k8s的API,也可以使用编程语言,如Go,Java,Python作为客户端来访问k8s.client-go是一个使用g ...

  4. jenkins连接外部k8s集群

    安装kubernetes插件 配置连接k8s集群的验证文件 查看k8s的 /root/.kube/config文件 获取/root/.kube/config中certificate-authority ...

  5. 在jenkins中连接kubernetes集群

    在jenkins中连接kubernetes集群 配置kubernetes plugin连接kubernetes集群 1.点击系统管理->系统设置-添加一个云,在下拉菜单中选择kubernets并 ...

  6. Element ui tree树形控件获取当前节点id和父节点id

    低版本Element ui tree树形控件获取当前节点id和父节点id的方法:点击查看 最新版本Element ui tree树形控件获取当前节点id和父节点id教程: 1.找到node_modul ...

  7. 修改element ui tree 搜索功能,实现分级搜索,关键字高亮

    element ui 里面的tree 自带的搜索功能是默认搜索的全部数据,有关键字的显示,没有的不显示 需求: 在element UI tree 原有功能不变的情况下新加 1)搜索 tree 时,如果 ...

  8. windows下eclipse远程连接hadoop集群开发mapreduce

    转载请注明出处,谢谢 2017-10-22 17:14:09 之前都是用python开发maprduce程序的,今天试了在windows下通过eclipse java开发,在开发前先搭建开发环境.在此 ...

  9. 连接redis集群报错: no reachable node in cluster

    今天在连接redis集群时遇到个问题,试了很多方案也没解决. 就是连接redis集群老是报错: no reachable node in cluster. 后来改了一些参数,就可以调通了. 废话不多说 ...

最新文章

  1. 前锋 php 杭州,前锋php培训
  2. 不经历风雨,怎么能见彩虹!马克斯与我的不解之缘!
  3. Spring源码分析之 lazy-init 实现原理
  4. MIGO相关的3个BADI增强点
  5. Spring MVC中的视图解析ViewResolver
  6. 【深入理解JVM】JVM字节码指令集
  7. dart系列之:集合使用实践
  8. 解决vue单页路由跳转后scrollTop的问题
  9. Python的安装路径
  10. LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
  11. ubuntu18.04 安装nvidia显卡驱动
  12. 计算机语言中索引什么意思,index在中是什么意思
  13. Biaofun讲解短视频营销对于2021年的大势所趋
  14. 电磁场与波 matlab,电磁场数值计算法与MATLAB实现
  15. 织梦dedecms模板安装过程的那点事儿
  16. NRF24L01的配置详解
  17. mysql jail_2.1.5 jail在生产环境下的注意事项
  18. 有关esp8266OTA升级的过程
  19. 卡巴斯基管理服务器地址更新
  20. ​​​​​​​24点游戏

热门文章

  1. go结构体初始化_go嵌套匿名结构体的初始化详解
  2. java指数函数_Java Math类方法学习记录
  3. 内存卡修复工具有哪些?这2种强烈推荐!
  4. [开源]java版QQ机器人集成小黄鸡功能
  5. python字节码文件后缀_如何生成Python的字节码文件
  6. smart phone flash tool ubuntu 18.04配置
  7. win7不在同一个网段怎么共享打印机
  8. 蔡高厅高等数学12-函数的极限与无穷小的关系
  9. 哈希洪水攻击是什么?
  10. oracle11 tns12505,TNS-12505 错误