Kubernetes 声明式API

对于声明式API来说,只需向系统提交一个定义好的API对象来声明资源对象的"期望状态"。然后由系统去确保资源对象从"当前状态"迁移到"期望状态"。这里的API对象是一种"意向表达(Record of Intent)“。创建API对象的本质上是在告知Kubernetes系统,期望资源对象看起来应该是什么样子,这就是Kubernetes系统所谓的期望状态(Desired State)。更多API对象的介绍可以参考笔者Kubernetes API对象一文或者参考官网Kubernetes API Overview一文。
声明式API践行了"将简单留给用户,将复杂流程系统"的设计理念。对于用户来说,只需掌握API对象的使用,无需关心内部的实现细节。系统会使用控制器模式将资源对象调谐到API对象指定的"期望状态”。声明式API是Kubernetes最核心的设计理念,正因为实现了对声明式API的支持,才可在基于Kubernetes构建的上层平台使用一致的编程范式和交互编程界面,才使得今天整个云原生生态中诞生了如此多的Kubernetes插件能力和扩展。

API对象

在Kubernetes中,一个API对象的完整资源路径是由Group(API组)、Version(API版本)和Resource(API资源类型)3个部分组成的。通过这样的结构,整个Kubernetes里的所有API对象就可以用如下的树形结构表示出来:

请添加图片描述

如上图中,Resource类型为Job的API对象,其分组是batch,Version是v1。可以看到对于Kubernetes的核心API对象,如Pod、Service、ConfigMap、Node、Namespace等,其所在Group为空。所以,对于这些API对象,Kubernetes会直接放置在/api这个层级下。

查找API对象

在Kubernetes中需要查找API对象时,首先匹配API对象的Group。对于核心API对象,Kubernetes会在/api这个层级下匹配。对于非核心对象,如Job、CronJob、Deployment、StatefulSet等,Kubernetes就会在/apis这个层级查找它对应的Group。以Job、CronJob为例,其Group为batch,则对应层级是/apis/batch。
然后,Kubernetes会进一步匹配到API对象的Version。在Kubernetes中,同一种API对象可以有多个版本,这正是Kubernetes进行API版本化管理的重要手段。
最后,Kubernetes会匹配API对象的Resource。同一个Group、同一个Version,可以拥有多种不同的资源类型。如Group为batch,Version为v1下的资源类型有Job、CronJob。这样,就可以匹配到需要查找的API对象。以Job为例,对应的层级是/apis/batch/v1/jobs。
一个Kubernetes集群,可以通过"kubectl api-resources"命令查看本集群所支持的全体API类型。

创建API对象

熟悉了API对象的查找过程后,接下来介绍Kubernetes创建API对象的过程。这里以创建一个/apis/batch/v2alpha1层级下的CronJob对象为例,创建过程对应流程如下图所示:

请添加图片描述

(1) 通过kubectl命令或API Server提供的接口发起创建API对象的POST请求后,编写的API对象的YAML信息会被提交给API Server。而API Server的第一个功能,就是过滤这个请求,并完成一些前置性的工作,比如授权、超时处理、审计等。
(2) 然后,请求会进入MUX和Routes流程。MUX和Routes是API Server完成URL和Handler绑定的场所。而API Server的Handler要做的事情,就是查找到对应的API对象的类型定义,这里是CronJob对象。
(3) 接着,API Server会根据这个API对象的类型定义,使用用户提交的YAML文件里的字段,创建一个API对象,这里是CronJob对象。在这个过程中,API Server会进行一个Convert工作,即:把用户提交的YAML文件,转换成一个叫作Super Version的对象,它正是该API资源类型所有版本的字段全集。这样用户提交的不同版本的YAML文件,就都可以用这个Super Version对象来进行处理了。
(4) 执行完上一步后,API Server会先后进行Admission()和Validation()操作。Admission负责对API对象做进一步的验证或添加默认参数。如在某些情况下,为了适用于应用系统的配置,Admission逻辑可能会改变目标对象。此外,Admission逻辑也会改变请求操作的一部分相关资源。而Validation,则负责验证这个API对象里的各个字段是否合法。这个被验证过的API对象,都保存在了API Server里一个叫作Registry的数据结构中。也就是说,只要一个API对象的定义能在Registry里查到,它就是一个有效的Kubernetes API对象。
(5) 最后,API Server会把验证过的API对象转换成用户最初提交的版本,进行序列化操作,并调用存储服务(默认是etcd)保存起来。

