侵权投诉

如何使用kubernetes client-go实践一个简单的与K8s交互过程

Linux爱好者 2021-02-02 11:16 次阅读

【导读】Kubernetes项目使用Go语言编写,对Go api原生支持非常便捷。本篇文章介绍了如何使用kubernetes client-go实践一个简单的与K8s交互过程。

kubernetes 的Go Client项目(client-go)

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

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

d4dd48de-61ff-11eb-8b86-12bb97331649.jpg

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

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

一个简单的k8s client 工具

让我们再次回顾我们将要构建的工具,来说明go client的用法。pvcwatch是一个简单的命令行工具,它可以监听集群中声明的PVC容量。当总数到达一个阈值的时候,他会采取一个action(在这个例子中是在屏幕上通知显示)

d541877c-61ff-11eb-8b86-12bb97331649.jpg

你能在github上找到完整的例子

这个例子是为了展示k8s的go client的以下几个方面:- 如何去连接 - 资源列表的检索和遍历 - 对象监听

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确保剩下的工作。

连接 API Server

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

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

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

从config文件

正如上面的例子所做的那样,你能从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()

创建一个clientset

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

typeClientsetstruct{
*authenticationv1beta1.AuthenticationV1beta1Client
*authorizationv1.AuthorizationV1Client
...
*corev1.CoreV1Client
}

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

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

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

funcmain(){
...
clientset,err:=kubernetes.NewForConfig(config)
iferr!=nil{
log.Fatal(err)
}
api:=clientset.CoreV1()
}

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

获取集群的PVC列表

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

import(
...
metav1"k8s.io/apimachinery/pkg/apis/meta/v1"
)
funcmain(){
varns,label,fieldstring
flag.StringVar(&ns,"namespace","","namespace")
flag.StringVar(&label,"l","","Labelselector")
flag.StringVar(&field,"f","","Fieldselector")
...
api:=clientset.CoreV1()
//setuplistoptions
listOptions:=metav1.ListOptions{
LabelSelector:label,
FieldSelector:field,
}
pvcs,err:=api.PersistentVolumeClaims(ns).List(listOptions)
iferr!=nil{
log.Fatal(err)
}
printPVCs(pvcs)
...
}

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

funcprintPVCs(pvcs*v1.PersistentVolumeClaimList){
template:="%-32s%-8s%-8s
"
fmt.Printf(template,"NAME","STATUS","CAPACITY")
for_,pvc:=rangepvcs.Items{
quant:=pvc.Spec.Resources.Requests[v1.ResourceStorage]
fmt.Printf(
template,
pvc.Name,
string(pvc.Status.Phase),
quant.String())
}
}

监听集群中pvc

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

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

启动监听功能

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

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

循环事件

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

import(
"k8s.io/apimachinery/pkg/api/resource"
...
)
funcmain(){
varmaxClaimsstring
flag.StringVar(&maxClaims,"max-claims","200Gi",
"Maximumtotalclaimstowatch")
vartotalClaimedQuantresource.Quantity
maxClaimedQuant:=resource.MustParse(maxClaims)
...
ch:=watcher.ResultChan()
forevent:=rangech{
pvc,ok:=event.Object.(*v1.PersistentVolumeClaim)
if!ok{
log.Fatal("unexpectedtype")
}
...
}
}

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

处理ADDED事件

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

import(
"k8s.io/apimachinery/pkg/watch"
...
)
funcmain(){
...
forevent:=rangech{
pvc,ok:=event.Object.(*v1.PersistentVolumeClaim)
if!ok{
log.Fatal("unexpectedtype")
}
quant:=pvc.Spec.Resources.Requests[v1.ResourceStorage]
switchevent.Type{
casewatch.Added:
totalClaimedQuant.Add(quant)
log.Printf("PVC%sadded,claimsize%s
",
pvc.Name,quant.String())
iftotalClaimedQuant.Cmp(maxClaimedQuant)==1{
log.Printf(
"
Claimoveragereached:max%sat%s",
maxClaimedQuant.String(),
totalClaimedQuant.String())
//triggeraction
log.Println("***Takingaction***")
}
}
...
}
}
}

处理DELETED事件

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

