认识Kubebuilder

news2024/11/17 5:24:14

认识Kubebuilder

  • 一、什么是Kubebuilder?
    • Kubebuilder,K8s operator创建框架
    • controller-runtime和controller-tools库
  • 二、Kubebuilder,举例来说
    • 开源项目kuik
  • 三、使用 kubebuilder init 创建基础项目
  • 四、使用kubebuilder create api生成控制器
    • CachedImages控制器
    • Pods控制器
    • 生成与 CRD 相关的文件
    • make generate和make manifest命令
    • 使用kubebuilder create webhook生成webhook
    • 使用make test运行测试
    • 在本地运行operator
  • 五、Kubebuilder: 优势和局限性
  • 六、我们对kubebuilder的看法

在这篇文章中,我将向您介绍如何使用kubebuilder轻松创建Kubernetes Operator。

在快速介绍 kubebuilder 后,我们将逐步创建一个 k8s Operator(以 kube-image-keeper Operator 为例,它是一个用于在 Kubernetes 集群中缓存镜像的开源工具)。最后,我们将讨论 kubebuilder 的优点和局限性。

一、什么是Kubebuilder?

Kubebuilder,K8s operator创建框架

  • Kubebuilder是一个旨在简化创建Kubernetes operators的框架。
  • 它使您能够直接从终端生成项目样板,包括诸如Makefile、Dockerfile和主要源文件(如main.go)等基本组件。
  • 一旦项目创建完成,Kubebuilder还可以帮助生成配置自定义资源定义(CRD)、控制器和Webhook的必要文件。

controller-runtime和controller-tools库

  • Kubebuilder基于controller-runtime和controller-tools库。虽然完全可以使用这些库来开发operator,但没有Kubebuilder会使这个过程变得繁琐,因为需要手动创建和编写必要的文件和代码,而Kubebuilder会自动生成这些文件和代码。

二、Kubebuilder,举例来说

让我们看一下使用 kubebuilder 创建 Kubernetes operator kube-image-keeper (kuik) 的具体示例。

开源项目kuik

  • Kuik是一个专为Kubernetes中容器镜像进行集群内缓存的operator。例如,在容器镜像注册表暂时不可用或为了避免超过注册表拉取配额(并产生相关费用)时,它非常有用。
  • 由于kuik是开源的,您有机会通过访问kuik的公共GitHub存储库来查看使用Kubebuilder生成的项目的整体架构。
  • 回到项目架构。简而言之,它包括两个控制器、一个变更Webhook和一个CRD,如下图所示:

在这里插入图片描述

  • 首先,Webhook重写Pod镜像的URL,将其重定向到缓存注册表。
  • 然后,两个控制器监视Pod和CachedImages:第一个根据Pod使用的镜像创建CachedImages,而第二个则通过CachedImages缓存请求的镜像。
  • 当kubelet要求容器运行时(例如containerd)启动容器时,运行时通过代理检索镜像,因为镜像已被重写为指向代理。
  • 最后,代理根据镜像是否已被缓存决定将镜像拉取请求转发到缓存注册表或原始注册表。

三、使用 kubebuilder init 创建基础项目

现在,大家到你们的终端吧!我们将生成 kubebuilder 项目的基本脚手架(或样板)。为此,请在空文件夹中执行以下命令:

kubebuilder init \
    --domain kuik.enix.io \
    --repo github.com/enix/kube-image-keeper

其中“domain”对应我们要创建的资源的api组,“repo”对应项目所在的git仓库。

Kubebuilder创建了几个文件和文件夹,包括:

  • config:包含项目的kustomize清单的文件夹。
  • Dockerfile:一个distroless Dockerfile。
  • hack:包含源文件的样板的文件夹(可用于在每个源文件顶部插入许可证)。
  • main.go:一个预填充的main函数,允许您立即启动一个功能性的“no-op”操作员。
  • Makefile:这个makefile允许您运行控制器,运行测试,甚至生成CRD的yaml清单。
  • PROJECT:描述kubebuilder项目及其各个组件的文件。

四、使用kubebuilder create api生成控制器

