首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >client-go连接K8s集群进行pod的增删改查

client-go连接K8s集群进行pod的增删改查

作者头像
用户5166556
发布2020-09-21 10:14:31
4K0
发布2020-09-21 10:14:31
举报

背景

最近在看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 spe
cified.

错误信息提示很清楚,没有找到本地文件夹下的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  --watch
NAME                               READY   STATUS    RESTARTS   AGE
demo-deployment-5fc8ffdb68-8xdcx   1/1     Running   0          26s
demo-deployment-5fc8ffdb68-w555g   1/1     Running   0          26s
demo-deployment-5fc8ffdb68-w555g   1/1     Terminating   0          42s
demo-deployment-5cb6f65f77-tn5bn   0/1     Pending       0          0s
demo-deployment-5cb6f65f77-tn5bn   0/1     Pending       0          0s
demo-deployment-5cb6f65f77-tn5bn   0/1     ContainerCreating   0          0s
demo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          43s
demo-deployment-5cb6f65f77-tn5bn   1/1     Running             0          2s
demo-deployment-5fc8ffdb68-8xdcx   1/1     Terminating         0          44s
demo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          45s
demo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          48s
demo-deployment-5fc8ffdb68-8xdcx   0/1     Terminating         0          48s
demo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          51s
demo-deployment-5fc8ffdb68-w555g   0/1     Terminating         0          51s
demo-deployment-5cb6f65f77-tn5bn   1/1     Terminating         0          52s
demo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          53s
demo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          56s
demo-deployment-5cb6f65f77-tn5bn   0/1     Terminating         0          56s

总结

本文主要通过在本地运行client-go/ClientSet客户端对Pod的增删改查,并解释了代码的执行过程。同时加深了对ClientSet客户端的理解。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 准备工作
  • client-go连接ApiServer进行Pod的增删改查
  • 总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档