自定义API对象

除了Kubernetes定义的API对象,Kubernetes也支持自定义API对象,这对扩展Kubernetes的功能有着重要的意义。为支持自定义API对象,Kubernetes在1.7版本之后,引入了CRD(Custom Resource Definition,自定义资源定义)插件机制。这样用户就可在Kubernetes中添加一个跟Pod、Node类似的、新的API资源类型,即:自定义API资源。这就如面向对象编程,如果想创建一个对象,应先定义一个类。在Kubernetes中,可以使用资源类型为CustomResourceDefinition的资源来声明自定义API资源。
在编写资源类型为CustomResourceDefinition的YAML文件前,先介绍下Kubernetes对CustomResourceDefinition的完整Schema约束。

apiVersion: apiextensions.k8s.io/v1               # CustomResourceDefinition所在分组及版本号
kind: CustomResourceDefinition                    # 指定资源类型为CustomResourceDefinition
metadata:                                         # 遵循一般地ObjectMeta定义annotations: object                                 # 记录一些注释信息,如轻量级上线工具的元数据信息、负责人员的电话或呼机号码等。creationTimestamp: time                             # 记录元数据的创建时间deletionGracePeriodSeconds: int                     # 优雅删除等待时间deletionTimestamp: time                             # 记录元数据的删除时间finalizers:                                         # 告诉 Kubernetes等到特定的条件被满足后,再完全删除被标记为删除的资源- string- stringgeneration: int                                     # 记录期望状态的版本的序列号lables: object                                      # 标签用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义name: string                                        # 标识元数据的名称namespace: string                                   # 指定作用的namespaceownerReferences:                                    # 指定属主(Owner)- object- objectuid: string                                         # 标识元数据,在整个集群中具有唯一性
spec:                                             # 描述期望状态及一些基础信息group: string                                       # 指定自定义资源所在分组scope: Namespaced | Cluster                         # 指定资源作用于Cluster还是Namespaceversions:                                           # 记录当前自定义资源支持的版本信息- name: string                                       # 版本名称,如v1、v2beta1等deprecated: boolean                                # 指定版本是否已经废弃,默认是falseserved: boolean                                    # 指定版本是否可以作为REST API使用storage: boolean                                   # 表示在将自定义资源保存到存储时应使用此版本。必须只有一个版本storage=true。同一时间段,只能使用一个版本schema:                                            # schema用来声明对自定义资源的字段规范openAPIV3Schema:                                     # OpenAPI v3 schema,定义遵循JSON Schematype: string                                          # 指定字段的类型properties: object                                    # 指定字段名及类型...conversion:                                         # 记录转换版本的策略strategy: None | Webhook                             # 选用的转换版本的策略webhook: object                                      # 策略为webhook的配置信息names:                                              # 指定自定义资源的类型名称kind: string                                         # 自定义资源的类型名称plural: string                                       # 自定义资源的复数名称singular: string                                     # 自定义资源的单数名称shortNames:                                          # 提供的自定义资源的简写- string- stringcategories:                                          # 指定自定义资源所属的类别,用于客户端(如kubectl get all)查找- string- string
status:                                           # 描述当前状态,由Kubernetes自动更新acceptedNames: object                              # 记录已经使用的名称conditions:                                        # 记录自定义资源的特定状态- object- objectstoredVersions:                                    # 自定义资源使用过的版本列表- string- string

可以看下,CustomResourceDefinition中字段的定义遵循一般的API对象中要求的字段,核心字段都是由apiVersion、kind、metadata、spec等组成,只是在字段含义上进行了扩展。更多CustomResourceDefinition的spec字段说明可以参考Kubernetes官网CustomResourceDefinitionSpec v1 apiextensions一文。更多CustomResourceDefinition的status字段说明可以参考Kubernetes官网CustomResourceDefinitionStatus v1 apiextensions一文。
接下来给出一个自定义资源的定义示例:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:name: example.custom.resource.definition
spec:group: example.k8s.ioversions:- name: v1served: truestorage: trueschema:openAPIV3Schema:type: objectproperties:host:type: stringport:type: stringnames:kind: CustomResourceplural: customresourcessingular: customresourcescope: Namespaced

