文章目录

  • 1. 简介
  • 2. Setup
  • 3. 连接 API Server
  • 4. 创建一个clientset
  • 5. 获取集群的PVC列表
  • 6. 监听集群中pvc
    • 6.1 启动监听功能
    • 6.2 循环事件
    • 6.3 处理ADDED事件
    • 6.4 处理DELETED事件
    • 6.5 运行程序
  • 7. 总结

参考链接:
kubernetes 的Go Client项目(client-go)


1. 简介

go client是k8s client中最古老的一个,具有很多特性。Client-go 没有使用Swagger生成器,它使用的是源于k8s项目中的源代码生成工具,这个工具的目的是要生成k8s风格的对象和序列化程序。

该项目是一组包的集合,该包能够满足从REST风格的原语到复杂client的不同的编程需求。

RESTClient是一个基础包,它使用api-machinery库中的类型作为一组REST原语提供对API的访问。作为对RESTClient之上的抽象,_clientset_将是你创建k8s client工具的起点。它暴露了公开化的API资源及其对应的序列化。

注意:在 client-go中还包含了如discovery, dynamic, 和 scale这样的包,虽然本次不介绍这些包,但是了解它们的能力还是很重要的。

2. Setup

client-go支持Godep和dep作为vendor的管理程序,我觉得dep便于使用所以继续使用dep。例如,以下是client-go v6.0和k8s API v1.9所需最低限度的Gopkg.toml。

[[constraint]]name = "k8s.io/api"version = "kubernetes-1.9.0"
[[constraint]]name = "k8s.io/apimachinery"version = "kubernetes-1.9.0"
[[constraint]]name = "k8s.io/client-go"version = "6.0.0"

运行dep ensure确保剩下的工作。

3. 连接 API Server

我们Go client的第一步就是建立一个与API Server的连接。为了做到这一点,我们要使用实体包中的clientcmd,如下代码所示:

import (
..."k8s.io/client-go/tools/clientcmd"
)
func main() {kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config",)config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {log.Fatal(err)}
...
}

_Client-go_通过提供实体功能来从不同的上下文中获取你的配置,从而使之成为一个不重要的任务。

你能从kubeconfig文件启动配置来连接API server。当你的代码运行在集群之外的时候这是一个理想的方案。clientcmd.BuildConfigFromFlags("", configFile)

当你的代码运行在这个集群中的时候,你可以用上面的函数并且不使用任何参数,这个函数就会通过集群的信息去连接api server。

clientcmd.BuildConfigFromFlags("", "")

或者我们可以通过rest包来创建一个使用集群中的信息去配置启动的(译者注:k8s里所有的Pod都会以Volume的方式自动挂载k8s里面默认的ServiceAccount,所以会用默认的ServiceAccount的授权信息),如下:

import "k8s.io/client-go/rest"
...
rest.InClusterConfig()

4. 创建一个clientset

我们需要创建一个序列化的client为了让我们获取API对象。在kubernetes包中的Clientset类型定义,提供了去访问公开的API对象的序列化client,如下:

type Clientset struct {*authenticationv1beta1.AuthenticationV1beta1Client*authorizationv1.AuthorizationV1Client
...*corev1.CoreV1Client
}

一旦我们有正确的配置连接,我们就能使用这个配置去初始化一个clientset,如下:

func main() {config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)...clientset, err := kubernetes.NewForConfig(config)if err != nil {log.Fatal(err)}
}

对于我们的例子,我们使用的是v1的API对象。下一步,我们要使用clientset通过CoreV1()去访问核心api资源,如下:

func main() {...clientset, err := kubernetes.NewForConfig(config)if err != nil {log.Fatal(err)}api := clientset.CoreV1()
}

你能在这里看到可以获得clientsets。

5. 获取集群的PVC列表

我们对clientset执行的最基本操作之一获取存储的API对象的列表。在我们的例子中,我们将要拿到一个namespace下面的pvc列表,如下:

