天天看点

kubebuilder实战之七:webhook

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,涉及java、docker、kubernetes、devops等;

本文是《kubebuilder实战》系列的第七篇,之前的文章咱们完成了一个operator的设计、开发、部署、验证过程,为了让整个过程保持简洁并且篇幅不膨胀,实战中刻意跳过了一个重要的知识点:webhook,如今是时候学习它了,这是个很重要的功能;

本篇由以下部分构成:

介绍webhook;

结合前面的elasticweb项目,设计一个使用webhook的场景;

准备工作

生成webhook

开发(配置)

开发(编码)

部署

验证defaulter(添加默认值)

验证validator(合法性校验)

熟悉java开发的读者大多知道过滤器(servlet filter),如下图,外部请求会先到达过滤器,做一些统一的操作,例如转码、校验,然后才由真正的业务逻辑处理请求:

kubebuilder实战之七:webhook

operator中的webhook,其作用与上述过滤器类似,外部对crd资源的变更,在controller处理之前都会交给webhook提前处理,流程如下图,该图来自《getting started with kubernetes | operator and operator framework》:

kubebuilder实战之七:webhook

再来看看webhook具体做了哪些事情,如下图,kubernetes官方博客明确指出webhook可以做两件事:修改(mutating)和验证(validating)

kubebuilder实战之七:webhook

kubebuilder为我们提供了生成webhook的基础文件和代码的工具,与制作api的工具类似,极大地简化了工作量,咱们只需聚焦业务实现即可;

基于kubebuilder制作的webhook和controller,如果是同一个资源,那么它们在同一个进程中;

为了让实战有意义,咱们为前面的elasticweb项目上增加需求,让webhook发挥实际作用;

如果用户忘记输入总qps,系统webhook负责设置默认值1300,操作如下图:

kubebuilder实战之七:webhook

为了保护系统,给单个pod的qps设置上限1000,如果外部输入的singlepodqps值超过1000,就创建资源对象失败,如下图所示:

kubebuilder实战之七:webhook

本篇实战中的完整源码可在github下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):

名称

链接

备注

项目主页

该项目在github上的主页

git仓库地址(https)

https://github.com/zq2599/blog_demos.git

该项目源码的仓库地址,https协议

git仓库地址(ssh)

[email protected]:zq2599/blog_demos.git

该项目源码的仓库地址,ssh协议

这个git项目中有多个文件夹,kubebuilder相关的应用在kubebuilder文件夹下,如下图红框所示:

kubebuilder实战之七:webhook

kubebuilder文件夹下有多个子文件夹,本篇对应的源码在elasticweb目录下,如下图红框所示:

kubebuilder实战之七:webhook

和controller类似,webhook既能在kubernetes环境中运行,也能在kubernetes环境之外运行;

如果webhook在kubernetes环境之外运行,是有些麻烦的,需要将证书放在所在环境,默认地址是:

为了省事儿,也为了更接近生产环境的用法,接下来的实战的做法是将webhook部署在kubernetes环境中

为了让webhook在kubernetes环境中运行,咱们要做一点准备工作安装cert manager,执行以下操作:

上述操作完成后会新建很多资源,如namespace、rbac、pod等,以pod为例如下:

操作完成后,准备工作结束,可以开始实战了;

进入elasticweb工程下,执行以下命令创建webhook:

上述命令执行完毕后,先去看看main.go文件,如下图红框1所示,自动增加了一段代码,作用是让webhook生效:

kubebuilder实战之七:webhook

上图红框2中的elasticweb_webhook.go就是新增文件,内容如下:

上述代码有两处需要注意,第一处和填写默认值有关,如下图:

kubebuilder实战之七:webhook

第二处和校验有关,如下图:

kubebuilder实战之七:webhook

咱们要实现的业务需求就是通过修改上述elasticweb_webhook.go的内容来实现,不过代码稍后再写,先把配置都改好;