这样,就定义了Group为example.k8s.io,Version为v1,kind为CustomResource的自定义资源类型。其中该类型资源包含两个关键字段host和port。使用"kubectl apply"命令后,就可在Kubernetes中创建该自定义资源。
完成了自定义资源的创建后,接下来就可以创建一个自定义API对象了。基于上述自定义资源创建的API对象示例如下:

apiVersion: example.k8s.io/v1
kind: CustomResource
metadata:name: demo-custom-resource
spec:host: "192.168.1.1"port: "80"

这样就定义了一个资源类型为CustomResource的API对象,其中有两个业务字段:host、port。然后使用使用"kubectl apply"命令后,就可在Kubernetes中创建该API对象。然后使用"kubectl get customresource xxx"就可以查看到新创建的API对象。

自定义控制器

声明式API的特点是只需告知系统资源对象的"期望状态",而无需关心系统如何实现从"当前状态"迁移到"期望状态"。在Kubernetes中,使用控制器确保资源对象在"期望状态"的调谐。对于自定义API对象,如果需要维持其"期望状态",还需定义一个自定义控制器。这篇文章重点关注自定义控制器的原理,更多自定义控制器的编码实现可以参考《深入剖析Kubernetes》一书或参考网络上相关软文。
自定义控制器的实现逻辑遵循一般的控制器的实现逻辑,这里给出控制器的实现逻辑图:

请添加图片描述

在上图中,控制器通过Informer来跟踪资源。Informer的Reflector负责与API Server保持通信,并基于List & Watch机制观察所关心的资源。一旦资源发生事件变更,Informer的Reflector就将资源列表和后续的资源变化放到FIFO。然后Informer会将相应的callbacks存入WorkQueue并等待Worker将其取出运行。Worker首先会比较WorkQueue中资源对象的实际状态与期望状态的差别,然后执行相应的业务逻辑(如删除不再需要的资源、创建新的资源等),直到达成期望状态。Worker在执行业务逻辑时,需要调用Client提供的CRUD 方法,由其代为向API Server发送执行请求。Api Server完成执行后,执行结果会被写入etcd,相应的记录也会被更新到API Server。
在上述逻辑中,控制器部分只需要实现期望状态的调谐即可,也即Worker的工作。此外,在控制器里可以对自定义API对象和默认API对象进行协同,来实现更复杂的编排功能。
控制器的实现体现了标准的"Kubernetes编程范式",即如何使用控制器模式同Kubernetes里API对象的"增、删、改、查"进行协作,进而完成用户业务逻辑的编写过程。简言之,Kubernetes的编程范式就是CRD + 自定义控制器。其中CRD用来定义资源对象,控制器则用来处理相应API对象的控制逻辑。

Operator

Operator是一种封装、部署和管理Kubernetes应用的方法。Operator是一种特定于应用的控制器,可扩展 Kubernetes API的功能,来代表Kubernetes用户创建、配置和管理复杂应用的实例。Operator可以在不修改Kubernetes自身代码的情况下,通过为一个或多个自定义资源关联控制器来扩展Kubernetes集群的能力。Operator基于Kubernetes资源和控制器构建,但又涵盖了特定于领域或应用的知识,用于实现其所管理软件的整个生命周期的自动化。Operator是将运维人员对软件操作的知识给代码化,同时利用Kubernetes强大的抽象来管理大规模的软件应用。
Operator使用自定义资源和自定义控制器实现应用的管理。Operator实际上是利用Kubernetes的CRD来描述需要部署的应用,然后在自定义控制器里根据自定义API对象的变化,来完成具体的部署和运维工作。高级配置和设置由用户在自定义资源中提供。Operator基于嵌入在Operator逻辑中的最佳实践将高级指令转换为低级操作。自定义资源是Kubernetes中的API对象扩展机制。自定义资源定义会明确自定义资源并列出可用的所有配置。自定义控制器实施控制循环,反复比较集群的理想状态和实际状态。如果集群的实际状态与理想状态不符,控制器将采取措施解决此问题。
Kubernetes Operator几乎可执行任何操作:按需部署应用、扩展复杂的应用、应用的版本升级、使用专用硬件管理计算集群中节点的内核模块,等等。
Operator的实现由标准的开发流程,这里不展开说明,有需求的同学还请自行学习。

参考

