原文 :https://blog.csdn.net/rancherlabs/article/details/80134006

作者:RancherLabs

Rancher是全球领先的企业级开源容器管理平台, 为容器提供网络、存储、主机管理、负载均衡等全套的基础架构服务。同时Rancher也是全球唯一提供Kubernetes、Mesos和Swarm的企业级分发版和商业技术支持的容器管理平台。Rancher目前已有超过6000万次下载,以及4000+生产环境应用。

首席软件工程师Alena Prokharchyk受邀在2017年12月6-8日的CNCF主办的Kubernetes领域顶级盛会KubeCon + CloudNativeCon 2017北美峰会上进行演讲,本文由演讲内容整理而成。


随着Kubernetes越来越受欢迎,围绕它的集成和监控服务的数量也在不断增长。Golang编写的所有此类服务的关键组件是kubernetes / client-go——一个用于与Kubernetes集群API通信的软件包。在本文中,我们将讨论client-go使用的基本知识,以及如何为开发人员节约编写实际应用程序逻辑所需的时间。我们还将展示使用该软件包的最佳实践,并从每天与Kubernetes进行集成工作的开发人员的角度,分享我们已有的经验。内容将包括:

  • 集群中的客户端认证 vs. 集群外的客户端认证
  • 基本列表,使用client-go去创建和删除Kubernetes对象的操作
  • 如何使用ListWatch和Informers监视K8s事件并做出反应
  • 如何管理软件包依赖

Kubernetes是一个平台

Kubernetes有很多受欢迎的地方。用户喜欢它的丰富功能、稳定性和性能。对贡献者来说,Kubernetes开源社区不仅规模庞大,还易于上手、反馈迅速。而真正让Kubernetes吸引了第三方开发者的是它的可扩展性。该项目提供了很多方式来添加新功能、扩展现有功能而且不会中断主代码库。正是这些,使得Kubernetes发展成为了一个平台。 
这里有一些方式来扩展Kubernetes:

上图所示,你可以发现每个Kubernetes集群组件无论是Kubelet还是API服务器,都可以以某种方式进行扩展。今天我们将重点介绍一种“自定义控制器”的方式,从现在起我将它称为Kubernetes控制器(Kubernetes Controller),或者简单地称为控制器(Controller)。

Kubernetes控制器究竟是什么?

控制器最常见的定义是:使得系统的当前状态达到所期望的状态的代码。但这究竟是什么意思呢?我们以Ingress控制器为例。Ingress是一个Kubernetes资源,它能够对集群中服务的外部访问进行定义。通常采用HTTP并且有负载均衡支持。然而Kubernetes的核心代码中并没有ingress的实现。第三方控制器的实现将包含: 
1.监控ingress/services/endpoint 资源的事件(创建、更新、删除) 
2.程序内部或外部的负载均衡器 
3.使用负载均衡器的地址来更新Ingress 
“所期望的状态”在Ingress这里指的是IP地址指向运行着的负载均衡器,该均衡器由用户根据ingress规范定义的规则实现。并且由外部Ingress控制器负责将ingress资源转移到这一状态。 
对相同的资源,控制器的实现以及部署他们的方式也可能会有所不同。你可以选择nginx控制器并将其部署到集群中的每个节点上作为守护进程集(Daemon Set),也可以选择在Kubernetes集群外部运行ingress控制器并且对F5编程作为负载均衡器。这里没有严格的规定,Kubernetes就是如此灵活。

Client-go

这里有几种获得Kubernetes集群及其资源相关信息的方法,你可以使用Dashboard、kubectl或者使用对Kubernetes API的编程式访问来实现。Client-go所有用Go语言编写的工具中使用最为广泛的库,还有许多其他语言的版本(java、python等)。如果你还没自己写过控制器,我推荐你首先去尝试go/client-go。Kubernetes是用Go编写的,而且我发现使用和主项目相同的语言来开发插件会更加方便。

我们来搭建吧…

要熟悉相关的平台和工具,最好的办法就是去实践,去实现一些东西。我们从简单入手,先实现一个如下的控制器: 
1.监控Kubernetes节点 
2.当节点上的镜像占用存储空间时进行警报,并且可以更改 
这部分的实现,源码可以在这里找到:https://github.com/alena1108/kubecon2017

基本流程

配置项目

作为一名开发者,我和Rancher Labs的同事们更愿意使用轻便简易的工具,在这里我将分享3个我最喜欢的工具,它们将帮助我们完成第一个项目。 
1.go-skel – Go语言的微服务skeleton,只需执行run ./skel.sh test123即可,它会为新的go项目test123创建skeleton。 
2.trash – Go语言的供应商管理工具。实际上这儿有很多依赖项管理工具,但是在临时依赖项管理方面,trash使用起来非常出色,而且简单。 
3.dapper – 在一致性环境中对任何现有构建工具进行封装的一种工具

添加client-go作为一个依赖项