funcmain(){
...
forevent:=rangech{
...
switchevent.Type{
casewatch.Deleted:
quant:=pvc.Spec.Resources.Requests[v1.ResourceStorage]
totalClaimedQuant.Sub(quant)
log.Printf("PVC%sremoved,size%s
",
pvc.Name,quant.String())
iftotalClaimedQuant.Cmp(maxClaimedQuant)<= 0{
log.Printf("Claimusagenormal:max%sat%s",
maxClaimedQuant.String(),
totalClaimedQuant.String(),
)
//triggeraction
log.Println("***Takingaction***")
}
}
...
}
}

运行程序

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

$>./pvcwatch
Usingkubeconfig:/Users/vladimir/.kube/config
---PVCs----
NAMESTATUSCAPACITY
my-redis-redisBound50Gi
my-redis2-redisBound100Gi
-----------------------------
Totalcapacityclaimed:150Gi
-----------------------------
---PVCWatch(maxclaims200Gi)----
2018/02/1321:55:03PVCmy-redis2-redisadded,claimsize100Gi
2018/02/1321:55:03
At50.0%claimcapcity(100Gi/200Gi)
2018/02/1321:55:03PVCmy-redis-redisadded,claimsize50Gi
2018/02/1321:55:03
At75.0%claimcapcity(150Gi/200Gi)

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

helminstall--namemy-influx
--setpersistence.enabled=true,persistence.size=75Gistable/influxdb

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

---PVCWatch(maxclaims200Gi)----
...
2018/02/1321:55:03
At75.0%claimcapcity(150Gi/200Gi)
2018/02/1322:01:29PVCmy-influx-influxdbadded,claimsize75Gi
2018/02/1322:01:29
Claimoveragereached:max200Giat225Gi
2018/02/1322:01:29***Takingaction***
2018/02/1322:01:29
At112.5%claimcapcity(225Gi/200Gi)

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

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

总结

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

责任编辑:xj

原文标题:使用 Go 构建 Kubernetes 应用

文章出处:【微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。


原文标题:使用 Go 构建 Kubernetes 应用

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
分享:

评论

相关推荐

关于K8s最详细的解析

一个目标:容器操作;两地三中心;四层服务发现;五种Pod共享资源;六个CNI常用插件;七层负载均衡;....
的头像 Linux爱好者 发表于 04-08 13:55 246次 阅读
关于K8s最详细的解析

Kubernetes云平台的弹性伸缩实现方案

容器技术可为多个业务需求及其依赖组件提供独立的应用资源,在现实生产环境中由于容器中的业务需求不断变化....
发表于 03-11 16:32 56次 阅读
Kubernetes云平台的弹性伸缩实现方案

基于kubernetes托管虚机后续管理设计

基于kubernetes托管虚机有一些现成的方案,不过今天笔者要聊的是在虚机交付后,该如何实现后续的....
的头像 39度创意研究所 发表于 10-15 16:52 767次 阅读
基于kubernetes托管虚机后续管理设计

Kubernetes存储体系解析 浅谈Volume概念的由来

Volume、PV、PVC、StorageClass由来 先思考一个问题,为什么会引入Volume这....
的头像 39度创意研究所 发表于 10-15 16:45 786次 阅读
Kubernetes存储体系解析 浅谈Volume概念的由来

对于容器和Kubernetes,企业应该意识到哪些主要优势和挑战?

虽然容器已经诞生了10多年,但在过去几年中,容器的普及和采用率仍然不断增长。根据Gartner的调查....
的头像 如意 发表于 10-11 10:11 591次 阅读
对于容器和Kubernetes,企业应该意识到哪些主要优势和挑战?

首次部署 Kubernetes 应用程序需注意的“陷阱”

根据我的个人经验,大多数人似乎倾向于通过 Helm 或者手动方式将应用程序甩给 Kubernetes....
的头像 如意 发表于 10-08 14:43 575次 阅读
首次部署 Kubernetes 应用程序需注意的“陷阱”

Kubernetes在授权方面的挑战和防御措施

随着越来越多的组织将容器化应用程序转移到生产环境中,Kubernetes已经成为在私有云、公共云和混....
的头像 如意 发表于 10-08 14:23 439次 阅读
Kubernetes在授权方面的挑战和防御措施

Kubernetes架构和核心组件组成 Kubernetes节点“容器运行时”技术分析