import (
...metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {var ns, label, field stringflag.StringVar(&ns, "namespace", "", "namespace")flag.StringVar(&label, "l", "", "Label selector")flag.StringVar(&field, "f", "", "Field selector")
...api := clientset.CoreV1()// setup list optionslistOptions := metav1.ListOptions{LabelSelector: label, FieldSelector: field,}pvcs, err := api.PersistentVolumeClaims(ns).List(listOptions)if err != nil {log.Fatal(err)}printPVCs(pvcs)
...
}

在上面的代码中,我们使用ListOptions指定 labelfield selectors (还有namespace)来缩小pvc列表的范围,这个结果的返回类型是v1.PeristentVolumeClaimList。下面的这个代码展示了我们如何去遍历和打印从api server中获取的pvc列表。

func printPVCs(pvcs *v1.PersistentVolumeClaimList) {template := "%-32s%-8s%-8s\n"fmt.Printf(template, "NAME", "STATUS", "CAPACITY")for _, pvc := range pvcs.Items {quant := pvc.Spec.Resources.Requests[v1.ResourceStorage]fmt.Printf(template, pvc.Name, string(pvc.Status.Phase), quant.String())}
}

6. 监听集群中pvc

k8s的Go client框架支持为指定的API对象在其生命周期事件中监听集群的能力,包括创建,更新,删除一个指定对象时候触发的CREATED,MODIFIED,DELETED事件。对于我们的命令行工具,我们将要监听在集群中已经声明的PVC的总量。

对于某一个namespace,当pvc的容量到达了某一个阈值(比如说200Gi),我们将会采取某个动作。为了简单起见,我们将要在屏幕上打印个通知。但是在更复杂的实现中,可以使用相同的办法触发一个自动操作。

6.1 启动监听功能

现在让我们为PersistentVolumeClaim这个资源通过Watch去创建一个监听器。然后这个监听器通过ResultChan从go的channel中访问事件通知。

func main() {...api := clientset.CoreV1()listOptions := metav1.ListOptions{LabelSelector: label, FieldSelector: field,}watcher, err :=api.PersistentVolumeClaims(ns).Watch(listOptions)if err != nil {log.Fatal(err)}ch := watcher.ResultChan()
...
}

6.2 循环事件

接下来我们将要处理资源事件。但是在我们处理事件之前,我们先声明resource.Quantity类型的的两个变量为maxClaimsQuanttotalClaimQuant来分别表示我们的申请资源阈值(译者注:代表某个ns下集群中运行的PVC申请的上限)和运行总数。

import("k8s.io/apimachinery/pkg/api/resource"...
)
func main() {var maxClaims stringflag.StringVar(&maxClaims, "max-claims", "200Gi", "Maximum total claims to watch")var totalClaimedQuant resource.QuantitymaxClaimedQuant := resource.MustParse(maxClaims)
...ch := watcher.ResultChan()for event := range ch {pvc, ok := event.Object.(*v1.PersistentVolumeClaim)if !ok {log.Fatal("unexpected type")}...}
}

在上面的for-range循环中,watcherchannel用于处理来自服务器传入的通知。每个事件赋值给变量event,并且event.Object的类型被声明为PersistentVolumeClaim类型,所以我们能从中提取出来。

6.3 处理ADDED事件

当一个新的PVC创建的时候,event.Type的值被设置为watch.Added。然后我们用下面的代码去获取新增的声明的容量(quant),将其添加到正在运行的总容量中(totalClaimedQuant)。最后我们去检查是否当前的容量总值大于当初设定的最大值(maxClaimedQuant),如果大于的话我们就触发一个事件。

import("k8s.io/apimachinery/pkg/watch"...
)
func main() {...for event := range ch {pvc, ok := event.Object.(*v1.PersistentVolumeClaim)if !ok {log.Fatal("unexpected type")}quant := pvc.Spec.Resources.Requests[v1.ResourceStorage]switch event.Type {case watch.Added:totalClaimedQuant.Add(quant)log.Printf("PVC %s added, claim size %s\n", pvc.Name, quant.String())if totalClaimedQuant.Cmp(maxClaimedQuant) == 1 {log.Printf("\nClaim overage reached: max %s at %s",maxClaimedQuant.String(),totalClaimedQuant.String())// trigger actionlog.Println("*** Taking action ***")}}...}}
}

6.4 处理DELETED事件

代码也会在PVC被删除的时候做出反应,它执行相反的逻辑以及把被删除的这个PVC申请的容量在正在运行的容量的总值里面减去。

func main() {...for event := range ch {...switch event.Type {case watch.Deleted:quant := pvc.Spec.Resources.Requests[v1.ResourceStorage]totalClaimedQuant.Sub(quant)log.Printf("PVC %s removed, size %s\n", pvc.Name, quant.String())if totalClaimedQuant.Cmp(maxClaimedQuant) <= 0 {log.Printf("Claim usage normal: max %s at %s",maxClaimedQuant.String(),totalClaimedQuant.String(),)// trigger actionlog.Println("*** Taking action ***")}}...}
}

6.5 运行程序

当程序在一个运行中的集群被执行的时候,首先会列出PVC的列表。然后开始监听集群中新的PersistentVolumeClaim事件。

$> ./pvcwatch
Using kubeconfig:  /Users/vladimir/.kube/config
--- PVCs ----
NAME                            STATUS  CAPACITY
my-redis-redis                  Bound   50Gi
my-redis2-redis                 Bound   100Gi
-----------------------------
Total capacity claimed: 150Gi
-----------------------------
--- PVC Watch (max claims 200Gi) ----
2018/02/13 21:55:03 PVC my-redis2-redis added, claim size 100Gi
2018/02/13 21:55:03
At 50.0% claim capcity (100Gi/200Gi)
2018/02/13 21:55:03 PVC my-redis-redis added, claim size 50Gi
2018/02/13 21:55:03
At 75.0% claim capcity (150Gi/200Gi)

下面让我们部署一个应用到集群中,这个应用会申请75Gi容量的存储。(例如,让我们通过helm去部署一个实例influxdb)。

helm install --name my-influx \
--set persistence.enabled=true,persistence.size=75Gi stable/influxdb

正如下面你看到的,我们的工具立刻反应出来有个新的声明以及一个警告因为当前的运行的声明总量已经大于我们设定的阈值。

--- PVC Watch (max claims 200Gi) ----
...
2018/02/13 21:55:03
At 75.0% claim capcity (150Gi/200Gi)
2018/02/13 22:01:29 PVC my-influx-influxdb added, claim size 75Gi
2018/02/13 22:01:29
Claim overage reached: max 200Gi at 225Gi
2018/02/13 22:01:29 *** Taking action ***
2018/02/13 22:01:29
At 112.5% claim capcity (225Gi/200Gi)

相反,从集群中删除一个PVC的时候,该工具会相应展示提示信息。

...
At 112.5% claim capcity (225Gi/200Gi)
2018/02/14 11:30:36 PVC my-redis2-redis removed, size 100Gi
2018/02/14 11:30:36 Claim usage normal: max 200Gi at 125Gi
2018/02/14 11:30:36 *** Taking action ***

7. 总结

这篇文章是进行的系列的一部分,使用Go语言的官方k8s客户端与API server进行交互。和以前一样,这个代码会逐步的去实现一个命令行工具去监听指定namespace下面的PVC的大小。这个代码实现了一个简单的监听列表去触发从服务器返回的资源事件。

kubernetes dev client-go 介绍相关推荐

  1. Kubernetes Resource QoS Classes介绍

    2019独角兽企业重金招聘Python工程师标准>>> Kubernetes Resource QoS Classes介绍 @(Kubernetes) 基本概念 Kubernetes ...

  2. Kubernetes的client-go库介绍

    官方示例:https://github.com/kubernetes/client-go/blob/master/examples/out-of-cluster-client-configuratio ...

  3. Kubernetes Python Client

    一.概述 Kubernetes官方维护的Python客户端client-python, 地址:https://github.com/kubernetes-client/python 安装模块 pip3 ...

  4. 学习笔记之-Kubernetes(K8S)介绍,集群环境搭建,Pod详解,Pod控制器详解,Service详解,数据存储,安全认证,DashBoard

    笔记来源于观看黑马程序员Kubernetes(K8S)教程 第一章 kubernetes介绍 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署 ...

  5. (转帖)开源容器集群管理系统Kubernetes架构及组件介绍

    最近在搞Docker还有她的管理工具,选型Kuberetes后,被她的术语和概念搞得晕头转向...看了一篇文章还不错,放到这里分享出来. 地址:http://www.linuxidc.com/Linu ...

  6. 开源容器集群管理系统Kubernetes架构及组件介绍

    Together we will ensure that Kubernetes is a strong and open container management framework for any ...

  7. Kubernetes入门一:介绍及环境准备

    Kubernetes学习笔记 本节主要介绍: Kubernetes的一些基础知识 Kubernetes集群搭建的相关操作内容 前言 1. 部署的演变过程: 整个部署的演变过程如图所示: 传统部署时代: ...

  8. Kubernetes系列之Helm介绍篇

    本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复[K8s实战]获取 介绍 Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来 ...

  9. linux主设备号作用是什么,linux 主设备号为1 以及/dev/null的介绍

    介绍个特殊的字符设备,主设备号为1的设备 1 char Memory devices 1 = /dev/mem Physical memory access 2 = /dev/kmem Kernel ...

最新文章

  1. .NET中的字符串你了解多少?
  2. 【摩天好课推荐】传统企业数字化转型的困惑、思考与实践
  3. SPSS的数据T检验
  4. junit 运行_运行,JUnit! 跑!!!
  5. 在Kaggle上免费使用GPU
  6. 【HTML/CSS】HTML5和CSS3的新特性
  7. Java HashMap元素取值
  8. 基因结构显示服务器,服务器固定结构 Server fixed structure
  9. 使用BetterZip结合自动操作工具和预设设置创建电影解压程序
  10. VueX模块化使用(超级实用)
  11. python 密度聚类_Python密度聚类算法-DBSCAN实践
  12. html代码实现简单的简历模板
  13. 什么是网络操作系统?网络操作系统具有那些基本功能?
  14. ps写php,ps怎么做立体效果文字
  15. Android 炫酷进度条
  16. QQ浏览器F12弹出新窗口问题
  17. AI研究者的方法论和工具箱|微软大牛独家「AI课程/资源/数据」
  18. Mysql学习之二. ken_len索引长度计算
  19. 如何在字符数组中存储空白字符
  20. Android图片海报制作-自定义文字排版控件组件

热门文章

  1. JS:变量提升与临时性死区TDZ
  2. 【图像分割】基于混洗Shuffled Complex Evolution实现图像分割附matlab代码
  3. oracle外币账套 初始化,Oracle EBS查找帐套本位币及币种间汇率转换的方法
  4. 聊一聊DDR3中的ODT(On-die termination)
  5. 计算机二级office高级应用和上机指导,2019年9月全国计算机二级教程:MS Office高级应用上机指导...
  6. 修改服务器bond网口mode4,双25GE网卡做bond4测试,其中一个网口没有流量一个网口可以打满的问题分享★★★...
  7. iOS 接入 招商 一网通的 各种坑
  8. 京瓷打印机1025默认管理员密码_FW316R默认管理员密码
  9. Linux网络——DNS域名解析服务
  10. 计算机基础2008版第7次作业,中医药大学-计算机基础2008版-1-7次作业.doc