写点什么

如何在 GO 语言中使用 Kubernetes API?

  • 2020-04-12
  • 本文字数:3472 字

    阅读完需:约 11 分钟

如何在GO语言中使用Kubernetes API?

Rancher Labs 首席软件工程师 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、在集群外运行二进制文件来测试代码,并把它部署到集群中


2020-04-12 20:401478

评论

发布
暂无评论
发现更多内容

跨系统数据一致性问题解决方案汇总

架构精进之路

系统架构 数据一致性 三周年连更

FastAPI 快速开发 Web API 项目: 模板和 Jinja 介绍

宇宙之一粟

Python FastApi 三周年连更 Jinja2

开心档之C++ STL 教程

雪奈椰子

SoapUI参数传递操作详解

Liam

Postman 开发工具 接口测试 soapui

接口测试利器:AREX

AREX 中文社区

测试 自动化测试 接口测试 回归测试

一文详解 PoseiSwap,Nautilus Chain 上的首个 DEX

股市老人

Vue3 使用 Teleport 封装 一个 Dialog

程序员海军

Vue Vue 3 三周年连更

一文掌握 Go fmt 标准库常用方法的使用

陈明勇

Go golang 三周年连更 输入输出 fmt

中小企业如何保障网络安全?用了这么多项目华为云其实还不错!

YG科技

软件测试/测试开发丨PageObject 设计模式

测试人

软件测试 自动化测试 测试开发 pageobject

如何快速在手机中查看UDID,无需itunes、itools

iOS MachineLearning 系列(2)—— 静态图像分析之矩形识别

珲少

IT分享丨我是如何利用华为云网站安全解决方案帮助中小型企业实现IT安全

YG科技

REST vs SOAP:两种 Web 服务协议的分析

Apifox

网络协议 Rest API soap web 服务

一文详解 PoseiSwap,Nautilus Chain 上的首个 DEX

EOSdreamer111

华为云网站安全解决方案:守护您的网站,让安全无忧

YG科技

回顾2022:Web性能方面有哪些新功能

南城FE

性能优化 前端

华为云网站安全解决方案:守护企业数字化转型之路,提升业务效率与安全

YG科技

数据库、

2023-04-18:ffmpeg中的hw_decode.c的功能是通过使用显卡硬件加速器(如 NVIDIA CUDA、Intel Quick Sync Video 等)对视频进行解码,从而提高解码效

福大大架构师每日一题

golang 音视频 ffmpeg 福大大

保姆级教程!如何在 Anolis 8 上构建基于 Nydus 和 Dragonfly 的镜像加速解决方案?

OpenAnolis小助手

Linux 开源 镜像 解决方案 龙蜥社区

Kyligence CTO|消除技术门槛,人人可用的敏捷数据工具

Kyligence

数据分析 指标平台

Go语言并发编程利器(一):如何正确使用Channel

Jack

苹果怎么查看UDID iPhone/iPad查看UDID教程【详解】

雪奈椰子

【Java技术指南】「Unirest编程专题」一起认识一下一个“灰常”优秀的Http工具,让Http开发变得如此简单

洛神灬殇

Java HTTP 4月日更 Unirest

基于TCP协议的Socket通信

芯动大师

TCP协议 Socket请求 三周年连更

文心一言 VS chatgpt (11)-- 算法导论2.3 7题 3.1 4~5题

福大大架构师每日一题

福大大 ChatGPT 文心一言

开心档之MySQL 序列使用

汇量科技使用倚天710云实例,高效处理大流量广告请求

云布道师

阿里云

字节跳动副总裁杨震原:好的AI基础设施,如何激发工程师创造力?

字节跳动技术范儿

机器学习 字节跳动 算法 模型训练 算法工程师

HTTP事务的时延

阿泽🧸

三周年连更 HTTP时延

华为云:网络安全愈发重要,企业该如何保障自身业务安全?

YG科技

如何在GO语言中使用Kubernetes API?_文化 & 方法_Rancher_InfoQ精选文章