[ K8s Operator 开发完整教程 -3 ] 利用 kubebuilder 直接上手
![[ K8s Operator 开发完整教程-3 ] 利用kubebuilder直接上手](https://static001.geekbang.org/infoq/f5/f588eee2174c4f774fc9ff099b33c548.png)
关于教程
在《[ K8s Operator 开发完整教程-1 ] 总览》文章中,有讲述整理系列文章的初衷和创作思路。
本节目标
在本机环境安装好 kubebuilder;
利用上节部署好的 Kubernetes 集群,部署 CRD。
CRD 编写逻辑,能设置副本数,能够创建 pod。
理论准备
控制器模式
这是一个控制环的例子:房间里的温度自动调节器。
当你设置了温度,告诉了温度自动调节器你的期望状态(Desired State)。 房间的实际温度是当前状态(Current State)。 通过对设备的开关控制,温度自动调节器让其当前状态接近期望状态。
一个控制器至少追踪一种类型的 Kubernetes 资源。这些对象有一个代表期望状态的 spec 字段。 该资源的控制器负责确保其当前状态接近期望状态。
>> https://kubernetes.io/zh-cn/docs/concepts/architecture/controller/
Operator 模式
在 Kubernetes 上运行工作负载的人们都喜欢通过自动化来处理重复的任务。 Operator 模式会封装你编写的(Kubernetes 本身提供功能以外的)任务自动化代码。
在不修改 Kubernetes 自身代码的情况下, 通过为一个或多个自定义资源关联控制器来扩展集群的能力。 Operator 是 Kubernetes API 的客户端, 充当自定义资源的控制器。
>> https://kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/operator/
环境准备
以作者本机为例,整理如下
操作系统:macOS 15.5.1
brew:Homebrew 4.1.6-22-gae0f563
Go:go version go1.20.2 darwin/amd64
IDE 或编辑器:VSCode 1.81.1
kubectl:v1.28.1
api-server:v1.27.0
步骤
安装 kubebuilder
在 kubebuilder 官网有详细的各平台的安装目录,我们以 macOS 为例:
注意:下载完可执行文件,这里容易出一个问题是,该文件可能是不受信任的导致不可用。
此时,可打开 /usr/local/bin/
目录,并找到该文件,用有件打开文件,打开一次后,后续应该就正常了。
![](https://static001.geekbang.org/infoq/57/57eb9a4550bbebcbbedea83805381c78.png)
验证安装效果
![](https://static001.geekbang.org/infoq/3a/3a88f44c4b81680b53a81555209b196c.png)
项目目录
项目根目录位于 ~/project/try-operator
,后续操作都在该目录下进行。
初始化项目
注意,若你实际执行的目录是在 $GOPATH 内,则不需 --repo 参数,即:
![](https://static001.geekbang.org/infoq/5a/5a6603a362cb95c15e12ac51ae808009.png)
命令讲解
细节扩展,参数含义我们可以在 kubebuilder init --help
留意
![](https://static001.geekbang.org/infoq/b9/b91592027c3fe7a42d4fa18946b89019.png)
更新依赖
初始化后,会根据代码模板生成一个工程目录,但项目依赖需手动更新
创建 API
理解 API
官网-API概述为我们提供了官方定义,我们来回顾一下:
REST API 是 Kubernetes 的基本结构。 所有操作和组件之间的通信及外部用户命令都是调用 API 服务器处理的 REST API。 因此,Kubernetes 平台视一切皆为 API 对象, 且它们在 API 中有相应的定义。
Kubernetes API 使你可以在 Kubernetes 中查询和操纵 API 对象 (例如 Pod、Namespace、ConfigMap 和 Event)的状态。
为了更容易演进和扩展其 API,Kubernetes 实现了 API 组, 这些 API 组可以被启用或禁用。
API 资源通过其 API 组、资源类型、名字空间(用于名字空间作用域的资源)和名称来区分。
由上可知,在 K8s 设计中,API 是管理各类资源的一个核心概念,我们通过 /api/<group>/<version>
或 /apis/<group>/<version>
接口操作资源。
K8s API 文档也可以参考 >> https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/
![](https://static001.geekbang.org/infoq/77/7706c33cda4d21390a36601d35d46b93.png)
创建
kubebuilder 提供一个命令及可选标签来生成指定配置的 API,如下
我们这里定义的组名 apps
,版本 v1
,而资源类型是我们新的自定义的 Application
。
![](https://static001.geekbang.org/infoq/2a/2afbca1f41e4f13323974686c0743ee3.png)
命令讲解
该命令有哪些命令标签可用,可通过 kubebuilder create api -h
,来一探究竟,这里大概扫一眼即可。
![](https://static001.geekbang.org/infoq/67/671192d6de0720d64503aeb93a429b80.png)
工程目录
在生成 API 之后,我们看到又多了很多文件,而现在已经比较完整了,如下:
![](https://static001.geekbang.org/infoq/51/51333011a896d3fbfffc20871c626980.png)
开发流程
在创建 API 的命令讲解中,我们看到文档中已经有写到如何进行后续操作,我们在此总结
编辑 API 方案和 CRD 资源结构,在
api/v1/application_types.go
中。编辑控制器,在
internal/controller/application_controller.go
中。生成清单文件,使用命令
make manifests
。应用 CRD 清单文件,使用命令
make install
。生成代码并调试当前控制器,使用命令
make run
。
![](https://static001.geekbang.org/infoq/b6/b64b25be6a64cf49e689935d77ec6e96.png)
按照上边的流程,我们一步一步来:
修改 CRD
![](https://static001.geekbang.org/infoq/f6/f6ce8ebf2a662b5b902d6182fdc92ff2.png)
去掉 foo 字段,添加副本数、模板两个字段
记得文件上部要引入新的包 corev1
修改完必须重新生成清单文件
![](https://static001.geekbang.org/infoq/60/604358613ca836b67af22df6437a7cc2.png)
部署 Application CRD
前提,记得你的 docker 已启动, 本地已经按照上节内容创建好的 k8s 集群。否则可能会报错
![](https://static001.geekbang.org/infoq/7d/7d8147a2f37b05011bb7434dfac17429.png)
正常情况的部署,输出可能如下
检查 CRD 是否存在并安装好
![](https://static001.geekbang.org/infoq/6e/6e36e7e5b0b78262cb6bc7b427e40772.png)
我们看到了名字 kindNames.groupNames.domain 的形式。
运行 Application
我们尝试编辑一个资源清单,在 config/samples/apps_v1_application.yaml
:
![](https://static001.geekbang.org/infoq/c2/c253c0400d16034b14803825dbffc087.png)
应用该文件
![](https://static001.geekbang.org/infoq/ec/ecc2fa3d69a46e94aa264ae92959cb65.png)
此时,我们能看到 kubectl get application
命令出现了我们创建的资源,但是 pod 是没有任何变化的。因为我们的控制器逻辑还没写。
未完,待续。。。
版权声明: 本文为 InfoQ 作者【baiyutang】的原创文章。
原文链接:【http://xie.infoq.cn/article/7a315f5168fda5e2e534ca406】。文章转载请联系作者。
评论