现在已经生成了基本项目,我们可以开始创建我们的控制器了。

CachedImages控制器

我们将从CachedImageController开始,它的作用是监视CachedImage,并在删除CachedImage时将引用的图像缓存或从缓存中删除它们:

kubebuilder create api \
    --kind CachedImage \
    --version v1alpha1 \
    --namespaced=false \
    --resource=true \
    --controller=true
  • 使用–resource和–controller标志可以让kubebuilder为指定的资源类型生成CRD和相应的控制器。否则,选择将以交互方式进行。标志–namespaced=false表示我们希望CachedImages是非命名空间的。

Pods控制器

为了生成负责监视Pods并创建CachedImages的控制器的基本结构,我们可以使用类似的命令。然而,我们指示Kubebuilder不要生成自定义资源定义(CRD),因为Pods已经是原生的Kubernetes资源。

kubebuilder create api \
    --group core \
    --kind Pod \
    --version v1 \
    --resource=false \
    --controller=true

运行这两个命令后,我们会得到几个新文件。值得注意的是,在controllers文件夹中,我们可以找到两个文件cachedimage_controller.go和pod_controller.go,以及suite_test.go文件,其中包含了快速设置集成测试所需的内容。CachedImage类型在api/v1alpha1/cachedimage_types.go文件中定义。我们注意到main.go文件已经更新,用于启动我们的两个新控制器。最后,PROJECT文件现在包含有关资源和控制器设置的信息。

为了说明,pod_controller.go文件如下所示:

package controllers

import (
	"context"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/log"
)

// PodReconciler reconciles a Pod object
type PodReconciler struct {
	client.Client
	Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=core,resources=pods/finalizers,verbs=update
func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	_ = log.FromContext(ctx)

	// TODO(user): your logic here

	return ctrl.Result{}, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&corev1.Pod{}).
		Complete(r)
}

协调函数定义协调循环。这是实现控制器逻辑的地方。

生成与 CRD 相关的文件

一旦实现了控制器并定义了 CachedImage 类型,我们仍然需要生成 CRD 的 yaml 清单以将其安装在 Kubernetes 集群中。

注释

如果你打开cachedimage_types.go,你可以看到一个CachedImage的定义,它看起来像这样(完整的文件有点长,但这部分对你来说是最有趣的):