打开文件config/default/kustomization.yaml,下图四个红框中的内容原本都被注释了,现在请将注释符号都删掉,使其生效:

kubebuilder实战之七:webhook

还是文件config/default/kustomization.yaml,节点vars下面的内容,原本全部被注释了,现在请全部放开,放开后的效果如下图:

kubebuilder实战之七:webhook

配置已经完成,可以编码了;

打开文件elasticweb_webhook.go

新增依赖:

找到default方法,改成如下内容,可见代码很简单,判断totalqps是否存在,若不存在就写入默认值,另外还加了两行日志:

接下来开发校验功能,咱们把校验功能封装成一个validateelasticweb方法,然后在新增和修改的时候各调用一次,如下,可见最终是调用apierrors.newinvalid生成错误实例的,而此方法接受的是多个错误,因此要为其准备切片做入参,当然了,如果是多个参数校验失败,可以都放入切片中:

再找到新增和修改资源对象时被调用的方法,在里面调用validateelasticweb:

编码完成,可见非常简单,接下来,咱们把以前实战遗留的东西清理一下,再开始新的部署和验证;

如果您是随着《kubebuilder实战》系列一路操作下来,此时系统上应该积攒了之前遗留的内容,可以通过以下步骤完成清理:

删除elasticweb资源对象:

删除controller

删除crd

现在万事俱备,可以部署webhook了;

部署crd

构建镜像并推送到仓库(我终于受够了hub.docker.com的龟速,改为阿里云镜像仓库):

部署集成了webhook功能的controller:

查看pod,确认启动成功:

修改文件config/samples/elasticweb_v1_elasticweb.yaml,修改后的内容如下,可见totalqps字段已经被注释掉了:

创建一个elasticweb资源对象:

此时单个pod的qps是500,如果webhook的代码生效的话,总qps就是1300,而对应的pod数应该是3个,接下来咱们看看是否符合预期;

先看elasticweb、deployment、pod等资源对象是否正常,如下所示,全部符合预期:

用kubectl describe命令查看elasticweb资源对象的详情,如下所示,totalqps字段被webhook设置为1300,realqps也计算正确:

再来看看controller的日志,其中的webhook部分是否符合预期,如下图红框所示,发现totalqps字段为空,就将设置为默认值,并且在检测的时候singlepodqps的值也没有超过1000:

kubebuilder实战之七:webhook

最后别忘了用浏览器验证web服务是否正常,我这里的完整地址是:http://192.168.50.75:30003/

至此,咱们完成了webhook的defaulter验证,接下来验证validator

接下来该验证webhook的参数校验功能了,先验证修改时的逻辑;

编辑文件config/samples/update_single_pod_qps.yaml,值如下:

用patch命令使之生效:

此时,控制台会输出错误信息:

再用kubectl describe命令查看elasticweb资源对象的详情,如下图红框,依然是500,可见webhook已经生效,阻止了错误的发生:

kubebuilder实战之七:webhook

再去看controller日志,如下图红框所示,和代码对应上了:

kubebuilder实战之七:webhook

接下来再试试webhook在新增时候的校验功能;

清理前面创建的elastic资源对象,执行命令:

修改文件,如下图红框所示,咱们将singlepodqps的值改为超过1000,看看webhook是否能检查到这个错误,并阻止资源对象的创建:

kubebuilder实战之七:webhook

执行以下命令开始创建elasticweb资源对象:

控制台提示以下信息,包含了咱们代码中写入的错误描述,证明elasticweb资源对象创建失败,证明webhook的validator功能已经生效:

不放心的话执行kubectl get命令检查一下,发现空空如也:

还要看下controller日志,如下图红框所示,符合预期:

kubebuilder实战之七:webhook

至此,operator的webhook的开发、部署、验证咱们就完成了,整个elasticweb也算是基本功能齐全,希望能为您的operator开发提供参考;

java系列

spring系列

docker系列

kubernetes系列

数据库+中间件系列

devops系列

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游java世界...