《Kubernetes权威指南 从Docker到Kubernetes实践全接触》 龚正 吴治辉 闫健勇 编著
《深入剖析Kubernetes》 张磊 著
https://www.bookstack.cn/read/learning-cloudnative/7bb7c6d9505bf389.md 声明式API
https://blog.csdn.net/KevinBetterQ/article/details/104012293 Kubernetes 核心理解之声明式API和编程范式
https://www.meshcloud.io/en/blog/should-i-provide-a-declarative-api-you-probably-should/ Should I provide a declarative API?
https://www.educative.io/blog/declarative-vs-imperative-programming Declarative vs imperative programming: 5 key differences
https://learn.lianglianglee.com/专栏/深入剖析Kubernetes 深入剖析Kubernetes
http://docs.kubernetes.org.cn/144.html Kubernetes 使用准入控制器(Admission Controllers)
https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ 使用 CustomResourceDefinition 扩展 Kubernetes API
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#customresourcedefinition-v1-apiextensions-k8s-io CustomResourceDefinition v1 apiextensions.k8s.io
https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/ Versions in CustomResourceDefinitions
https://hliangzhao.cn/post/2021/12/23/k8s-4/ 自定义资源对象与控制器的实现
https://zhuanlan.zhihu.com/p/141877334 如何在Kubernetes中创建一个自定义Controller?
https://blog.csdn.net/KevinBetterQ/article/details/104012293 Kubernetes 核心理解之声明式API和编程范式
https://kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/operator/ Operator 模式
https://www.redhat.com/zh/topics/containers/what-is-a-kubernetes-operator 什么是 Kubernetes Operator?
https://jimmysong.io/kubernetes-handbook/develop/operator.html Operator
https://zhuanlan.zhihu.com/p/339966406 深入理解Kubernetes Operator
https://zhuanlan.zhihu.com/p/515524518 面向k8s编程,如何写一个Operator

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2804292.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins持续集成Python项目

一、前言   之前学习了很多自动化测试框架,但是写的脚本都是本地执行,多数用来造数据。最近公司掀起一股自动化测试的风,所以就想研究下如何集成jenkins,本次采用pytest,用的是阿里云服务器centos7。 二、服务器环境…

1.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-测试需求与需求拆解

内容参考于:易道云信息技术研究院VIP课 上一个内容:分析接收到的对话数据包 这是一个新的篇章,之前是关于把我们的东西放进游戏里和内存里的数据分析与利用,现在是专注于网络部分,通过分析网络数据包得到应用程序中各…

J7 - 对于ResNeXt-50算法的思考

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 J6周有一段代码如下 思考过程 首先看到这个问题的描述,想到的是可能使用了向量操作的广播机制然后就想想办法验证一下&…

华清远见作业第四十二天——Qt(第四天)

思维导图&#xff1a; 编程&#xff1a; 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTextToSpeech> //语音播报类 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public Q…

【C++精简版回顾】5.字符串

1.字符串的四种初始化方式 string str "ilove"; string str1("ilove"); string str2(str1); string str3 str1; 2.针对字符串的一些函数 &#xff08;1&#xff09;字符串长度 cout<<str.length()<<endl;&#xff08;2&#xff09;查找字…

基于qt的图书管理系统----03核心界面设计

参考b站&#xff1a;视频连接 源码github&#xff1a;github 目录 1 添加软件图标2 打包程序3 三个管理界面设计4 代码编写4.1 加载界面4.2 点击按钮切换界面4.3 组团添加样式4.4 搭建表头4.5 表格相关操作 从别人那里下载的项目会有这个文件&#xff0c;里边是别人配置的路径…

[NOI2000]单词查找树

牛客题目链接:https://ac.nowcoder.com/acm/problem/16864 题目描述: 在进行文法分析的时候&#xff0c;通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度&#xff0c;通常都要画出与单词列表所对应的单词查找树&#xff0c;其特点如下 (1). 根节点不包含…

Docker 是怎么工作的?

Docker 是怎么工作的&#xff1f; 本文转自 公众号 ByteByteGo&#xff0c;如有侵权&#xff0c;请联系&#xff0c;立即删除 Docker 是如何工作的&#xff1f; 下图展示了 Docker 的架构&#xff0c;以及当我们运行 “docker build”、"docker pull "和 "docke…

灌水:powershell 练习正则表达式