为了方便使用client-go的代码,我们必须要将其设置为项目的依赖项。将它添加到vendor.conf文件中:

接着运行trash。它会将vendor.conf中定义的所有依赖项都拉到项目的vendor文件夹中。在这里需要确保client-go与你集群对应的Kubernetes版本是兼容的。

创建一个客户端

在创建与Kubernetes API通信的客户端之前,我们必须要先决定如何运行我们的工具:是在Kubetnetes集群内部还是外部。当应用程序在集群内部运行时,对它进行容器化,部署成为Kubernetes pod。它还提供了一些额外的功能:你可以选择部署它的方式(Deamon set运行在每个节点上,或者作为n个副本的部署),配置针对它的健康检查等等。当应用程序在集群外部运行时,就需要自己来管理它。下面的配置可以让我们的工具变得更灵活,并且支持基于config flag定义客户端的两种方式:

我们将在调试应用程序时使用集群外部运行的方式,这样你不需要每次都构建镜像并且将其重新部署成Kubernetes pod。在测试好应用程序后,我们就可以构建镜像并将其部署到集群中。 
正如在截图中看到的那样,正在构建配置,并将其传递到kubernetes.NewForConfig来生成客户端。

使用基本的CRUDs

我们的工具需要监控节点。在实现逻辑流程之前,我们先来熟悉使用client-go执行CRUD操作:

上面的截图展示了: 
1.List节点minikube,是经过FieldSelector过滤器实现的 
2.用新的标注来更新节点 
3.使用gracePerios=10秒指令删除节点—意思是从该命令执行后10秒才会执行删除操作 
上面所有的步骤都是使用我们之前创建的用户集(clientset)进行的。 
我们还需要节点上镜像的相关信息;它可以通过访问相应的字段来检索:

使用Informer来进行监控/通知

现在我们知道了如何从Kubernetes APIs中获取节点并从中得到镜像信息。那么我们该如何监控镜像大小的变化呢?最简单的方法是周期性轮询节点,计算当前的镜像存储容量,并将其和先前轮询的结果比较。这里的不足之处在于:无论节点是否发生变化,我们执行的列表调用都会获取所有的节点,这可能会很费资源——特别是当轮询间隔很短的时候。而我们真正想要实现的是—在节点发生变化时得到通知,只有在这之后才执行我们的逻辑流程。这些就是client-go的Informer来做的。

在这个例子中,我们经过watchList指令为节点对象创建Informer来监控节点,设置对象类型为api.Node和30秒的同步周期来周期性地轮询节点,无论节点是否发生改变——这种方式在更新事件出于某种原因发生终止时可以很好的进行撤回。在最后一个参数,我们传递了2个回调函数——handleNodeAdd和handleNodeUpdate。这些回调函数具有实际的逻辑,并且在节点上的镜像占用存储发生改变时触发。NewInformer返回2个对象——controller和store。一旦controller启动,将会开始对node.update和node.add的监控,并且调用回调函数。这部分代码的存储区位于内存缓存中,由informer负责更新,另外你可以在缓存区中获取节点对象而不用直接调用Kubernetes APIs:

我们的项目中只有一个控制器,使用常规的Informer就足够了。不过,如果未来你的项目最终同一个对象拥有了多个控制器,我建议你使用SharedInformer。这样一来你不用再一个一个为每个控制器配上Informer,只需要注册一个Shared informer即可,并且让每个控制器注册自己的一组回调函数,返回共享缓存,这可以减少内存占用:

部署时间

是时候来部署和测试代码了!对于第一次运行,我们只需要创建一个go的二进制文件并且在集群外模式下运行它即可:

如要更改消息输出,那么使用镜像部署一个pod,该镜像是没有在当前节点显示的镜像。 
在基本的功能通过测试之后,接下来就是按照集群模式尝试运行它了。为此我们必须先创建镜像,定义它的Dockerfile:

并使用docker build创建一个镜像,该命令将生成一个可用在Kubernetes中部署pod的镜像。现在你的应用程序可以作为一个pod运行在Kubernetes集群上了。这里是一个部署定义的例子,在之前的截图中,我使用了该例部署我们的应用程序:

在本文中我们做了如下工作: 
1.创建go项目 
2.为项目添加client-go包的依赖项 
3.创建用于和Kubernetes api通信的客户端 
4.定义一个用于监控节点对象改变,并且一旦发生就执行回调函数的Informer 
5.在回调函数中实现一个实际的逻辑 
6.在集群外运行二进制文件来测试代码,并把它部署到集群中

推荐阅读

http://mp.weixin.qq.com/s/4-cFeRsa0J4tr6GE91Grag 
http://mp.weixin.qq.com/s/2qZHVM-JrJ4kaKt4qBhq5w 
http://mp.weixin.qq.com/s/prP9pFTXG6EHoDGoh_nyEA 
http://mp.weixin.qq.com/s/FJ2D34ewH_bL8kSM-eUE1g