type CachedImageSpec struct {
	Foo string `json:"foo,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster
type CachedImage struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   CachedImageSpec   `json:"spec,omitempty"`
	Status CachedImageStatus `json:"status,omitempty"`
}

除了结构体之外,我们还可以看到各种注释。这些注解描述了如何生成相应的CRD。例如,+kubebuilder:resource:scope=Cluster 表示 CachedImage 没有命名空间。其他注释也可用,例如,您可以添加要在 kubectl get 期间显示的列,这要归功于注释 +kubebuilder:printcolumn:name=“Foo”,type=“string”,JSONPath=“.spec.foo”。在这种特定情况下,我们添加“Foo”列,显示 CachedImages 的 .spec.foo 值。

make generate和make manifest命令

为了生成与我们的CRD相关的文件,我们将使用两个命令。

第一个命令make generate在调用kubebuilder create api命令时会自动执行,它会创建api/v1alpha1/zz_generated.deepcopy.go文件,该文件实现了操作符的某些关键函数,例如CachedImage.DeepCopy函数。

第二个命令是我们最感兴趣的命令:make manifests。这个命令会生成config/crd/bases/kuik.enix.io_cachedimages.yaml文件,其中包含了CRD的定义,我们随后可以将其安装到我们的Kubernetes集群中。

使用kubebuilder create webhook生成webhook

我们已经创建了两个控制器和我们的CRD,现在剩下的就是创建我们的变异webhook。

为了做到这一点,通常我们使用kubebuilder create webhook命令。然而,我们有一个小问题:kubebuilder不支持为“核心类型”创建webhook,而我们想要创建的webhook恰好是针对Pods的。因此,我们按照官方kubebuilder文档的说明,使用controller-runtime库自己创建此部分的样板代码。

如果您想为自定义资源创建webhook,就像创建控制器一样简单:

kubebuilder create webhook \
    --kind CachedImage \
    --version v1alpha1 \
    --defaulting

您可以在 --conversion、–defaulting 和 --programmatic-validation 标志之间进行选择,以创建不同类型的 Webhook。必须至少提供这 3 个标志之一,对应于以下功能:

  • –conversion:转换 webhook
  • –defaulting:实现 Defaulter 接口的准入 Webhook
  • –programmatic-validation:实现验证器接口的准入 webhook

使用make test运行测试

在配置控制器的各个组件之后,下一步显然是检查所有东西是否正常工作。为了做到这一点,我们实现了必要的测试,并重点关注suite_test.go文件中的集成测试。

为了执行测试,我们使用make test命令,该命令负责下载测试依赖项并执行它们。我们可以使用ENVTEST_K8S_VERSION环境变量选择要运行集成测试的Kubernetes API版本,例如ENVTEST_K8S_VERSION=1.25。但是要小心,只有控制平面的一部分会启动,即API服务器和etcd,但除我们创建的控制器之外的其他各种控制器不会被执行。因此,行为可能与预期略有不同。您可以在文档中找到更多细节。

在本地运行operator

为了简化开发过程,kubebuilder允许您使用’make run’命令在本地计算机上轻松运行操作符。当然,需要连接到您打算操作的Kubernetes集群。
然而,当您的操作符包含一个webhook时,需要采取一些预防措施。webhook需要一个证书以确保正常运行(在相应的MutatingWebhookConfiguration中指定的证书),并且发送到webhook的请求必须在集群外部发送。在这种情况下,我们将通过URL而不是Kubernetes服务在webhook配置(MutatingWebhookConfiguration.webhooks.clientConfig)中进行配置。文档建议在本地测试代码之前通过设置ENABLE_WEBHOOKS=false环境变量禁用webhook。

五、Kubebuilder: 优势和局限性

现在我们已经看到了使用kubebuilder创建Kubernetes操作符的用法,让我们来看看它的优势和局限性:

Kubebuilder的优势

  • 快速的Kubernetes操作符开发:kubebuilder简化了项目的快速启动过程。
  • 无需费力创建和维护CRD:它简化了定义和更新自定义资源定义的过程。
  • 集成测试的内置脚手架:kubebuilder设置了一个具有指定版本的Kubernetes API和etcd(不包括控制平面控制器)。这对于在GitHub中的测试矩阵非常方便。
  • 相对于Operator SDK的简单性:与Operator SDK相比,kubebuilder提供了一种更简单的方法,而Operator SDK本身是建立在kubebuilder之上。

Kubebuilder的局限性

  • 繁琐而手动的kubebuilder更新:当升级到较新版本的kubebuilder(因此更新生成的代码以获得改进)时,没有明确的说明如何修改先前生成的文件。仅仅更新kubebuilder是不够的,因为现有文件仍然保持不变。为了将新版本的kubebuilder的增强功能合并到项目中,最简单的方法是在新目录中重新生成项目,然后手动将脚手架更改应用到原始项目中。这项任务可能很繁琐。虽然已经提出了一个命令来简化这项任务,但在撰写本文时尚未实施。
  • 对Kustomize的原生支持,但不支持Helm:kubebuilder自动生成Kustomize清单,而不提供用户选择的选项。如果用户计划使用Helm部署应用程序,他必须手动编写Helm清单。
  • 非标准的目录结构:控制器和api文件夹应该在pkg或internal文件夹中。
  • Kubebuilder、Kubernetes和Golang之间的版本依赖关系:更新这三个元素中的一个可能需要更新其他元素。例如,更新golang版本可能需要更新Kubernetes版本,并放弃对旧版本的支持。特定版本的kubebuilder被设计为与特定的Kubernetes版本一起使用,依此类推。
  • 使用dependabot(用于自动更新依赖项的GitHub bot):您可能需要要求dependabot忽略由kubebuilder管理的某些依赖项,因为更新它们可能会导致问题。如前所述,kubebuilder、Kubernetes和golang的版本密切相关,并且通常需要协调更新。
  • gitignore文件夹中的二进制文件:makefile在被git忽略的文件夹中安装二进制文件。在更新项目时,请记得删除这些二进制文件,以便kubebuilder可以重新安装它们。忘记这一步可能导致二进制文件与kubebuilder版本不匹配,可能导致项目故障。
  • 核心类型的脚手架:kubebuilder无法为Kubernetes核心类型(如Pods)生成脚手架。这方面需要手动配置。在kube-image-keeper项目的示例中,我们在Pods上使用了一个变异webhook。kubebuilder无法为此webhook生成所需的文件,因此我们必须手动创建它们。

六、我们对kubebuilder的看法

Kubebuilder可以显著简化您的Kubernetes操作符的开发。它在启动新项目时似乎特别有价值。然而,根据操作符的不同,它也有一些限制,这使得它的使用变得复杂,并需要偏离工具的初始操作和文件组织。在这种情况下,您需要仔细评估是否继续使用Kubebuilder或转换为手动操作符更新。

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

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

相关文章

gitea仓库迁移新服务器 更新远程仓库地址(git remote remove origin)

文章目录 引言I 镜像部署方式迁移案例迁移容器备份gitea服务器配置II 修改​远程仓库地址set-url语法案例III 扩展基于git命令方式进行代码迁移忽略被追踪的文件(update .gitignore)see also引言 由于部署git仓库的机器不稳定,决定进行服务器迁移。更新远程仓库地址的应用场景…

传统助贷机构如何利用CRM系统转型升级

传统助贷机构在利用CRM系统(客户关系管理系统)进行转型升级时,可以遵循以下几个关键步骤和策略,以优化客户管理、提升业务效率并实现业务增长: 一、明确转型升级目标 首先,传统助贷机构需要明确利用CRM系统…

使用docker compose一键部署 Openldap

使用docker compose一键部署 Openldap LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是一种用于访问分布式目录服务的网络协议,OpenLDAP 是 LDAP 协议的一个开源实现,由 OpenLDAP 项目提供&#x…

python库(21):TextBlob库实现文本处理

1 TextBlob简介 TextBlob 是一个基于 Python 的文本处理库,能够让基础的自然语言处理任务变得异常简单。 它提供了一个简单直观的 API,让你能够轻松执行词性标注、名词短语提取、情感分析、文本分类和关键词提取等功能。 值得一提的是,Tex…

Linux git的基本使用 安装 提交

目录 安装git 首次使用git的配置 拉取仓库 步骤1:新建仓库 步骤2:复制仓库地址 步骤3:远端仓库拉取到本地 上传代码 常用指令 安装git sudo apt-get install git # Ubuntu/Debian sudo dnf install git # Fedora sudo yum insta…

BMS中内阻补偿的使用

在BMS(电池管理系统)中,内阻补偿的使用主要涉及以下几个步骤和方法: 1. 内阻测量 实时监测:通过专用电路或算法实时测量电池的内阻。常用的方法包括脉冲测试法和交流阻抗测试法。计算内阻:基于电流和电压…

基于AI+多技术融合在流域生态系统服务评价 制图、水资源水环境水生态分析、土壤侵蚀分析、流域产水分析、流域碳收支评估、气候变化影响等应用

流域生态系统服务在环境保护与资源管理中具有不可替代的重要性。随着全球气候变化和人类活动对自然环境的压力日益增大,流域生态系统的稳定性和健康状况面临严峻挑战。水资源短缺、洪水频发、水质污染、生物多样性减少等问题,正在威胁流域内及其下游区域…

【综合架构】Part 5.2 Ansible

安装设备:管理设备-m01-10.0.0.61 部署与配置 部署 yum install -y ansible 配置 步骤 1:修改配置文件:关闭Host_key_checking。 vim /etc/ansible/ansible.cfg 步骤 2:修改配置文件:开启日志功能。

作为HR如何解决候选人爽约的问题

为了降低候选人的爽约概率,HR可以直接在预约面试时,通过电话或短信等多种方式,与候选人进行沟通,确保对方完全清楚面试的时间、地点和流程。在双方沟通的过程中,HR一定要注意语气亲切,要让候选人感受到企业…

2020年中国海岸带10m土地覆盖图

2020年中国海岸带10m土地覆盖遥感图 数据介绍 土地利用/覆盖分类是研究海岸带动态变化过程、理解滨海社会-生态系统作用机制和支持可持续发展的重要基础。中国海岸带土地覆盖复杂多样,以往多类别地表覆盖和滨海湿地专题数据集难以兼顾陆域和海域信息,而…

软考攻略/超详细/系统集成项目管理工程师/基础知识分享07

第三章 信息技术服务 3.1 内涵与外延 3.1.1 服务的特征(掌握) 服务的特征包括:无形性、不可分离性、可变性和不可储存性等。 3.1.2 IT服务的内涵(掌握) IT服务除了具备服务的基本特征,还具备本质特征、形…

利用C++实现PCL点云可视化:示例程序及解析(持续更新)

【版权声明】本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 参考书籍:《人工智能点云处理及深度学习算法》 本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“【python三维深度学习】python…

HTML <template> 标签的基本技巧

前言 HTML中的<template>标记是 Web 开发中一个功能强大但经常未得到充分利用的元素。它允许你定义可重复使用的内容&#xff0c;这些内容可以克隆并插入 DOM 中而无需最初渲染。 此功能对于创建动态、交互式 Web 应用程序特别有用。 在本文中&#xff0c;我们将探讨有…

二极管、电阻、电容、电感的种类及作用

系列文章目录 文章目录 系列文章目录前言二极管的种类二极管的作用电容的种类电容的作用电阻的作用电感的作用 前言 参考&#xff1a;这个UP的视频&#xff1a;8位和32位单片机最本质区别&#xff0c;2分钟看懂&#xff01; 二极管的种类 1.恒流二极管&#xff1a;可以用在恒…

微积分复习笔记 Calculus Volume 1 - 1.2 Basic Classes of Functions

1.2 Basic Classes of Functions - Calculus Volume 1 | OpenStax

NetApp AFF A 全闪存系列,专为 AI 时代打造的统一数据存储

NetApp AFF A 系列系统可轻松为要求最苛刻的工作负载提供动力支持&#xff0c;从当前运行业务的任务关键型应用程序到未来将释放创新潜能和工作效率的 AI 和 GenAI 工作负载。凭借 GenAI 和其他现代企业业务负载所迫切需要的高级数据管理能力、行业领先的勒索软件防范技术和云集…

antd vue switch组件怎么把值true、false改为uint32类型的1和0

背景 已知switch组件的checked属性默认是传入true 和 false的&#xff0c;但是有这样的业务情景&#xff0c;既需要使用的是开关&#xff0c;又需要传入的是整数&#xff0c;那么我们应该如何修改呢&#xff1f; 解决方案 <a-form-item label"允许失败时保存"&…

视频压缩怎么操作?三个办法教你无损压缩视频

随着假期的结束&#xff0c;很多同学和朋友们开始整理自己在假期期间拍摄的各种视频&#xff0c;准备分享到社交媒体或是保存到自己的移动设备上。 然而&#xff0c;面对高清甚至4K视频的大文件体积&#xff0c;不少人都会遇到存储空间不足的问题。这时候&#xff0c;一个好的…

完全二叉树的表示转换:从邻接链表到邻接矩阵

完全二叉树的表示转换:从邻接链表到邻接矩阵 摘要一、引言二、完全二叉树的特点三、邻接链表到邻接矩阵的转换四、C代码实现五、结果分析六、结论摘要 在数据结构中,树是一种重要的非线性数据结构,用于表示具有层次关系的数据。树的表示方法主要有两种:邻接链表和邻接矩阵…

vscode +STM32 VS CODE EXTENSION

stm32 vs code extersion 1.0.0版本可以直接导入cubeide的工程&#xff0c;之后版本不可以&#xff0c;所以为了省事&#xff0c;使用stm32 vs code extersion 1.0.0插件。 安装完stm32 vs code extersion插件&#xff0c;会默认把相关插件一起安装。但是需要手动安装Ninja&am…