亲爱的读者们&#xff0c;请展示你们的能力&#xff1a;解析&#xff08;使用代码&#xff09;解析以下字符串 <鱼龙混杂的奇葩文件#> UI1|System.Windows.Forms.linklabel #创建用户对象 1.location.250.250 1.text.磁盘清理 1.autosize #自适应大小 #存在混淆风险…

分享一个UE的SmoothStep小技巧

SmoothStep节点可以制作更平滑的动画&#xff0c;而如果将max参数作为值传入将value和min参数作为约束&#xff0c;则可以做出类似冲击波的渐变效果&#xff1a; 并且通过修改value与min之间的数值差&#xff0c;可以调节渐变。 这个技巧主要就是可以产生硬边。 比如我们可…

Node.js的debug模块源码分析及在harmonyOS平台移植

Debug库 是一个小巧但功能强大的 JavaScript 调试工具库&#xff0c;可以帮助开发人员更轻松地进行调试&#xff0c;以便更快地发现和修复问题。它的主要特点是可以轻松地添加调试日志语句&#xff0c;同时在不需要调试时可以轻松地禁用它们&#xff0c;以避免在生产环境中对性…

【qt】类似微信扫描动画局部paint,防止cpu占用过高

实现类似微信扫码扫描效果&#xff0c;arm性能不高&#xff0c;如果直接定时器move线条的位置全局paint&#xff0c;会导致cpu占用过高&#xff0c;UI卡顿。所以需要仅仅绘制需要绘制的区域&#xff0c;减少cpu占用。 主要代码 #define MOVE_STEP 2 #define START_Y 300 #de…

使用HiveMQ实现Android MQTT

MQTT官网&#xff1a;https://mqtt.org/ 百度Android MQTT&#xff0c;或者B站上搜索&#xff0c;发现大多使用https://github.com/eclipse/paho.mqtt.android&#xff0c;这是Eclipse的一个Android MQTT客户端实现库&#xff0c;但是我发现这个库在运行到高版本的手机上时报错…

第九节HarmonyOS 常用基础组件27-Rating

1、描述 提供在给定范围内选择评分的组件。 2、接口 Rating(options?:{rating:number, indicator?:boolean}) 3、参数 参数名 参数类型 必填 描述 rating number 是 设置并接收评分值。默认值&#xff1a;0&#xff1b;取值范围[0, stars]&#xff0c;小于0取0&am…

运维SRE-17 自动化批量管理-ansible3

--- - hosts:alltasks:- name: 01 打开冰箱门shell: echo 01 >> /tmp/bingxiang.log- name: 02 把大象放进冰箱里shell: echo 02 >> /tmp/bingxiang.log- name: 03 关上冰箱门shell: echo 03 >> /tmp/bingxiang.log[rootm01 /server/ans/playbook]# cat 05-n…

Spring Boot WebFlux:实现web(Server-Sent Events)事件异步推送

WebFlux 在Spring Boot中&#xff0c;Flux是一个重要的概念&#xff0c;它是Spring Framework 5.0以后引入的响应式编程框架WebFlux的核心组件之一。Flux是Reactor项目的一部分&#xff0c;它实现了Reactive Streams规范&#xff0c;用于处理异步、非阻塞的数据流。 与传统的…

Grounded-SAM(最强Zero-Shot视觉应用):本地部署及各个模块的全网最详细使用教程!

本篇文章主要对Grounded-SAM项目的部署以及使用进行讲解&#xff0c;目的是使读者可以直接参考文档去使用Grounded-SAM&#xff0c;而无需再去参考Github一步步自己去分析尝试&#xff08;也算是我使用过程中的心得&#xff09;。 对于Grounded-SAM 技术报告的paper阅读可以跳转…

介绍 CI / CD

目录 一、介绍 CI / CD 1、为什么要 CI / CD 方法简介 1、持续集成 2、持续交付 3、持续部署 2、GitLab CI / CD简介 3、GitLab CI / CD 的工作原理 4、基本CI / CD工作流程 5、首次设置 GitLab CI / CD 6、GitLab CI / CD功能集 一、介绍 CI / CD 在本文档中&#x…

echarts 实现x轴文字过长时折行展示

代码如下&#xff1a; this.options {color: ["#0075FF", "#00E2C4", "#FCA884", "#FFCB11"],grid: {top: "25%",bottom: "6%",right: "8%",left: "8%",containLabel: true,},legend: {top…

springboot751社区维修平台

springboot751社区维修平台 获取源码——》公主号&#xff1a;计算机专业毕设大全