Kubernetes Operator

在这里插入图片描述

从Deployment开始

在解释什么是Operator之前,让我们先从最熟悉的Deployment开始。
当我们写好一个Deployment的yaml之后,然后运行kubectl apply -f deployment.yaml,我们就可以看到pod们被创建出来。
然后我们手动删掉一个pod后,又会有一个新的pod被创建出来。
这一切都是怎样发生的?Deployment背后的工作原理是怎样的?
让我们以程序员的直觉来猜一猜,当我们执行完kubectl apply -f my_deployment.yaml之后,大概发生了以下事情:

  1. deployment.yaml的文件内容被kubectl发送到了kubernetes server。
  2. kubernetes server收到deployment.yaml之后,把它丢给一个专门处理Deployment对象的处理器(我们就叫它DeploymentController好了)。
  3. DeploymentController解析deployment.yaml,根据yaml中的的replica以及image之类的信息调用kubernetes创建pod的接口创建出符合期望的pod。
  4. 当我们执行kubectl delete pod xxx时,kubectl调用了kubernetes delete pod 的接口,kubernetes删掉pod的同时,把删除pod的事件也通知给DeploymentController。
  5. DeploymentController得知一个pod被删掉了,立马再创建一个出来,使得pod的数量和deployment.yaml中的replicas保持一致。
    好吧,就算是我们猜的差不多,那这些和Operator有啥关系呢?

当Kubernetes内置的组件不够用时

Deployment也好,StatefulSet、Service也好,当这些通用的组件有时候不够我们用时,怎么办?
比如,我需要这样一种功能:
和deployment相似,可以设置replicas,并创建出replicas个pod来,但是pod的名字必须以jin、mu、shui、huo、tu命名。
我们熟悉的Deployment、StatefulSet 等等都无法满足我们的要求。
于是我们想:要是能自己写一个类似Deployment的Controller就好了,自己定义好yaml的格式,然后kubectl执行,然后kubernetes server把yaml丢给这个Controller,然后Controller创建指定数量和名字的pod。
很幸运,Kubernetes确实支持我们设想的这种模式,还给这种模式起了个名字,叫做Operator。
来个简单的示意图:
在这里插入图片描述
可以看出来,Operator工作模式的关键在于两点:

  1. 可以自定义yaml的格式(资源文件),这种自定义的资源文件叫做Custom Resource Definition.
  2. Kubernetes Server可以把我们关心的资源(不只是我们自定义的资源)的事件通知给Controller,这种通知机制是Kubernetes内置的功能,感兴趣的话,可以搜索一下Kubernetes list-watch,网上有不少讲解的文章,这里不再赘述。

听起来原理挺简单,但还是无从下手,如果你打算开发一个Operator,那么下面的问题可能是你关心的。

你可能感兴趣的问题

怎么开发一个Operator

如果有自定义资源的需求,那么从步骤1开始,先得编写CRD,如果没有自定义资源的需求,只是操作Kubernetes原生资源的话,可以直接从3开始。

  1. 编写自己的Custom Resource Definition, 关于怎么编写CRD,具体可以看这里:https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
  2. 编写完CRD之后,运行kubectl apply -f CRD.yaml, 将CRD注册到Kubernetes server。
  3. 然后就可以编写自己的Opertor了。

按上面的介绍的Operator的工作原理,其实我们只需要编写一段代码watch我们关心的资源就行了,watch是Kubernetes的一个接口,一个Http接口,所以,所谓watch,其实就是想办法跟这个Http接口建立长连接,使得Kubernetes的Api Server能通过这个连接即使将事件通知给Operator。要建立长连接,很自然的想到WebSocket,Kubernetes的Operator们也确实是这样做的。
建立好长连接之后,剩下的和处理普通的Websocket消息就没什么区别了。

Watch的维护

既然Watch是一个长连接,那我们就得处理连接断开的情况,我们不能直接进行重连,需要先进行list,拿到当前的资源列表,然后再进行Watch,为什么需要先list再watch,一会儿再说。回到断线重连上来,其实这个动作不需要我们做,包括websocket的初始连接,这些事情,Kubernetes的客户端(SDK)都帮我们做好了,无论是Java的还是Go的SDK。

SDK

如上面所述,Kubernetes的API是Http的,那也就是说,任何语言都可以用来开发Operator,只要它能支持Http协议,极端一点,如果你不怕麻烦,用浏览器也可以折腾出来一个Kubernetes的Operator。
Java SDK 推荐fabric8io

ResourceVersion

回到上面提到的,为什么要先list再watch,是因为每个事件都有一个ResourceVersion,建立Watch连接时,传入ResourceVersion,Kubernetes便会以传入的ResourceVersion为起点,将之后发生的事件发送给Operator。那么怎么拿到这个初始ResourceVersion呢,很简单,list(或者get查询)拿到资源事件列表,解析出其中的ResourceVersion,然后再进行Watch。
因为Kubernetes不会长期存储所有事件,随着新的事件的产生,旧的事件会逐渐被删掉。如果我们watch了一个很少变更的资源,那么随着时间的推移,我们建立watch时传入的ResourceVersion对应的事件就会被Kubernetes删掉,这时对于Kubernets来说,已经找不到事件的起点了,对于这种老旧的watch,Kubernets会断开连接,此时,就需要我们重新进行一遍list-watch了。

部署Operator

部署在哪里

Operator开发完之后,理论上你可以部署在任何能到联通Kubernetes Api Server的地方。当前,还是推荐部署到Kubernetes集群中,以Deployment的方式,将replicas设置成1。 这样Operator即使挂了,Deployment也会为我们重新拉起来。
因为要通过Api Server操作Kubernetes的各种资源,出于安全考虑,需要进行认证和鉴权。

认证

认证是为了确定client的合法身份。
认证可以使用user,比如我们自己建立了一个Kubernetes集群,在~/.kube目录下会有一个config文件,里面就是用户的认证信息,默认应该是个Admin用户。当我们使用kubectl进行操作时,其实使用的就是这个config文件中的用户进行认证的。
当然,除了user,还可以使用ServiceAccount,ServiceAccount可以绑定到Pod上,然后从这个pod中发起的对于Api Server的调用,就使用的ServiceAccount的信息。

鉴权

认证是为了确定client的身份,鉴权是为了确定client可以操作的范围。
鉴权可以用RBAC(Role Based Access Control)来完成。

到实践中去

只是看的话,原理能明白,但是估计多一段时间就忘了,本文更多的是希望能帮到在开发Operator过程中遇到问题的同学。网上关于Operator的资料并不多,关于Java开发Operator更是几乎没有,希望对大家有所帮助,不至于像我当初一样,只能摸着石头过河,面对茫茫互联网,就是找不到一篇我想要的文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值