如何在GO语言中使用Kubernetes API?相关推荐

  1. python flink_如何在 Apache Flink 中使用 Python API?

    原标题:如何在 Apache Flink 中使用 Python API? 导读:本文重点为大家介绍 Flink Python API 的现状及未来规划,主要内容包括:Apache Flink Pyth ...

  2. linux检查socekt是否断开,如何在C语言中判断socket是否已经断开

    如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭.小编今天跟大家简单介绍下如何在C语言中判断socket是否已经断开 下面来介绍判断非 ...

  3. 在linux下,如何在C语言中使用正则表达式

    http://hi.baidu.com/d_south/blog/item/9d22a34b1fc2bcf483025c53.html 在linux下,如何在C语言中使用正则表达式(整理) 2008- ...

  4. c语言if中文字符串比较好,如何在C语言中使用汉字作为if的判断语句?

    题目: 如何在C语言中使用汉字作为if的判断语句? 解答: 直观点可以用strcmp函数,如果想用直接用==或!=来判断,你要先把汉字换成一个unsigned short型,要比较的汉字也放入一个un ...

  5. 怎样设置一个函数C语言,C语言中怎样编写一个函数 如何在C语言中定义一个函数?...

    如何在C语言中定义一个函数?小编很想在你面前流泪最后却还是选择装作打个哈欠 为什么小编怎么定义函数都不正确呢? 总是说小编 表达语法错误在main函数中 小编们可以在头文件与main函数之间定义,并编 ...

  6. c语言如何输入数字,请问如何在C语言中输入数字获得拼音?

    请问如何在C语言中输入数字获得拼音? 答案:1  信息版本:手机版 解决时间 2018-12-10 16:41 已解决 2018-12-10 08:20 请问如何在C语言中输入数字获得拼音? 最佳答案 ...

  7. c语言编程输出字母倒三角形,如何在C语言中打印倒三角形

    如何在C语言中打印倒三角形 发布时间:2020-07-28 11:53:15 来源:亿速云 阅读:281 作者:Leah 这期内容当中小编将会给大家带来有关如何在C语言中打印倒三角形,文章内容丰富且以 ...

  8. c语言 引用定义变量,如何在c语言中定义及引用全局变量?

    如何在c语言中定义及引用全局变量? 答案:5  信息版本:手机版 解决时间 2019-10-03 10:30 已解决 2019-10-02 15:19 如何在c语言中定义及引用全局变量? 最佳答案 2 ...

  9. 如何在R语言中建立六边形矩阵热图heatmap可视化

    原文链接:http://tecdat.cn/?p=18879 这是一个六边形热图可视化程序,主要用到的知识RColorBrewer,fields,也就是R中的可视化绘图库(点击文末"阅读原文 ...

最新文章

  1. Flyme6系统适配教程(Patchrom)
  2. java教务系统类设计_基于Java EE体系的高校教务管理系统的设计开发
  3. ASP.NET Repeater 头模板(HeaderTemplate)和FooterTemplate模板中查找控件
  4. poj 3486 A Simple Problem with Integers(树状数组第三种模板改段求段)
  5. 光电转换模块_关于光电倍增管(PMT)模块的选型与使用
  6. 如何选择Spark Streaming 的Reveiver和Direct模式
  7. JAVA转大数据的学习之路,就该这样走(内附1T大数据资料)
  8. wpf 修改输入框 光标_WPF中鼠标光标的设置
  9. 关系代数 元组关系演算
  10. 苹果付费app共享公众号_公众号+搭建知识付费网课分销平台聚合型玩法解析
  11. 设计稿 自动html,简单的登陆页面PSD设计稿来演示转化为HTML页面的全部过程
  12. Java多线程实现简易微信发红包
  13. Ubuntu云服务器搭建饥荒联机版服务器教程
  14. 简述python在量化金融中应用_Python金融量化
  15. 用python生成M序列
  16. 新服务器安装 -mima
  17. WinSock控件及WinSockAPI
  18. 一对一 视频聊天源码,不要小瞧社交平台的盈利方式
  19. 点燃我,温暖你(打火机与公主裙)真零基础爱心教程!
  20. 计算机鼓轮原理,数码裂隙灯显微镜光学系统的设计与实现

热门文章

  1. 技能类别mysql_MySQL 数据类型
  2. 浙大计算机基础知识2,[精选资料]14年浙大远程计算机基础2Windows知识题高起专 作业题2答案...
  3. python size和count_groupby 的妙用(注意size和count)
  4. Statement对象最新解析
  5. Opencv之二维码识别---QRCodeDetector
  6. PCL之区域生长分割
  7. linux能上ps吗,在linux上使用ps(转载)
  8. java语句电脑定时关机_月光软件站 - 编程文档 - Java - windows定时关机程序
  9. 阿里开发者们的第15个感悟:做一款优秀大数据引擎,要找准重点解决的业务场景...
  10. ms12_004漏洞进行渗透