Kubernetes 架构简介 Kubernetes架构如下图所示: 在这张系统架构图中,我们把服务....
的头像 39度创意研究所 发表于 09-25 15:53 865次 阅读
Kubernetes架构和核心组件组成 Kubernetes节点“容器运行时”技术分析

GlobalRouter模式架构和VPC-CNI 模式架构对比

创建集群时指定 GlobalRouter 模式,在需要使用 VPC-CNI 模式时为集群启用 VPC....
的头像 39度创意研究所 发表于 09-23 11:24 1309次 阅读
GlobalRouter模式架构和VPC-CNI 模式架构对比

云计算:Kubernetes架构的八个问题解答

Kubernetes的架构非常适合大规模的组织,但是对于中小组织来说,它可能会过于复杂。
的头像 如意 发表于 08-19 11:24 505次 阅读
云计算:Kubernetes架构的八个问题解答

云原生技术为什么能迅速崛起

云原生技术是关于如何构建应用程序,而不是在那里构建应用程序。这意味着全球企业可以在自己的数据中心以及....
的头像 汽车玩家 发表于 05-05 21:38 525次 阅读
云原生技术为什么能迅速崛起

在Windows 10上创建单节点的Kubernetes实施示例

Kubernetes使开发人员和系统管理员可以快速部署应用程序并将其扩展到其需求,而无需停机。Kub....
的头像 汽车玩家 发表于 05-05 21:01 698次 阅读
在Windows 10上创建单节点的Kubernetes实施示例

kubernetes v112二进制方式集群部署

kubernetes v112 二进制方式集群部署
发表于 05-05 16:30 28次 阅读
kubernetes v112二进制方式集群部署

如何解决Kubernetes中部署故障及技巧

Kubernetes资源配置中的错误,例如在部署(Deployment)和服务(Service)里。
发表于 05-04 07:12 217次 阅读
如何解决Kubernetes中部署故障及技巧

W5500运行Client例程时,为什么总在“关闭”和“初始化”状态?

我的W5500运行Client例程时,过去曾有发送成功的情况,具体细节记不清了。 现在运行do_tcp_client(),总在这两种情况下交替运...
发表于 04-17 23:18 1772次 阅读
W5500运行Client例程时,为什么总在“关闭”和“初始化”状态?

Kubernetes Dashboard实践学习

关于Kubernetes Dashboard的实践学习
发表于 04-10 14:09 185次 阅读
Kubernetes Dashboard实践学习

从零开始入门 | Kubernetes 中的服务发现与负载均衡

一、需求来源 为什么需要服务发现 在 K8s 集群里面会通过 pod 去部署应用,与传统的应用部署不....
发表于 03-18 11:45 196次 阅读
从零开始入门 | Kubernetes 中的服务发现与负载均衡

一小时快速搭建基于阿里云容器服务-Kubernetes的Web应用

如果您是一个Kubernetes的初学者,本文可以帮助你快速在云上搭建一个可实际使用的集群环境,并发....
发表于 03-09 17:07 435次 阅读
一小时快速搭建基于阿里云容器服务-Kubernetes的Web应用

从零开始入门 K8s | 调度器的调度流程和算法介绍

Kubernetes 作为当下最流行的容器自动化运维平台,以声明式实现了灵活的容器编排,本文以 v1....
发表于 03-09 17:04 274次 阅读
从零开始入门 K8s | 调度器的调度流程和算法介绍

Kubernetes资源配额的详细步骤

Kubernetes资源配额
发表于 03-06 10:18 66次 阅读
Kubernetes资源配额的详细步骤

预测2020年Kubernetes的五种趋势

随着 Kubernetes 的采用率不断增长,IT 领域在接下来的这一年里应当关注什么?The En....
的头像 汽车玩家 发表于 01-14 11:00 1987次 阅读
预测2020年Kubernetes的五种趋势

如何建立Kubernetes平台的?

工程师在启动工作负载时并没有统一的体验。无状态服务、有状态服务和批处理作业由完全不同的技术栈部署和管....
的头像 InfoQ 发表于 12-12 14:22 1758次 阅读
如何建立Kubernetes平台的?

请问有没有html例程可以加到我的C程序中去?

额,就像路由可以通过固定IP可以网页设置IP,网关一样. 我在STM32F4上通过ucosii+lwip写了一个client程序,请问大神,有没有...
发表于 11-05 22:04 143次 阅读
请问有没有html例程可以加到我的C程序中去?

