Kubebuilder 使用记录
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubebuilder 使用记录相关的知识,希望对你有一定的参考价值。
文章目录
operator 介绍
(1)不同应用平台需要管理的目标各有差异,如何在 Kubernetes 中兼容定义管理的
目标?
(2)如何管理和备份系统的应用数据,协调各应用之间不同生命周期的状态?
(3)能否用同样的 Kubectl 命令来管理自己定义的复杂分布式应用?
在这些场景下,Kubernetes 自身基础模型已经无法支撑不同业务领域下的自动化场景。为了满足这些需求,谷歌提出了 Third Party Resources(TPR)概念,允许开发者根据业务需求的变化自定义资源和控制器,用于编写面向领域知识的业务逻辑控制,这就是Operator 的核心概念(后来 Kubernetes 使用 CRD 替代了 TPR,这两种机制除了名称,其他方面并没有什么变化)。
Operator 是 一 种 封 装、 部 署 和 管 理 Kubernetes 应 用 的 方 法, 用 户 可 以 使 用 Kubernetes API 和 Kubectl 工 具 在 Kubernetes 上 部 署 并 管 理 Kubernetes 应 用。Operator 基于基本 Kubernetes 资源和控制器概念构建,但又涵盖了特定领域或应用的知识,用于实现其所管理软件的整个生命周期的自动化,它是一种特定于应用的控制器,可扩展 Kubernetes API 的功能,是 Kubernetes 用户创建、配置和管理复杂应用的实例。
简单来说 Operator=Controller+CRD,Operator 是由 Kubernetes 自定义资源(CRD)和控制器(Controller)构成的云原生᠀展服务,其中 CRD 定义了每个 Operator 需要创建和管理的自定义资源对象,底层实际就是通过 APIServer 接口在 ETCD 中注册一种新的资源类型,注册完成后就可以创建该资源类型的对象了。但是仅注册资源和创建资源对象是没有任何实际意义的,CRD 最重要的是需要配合对应的 Controller 来实现自定义资源的功能,达到自定义资源期望的状态,比如内置的 Deployment Controller 用来控制 Deployment 资源的功能,根据配置生成特定数量的 Pod 监控其状态,并根据事件做出相应的动作。
用户想为自己的自定义资源构建一个 Kubernetes Operator,有很多工具可供选择,比如 Operator SDK、Kubebuilder,甚至可以使用 Operator SDK(Helm、Ansible、Go)
本文介绍 Kubebuilder,operator-sdk 可自行学习。
Kubebuilder
Kubebuilder 是一个帮助开发者快速开发 Kubernetes API 的脚手架命令行工具,依赖 Controller-tool 和 Controller-runtime 等库,简化 Kubernetes Controller 的开发,并且对 Kubernetes 的几个常用库进行了封装。
Kubebuilder 的整体工作流程如下:
(1)初始化一个新的工程目录。
(2)创建一个或多个资源 API CRD,然后将字段添加到资源。
(3)在控制器中实现协调循环(Reconcile Loop),监听额外的资源。
(4)在集群中运行测试(自动安装 CRD 并自动启动控制器)。
(5)更新引导测试新字段和业务逻辑。
(6)生产环境使用 Dockerfile 构建和发布容器。
实操手册
安装
git clone https://gitee.com/henrywangx/kubebuilder.git
cd kubebuilder
make build
cp bin/kubebuilder $GOPATH/bin
源码安装,速度不会比直接去 GitHub 上拉取成品要慢。
如果是跟着我的系列走到这里,默认是有 go 环境的。
export GO111MODULE=on
export GOPROXY=https://goproxy.io
kustomize 也是要安装一下的,搜一下 git 上的官网,直接下载成品也就几个 M,加个执行权限,然后放到 /usr/local/bin 目录下去。
创建project
mkdir $GOPATH/src/demo
cd $GOPATH/src/demo
kubebuilder init --domain demo.com --license apache2 --owner "xiong"
如果说第三步报错,就换到正常 home 下的个人目录里,再走一遍。
这里kubebuilder帮我们生成了一下模板文件夹,包括解决crd的rbac, cert, webhook的文件。暂时不用管他们,这时需要保证你的终端能访问k8s的测试集群,简单就是用kubectl cluster-info看看是否出错,如果不出错,就可以run起来main.go了
kubectl cluster-info
go run main.go
会有点久,不急,一两分钟吧。
然后可以看到终端输出log。
ok, 接下来我们就可以用kubebuilder帮我们创建一个我们想要的crd,我就叫这个crd为Object吧:
kubebuilder create api --group infra --version v1 --kind Object
执行上面的命令之后,kubebuilder就帮我们创建了两个文件api/v1/object_types.go和controllers/object_controller.go, 前者是这个crd需要定义哪些属性,而后者是对crd的reconsile的处理逻辑(也就是增删改crd的逻辑), 我们后面再讲这两个文件。
执行:
make install
把这个报错解决了咱再往下。我一直以为是教程里面的哪一步错了,导致我执行 make install 一直都报错,直到我啥也不动创建完 api 就 make,依旧报错的时候,我就知道事情不简单了。
我反手就打开了 Makefile,一顿操作猛如虎,然后解决了。
回过头我们再看一下api/v1/object_types.go,这里我在spec里面加一个Detail,在status里面加一个Created:
// ObjectSpec defines the desired state of Object
type ObjectSpec struct
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of Object. Edit Object_types.go to remove/update
Foo string `json:"foo,omitempty"`
Detail string `json:"detail,omitempty"`
// ObjectStatus defines the observed state of Object
type ObjectStatus struct
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Created bool `json:"created,omitempy"`
实际上kubebuilder就是帮我们生成Object的spec和status的模板,从注释就也可以看出来spec是我们期望的crd状态,而status就是观测到的状态。可以看到默认定义下面,kubebuilder会为我们生成对应的yaml文件在config/samples/infra_v1_object.yaml:
---
apiVersion: infra.demo.com/v1
kind: Object
metadata:
name: object-sample
spec:
# Add fields here
foo: bar
detail: "detail for demo"
在controllers/object_controller.go,也就是kubebuilder帮我们生成的Reconcile代码里面,我添加了打印Detail的信息,并且把Created改成true:
//此method在controllers/object_controller.go
func (r *ObjectReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error)
ctx := context.Background()
_ = r.Log.WithValues("object", req.NamespacedName)
// your logic here
// 1. Print Spec.Detail and Status.Created in log
obj := &infrav1.Object
if err := r.Get(ctx, req.NamespacedName, obj); err != nil
fmt.Errorf("couldn't find object:%s", req.String())
else
//打印Detail和Created
r.Log.V(1).Info("Successfully get detail", "Detail", obj.Spec.Detail)
r.Log.V(1).Info("", "Created", obj.Status.Created)
// 2. Change Created
if !obj.Status.Created
obj.Status.Created = true
r.Update(ctx, obj)
return ctrl.Result, nil
接着,再 run 一下那个 main.go 试试,如果日志打印直接截停了,你就知道新的问题出现了,解决掉就好。如果没有截停,那就没事了(我前面之所以反手就打开了 Makefile,就是在日志里面看到的。。。)
现在我们就可以用 config/samples/infra_v1_object.yaml 创建一个 Object:
kubectl create -f config/samples/infra_v1_object.yaml
再看看从k8s里面看到的这个Object的状态:
kubectl get object object-sample -o yaml
apiVersion: infra.demo.com/v1
kind: Object
metadata:
creationTimestamp: "2022-05-26T11:39:34Z"
generation: 2
name: object-sample
namespace: default
resourceVersion: "433782"
selfLink: /apis/infra.demo.com/v1/namespaces/default/objects/object-sample
uid: 3f4b368d-2988-11ea-a544-080027d6a71e
spec:
detail: detail for demo
foo: bar
status:
Created: true #此处是我们修改成true的状态
可以看到这个object-sample的status.Created已经被修改为true了
晕吧,我也晕呐,我还去看那本《云原生应用设计与开发》,然后我才意识到,要做这个开发,得对 k8s 的理解再上一层楼才够用。
然后我的预算嘛,这个月先把面铺开,下个月还要重头过一遍实践的。写这一篇,主要也是记录一下我是如何过了 make install 那一关的,不然二十天后实践又要给卡这里了。
最后,附上链接:https://book.kubebuilder.io/
不反感看英文的小伙伴可以去看看,挺好的。
以上是关于Kubebuilder 使用记录的主要内容,如果未能解决你的问题,请参考以下文章
深入解析 Kubebuilder:让编写 CRD 变得更简单
kubebuilder 实战之开发一个存储用户信息的 operator