kubernetes系统基本概念

一文带你看透kubernetes 容器编排系统
发表于 11-05 08:26 140次 阅读
kubernetes系统基本概念

Kubernetes平台中的日志收集方案

十、Kubernetes平台中日志收集
发表于 11-04 09:19 142次 阅读
Kubernetes平台中的日志收集方案

如何使用netconn进行编程最大接收字节数目?

小弟的程序是在原子的netconn webserver基础上进行修改的,但是配置文件没有修改. 当sever端和client端建立连接之后... server端...
发表于 10-23 20:54 119次 阅读
如何使用netconn进行编程最大接收字节数目?

网络通信实验无法重新连接该怎么解决?

板子用client端,电脑用server端,连接上后服务端再断开-重连,是正常的.但是当板子给电脑发送数据的过程中电脑服务端断开,此时...
发表于 10-20 22:27 276次 阅读
网络通信实验无法重新连接该怎么解决?

运行官方的TCP client例程,接收大量数据会卡死

如题,运行官方的TCP client 例程,为什么接收大量数据时会卡死?  并且很慢呢?  发送的数据 &nbs...
发表于 10-16 08:34 513次 阅读
运行官方的TCP client例程,接收大量数据会卡死

一文解读Kubernetes的重要性

如果你对容器化感兴趣并且关注过,可能会听过许多关于Kubernetes的事情。随着云开发的重点转移到....
的头像 电子发烧友网工程师 发表于 06-02 10:06 5188次 阅读
一文解读Kubernetes的重要性

【大神课堂】轻松加愉快的 Kubernetes 安装教程

k8s轻松加愉快安装教程!
的头像 马哥Linux运维 发表于 06-02 10:39 3292次 阅读
【大神课堂】轻松加愉快的 Kubernetes 安装教程

Google Kubernetes机器学习工具包Kubeflow发布0.1版

在Kubernetes日渐成为各大基础架构环境都要支持的公用工具时,其应用也逐渐在各个领域发酵,而该....
发表于 05-17 08:17 1298次 阅读
Google Kubernetes机器学习工具包Kubeflow发布0.1版

如何利用Splunk最新的Metrics Store来对Kubernetes的集群进行性能监控

Kubernetes已经成为容器编排的不二选择,你还不快学着点?注意这里deployment的--s....
的头像 马哥Linux运维 发表于 04-28 09:28 5772次 阅读
如何利用Splunk最新的Metrics Store来对Kubernetes的集群进行性能监控

Kubernetes网络部署方案

其实吧,Calico在Kubernetes网络方案用用的比Flanneld多,Calico懂得玩伸缩....
的头像 马哥Linux运维 发表于 03-21 16:18 5414次 阅读
Kubernetes网络部署方案

深入了解kubernetes

2014年出现的kubernetes(又叫k8s)更加炙手可热,我想大部分人仅仅是听说过,简单了解它....
的头像 阿铭linux 发表于 02-09 15:56 2544次 阅读
深入了解kubernetes

Kubernetes网络隔离NetworkPolicy实验

Kubernetes的一个重要特性就是要把不同node节点的pod(container)连接起来,无....
发表于 11-28 10:00 1719次 阅读
Kubernetes网络隔离NetworkPolicy实验

Kubernetes和Mesos集成的优势与原理

Kubernetes是一个docker集群管理工具,主要包含资源管理,部署运行,服务发现,扩容缩容等....
发表于 10-12 17:46 458次 阅读
Kubernetes和Mesos集成的优势与原理

Kubernetes API详解

摘要:Kubernetes是Google开源的容器集群管理系统。它构建Ddocker技术之上,为容器....
发表于 10-12 16:19 336次 阅读
Kubernetes API详解

CLient相关资料

CLient,好东西,喜欢的朋友可以下载来学习。
发表于 02-19 17:00 471次 阅读
CLient相关资料

Client Server模型数据实现技术

本论文主要讨论基于Client/Server 数据完整性约束及其如何实施企业业务规则,并以SQLSe....
发表于 09-18 10:42 465次 阅读
Client Server模型数据实现技术

基于Client/Server的网络建设方案的设计与实现

         本....
发表于 09-11 09:45 459次 阅读
基于Client/Server的网络建设方案的设计与实现