关于云计算:kubebuilder实战之四operator需求说明和设计

55次阅读

共计 4448 个字符,预计需要花费 12 分钟才能阅读完成。

欢送拜访我的 GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,波及 Java、Docker、Kubernetes、DevOPS 等;

系列文章链接

  1. kubebuilder 实战之一:筹备工作
  2. kubebuilder 实战之二:首次体验 kubebuilder
  3. kubebuilder 实战之三:基础知识速览
  4. kubebuilder 实战之四:operator 需要阐明和设计
  5. kubebuilder 实战之五:operator 编码
  6. kubebuilder 实战之六:构建部署运行
  7. kubebuilder 实战之七:webhook
  8. kubebuilder 实战之八:知识点小记

本篇概览

  • 作为《kubebuilder 实战》系列的第四篇,经验了后面的充分准备,从本篇开始,咱们来开发一个有理论作用的 operator,该 operator 名为 <font color=”blue”>elasticweb</font>,既弹性 web 服务;
  • 这将是一次残缺的 operator 开发实战,设计、编码、部署等环节都会参加到,与《kubebuilder 实战之二:首次体验 kubebuilder》的不同之处在于,elasticweb 从 CRD 设计再到 controller 性能都有明确的业务含意,能执行业务逻辑,而《kubebuilder 实战之二》仅仅是一次开发流程体验;
  • 为了做好这个 operator,本篇不急于编码,而是认真的做好设计工作,咱们的 operator 有什么性能,解决了什么问题,有哪些核心内容,都将在本篇整顿分明,有了这样的筹备,能力在下一章写出符合要求的代码;
  • 接下来咱们先聊一些背景常识,以便更好的进入正题;

需要背景

  • QPS:Queries-per-second,既每秒查问率,就是说服务器在一秒的工夫内解决了多少个申请;
  • 背景:做过网站开发的同学对横向扩容应该都理解,简略的说,假如一个 tomcat 的 QPS 下限为 500,如果内部拜访的 QPS 达到了 600,为了保障整个网站服务质量,必须再启动一个同样的 tomcat 来独特摊派申请,如下图所示 (简略起见,假如咱们的后盾服务是无状态的,也就是说不依赖宿主机的 IP、本地磁盘之类):

  • 以上是横向扩容惯例做法,在 kubernetes 环境,如果内部申请超过了单个 pod 的解决极限,咱们能够减少 pod 数量来达到横向扩容的目标,如下图:

  • 以上就是背景信息,接下来咱们聊聊 elasticweb 这个 operator 的具体性能;

需要阐明

  • 为了说分明需要,这里虚构一个场景:小欣是个 java 开发者,就是下图这个妹子:

  • 当初小欣要将 springboot 利用部署到 kubernetes 上,她的现状和面临的问题如下:
  • springboot 利用已做成 docker 镜像;
  • 通过压测得出单个 pod 的 QPS 为 500;
  • 估算得出上线后的总 QPS 会在 800 左右;
  • 随着经营策略变动,QPS 还会有调整;
  • 总的来说,小欣手里只有三个数据:docker 镜像、单个 pod 的 QPS、总 QPS,她对 kubernetes 不理解,须要有个计划来帮她将服务部署好,并且在运行期间能撑持内部的高并发拜访;

以上就是小欣的需要了,咱们来小结一下:

  1. 咱们为小欣开发一个 operator(名为 <font color=”blue”>elasticweb</font>),对小欣来说,她只有将手里的三个参数(docker 镜像、单个 pod 的 QPS、总 QPS)通知 elasticweb 就完事儿了;
  2. elasticweb 在 kubernetes 创立 pod,至于 pod 数量当然是主动算进去的,要确保能满足 QPS 要求,以后面的状况为例,须要两个 pod 能力满足 800 的 QPS;
  3. 单个 pod 的 QPS 和总 QPS 都随时可能变动,一旦有变,elasticweb 也要主动调整 pod 数量,以确保服务质量;
  4. 为了确保服务能够被内部调用,咱们再顺便帮小欣创立好 service(她对 kubernetes 理解不多,这事儿咱们就棘手做了吧);

自保申明

  • 看过上述需要后,聪慧的您肯定会对我投来鄙视的眼光,其实 kubernetes 早就有现成的 QPS 调节计划了,例如批改 deployment 的正本数、单个 pod 纵向扩容、autoscale 等都能够,本次应用 operator 来实现仅仅是为了展现 operator 的开发过程,并不是说自定义 operator 是惟一的解决方案;
  • 所以,如果您感觉我这种用 operator 实现扩容的形式很 low,<font color=”red”> 请不要把我骂得太惨 </font>,我这也只是为了展现 operator 开发过程而已,况且咱这个 operator 也不是一无是处,用了这个 operator,您就不必关注 pod 数量了,只有聚焦单实例 QPS 和总 QPS 即可,这两个参数更贴近业务;
  • 为了不把事件弄简单,<font color=”blue”> 假如每个 pod 所需的 CPU 和内存是固定的 </font>,间接在 operator 代码中写死,其实您也能够本人改代码,改成能够在内部配置,就像镜像名称参数那样;
  • 把需要都交代分明了,接下来进入设计环节,先把 CRD 设计进去,这可是外围的数据结构;

CRD 设计之 Spec 局部

Spec 是用来保留用户的期望值的,也就是小欣手里的三个参数(docker 镜像、单个 pod 的 QPS、总 QPS),再加上端口号:

  1. image:业务服务对应的镜像
  2. port:service 占用的宿主机端口,内部申请通过此端口拜访 pod 的服务
  3. singlePodQPS:单个 pod 的 QPS 下限
  4. totalQPS:以后整个业务的总 QPS
  5. 对小欣来说,输出这四个参数就完事儿了;

CRD 设计之 Status 局部

  • Status 用来保留理论值,这里设计成只有一个字段 <font color=”blue”>realQPS</font>,示意以后整个 operator 理论能反对的 QPS,这样无论何时,只有小欣用 <font color=”blue”>kubectl describe</font> 命令就能晓得以后零碎实际上能反对多少 QPS;

CRD 源码

  • 把数据结构说明确的最好办法就是看代码:
package v1

import (
    "fmt"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "strconv"
)

// 冀望状态
type ElasticWebSpec struct {
    // 业务服务对应的镜像,包含名称:tag
    Image string `json:"image"`
    // service 占用的宿主机端口,内部申请通过此端口拜访 pod 的服务
    Port *int32 `json:"port"`

    // 单个 pod 的 QPS 下限
    SinglePodQPS *int32 `json:"singlePodQPS"`
    // 以后整个业务的总 QPS
    TotalQPS *int32 `json:"totalQPS"`
}

// 理论状态,该数据结构中的值都是业务代码计算出来的
type ElasticWebStatus struct {
    // 以后 kubernetes 中理论反对的总 QPS
    RealQPS *int32 `json:"realQPS"`
}

// +kubebuilder:object:root=true

// ElasticWeb is the Schema for the elasticwebs API
type ElasticWeb struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   ElasticWebSpec   `json:"spec,omitempty"`
    Status ElasticWebStatus `json:"status,omitempty"`
}

func (in *ElasticWeb) String() string {
    var realQPS string

    if nil == in.Status.RealQPS {realQPS = "nil"} else {realQPS = strconv.Itoa(int(*(in.Status.RealQPS)))
    }

    return fmt.Sprintf("Image [%s], Port [%d], SinglePodQPS [%d], TotalQPS [%d], RealQPS [%s]",
        in.Spec.Image,
        *(in.Spec.Port),
        *(in.Spec.SinglePodQPS),
        *(in.Spec.TotalQPS),
        realQPS)
}

// +kubebuilder:object:root=true

// ElasticWebList contains a list of ElasticWeb
type ElasticWebList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []ElasticWeb `json:"items"`}

func init() {SchemeBuilder.Register(&ElasticWeb{}, &ElasticWebList{})
}

业务逻辑设计

  • CRD 的实现代表外围数据结构曾经确定,接下来是业务逻辑的设计,次要是理分明 controller 的 Reconcile 办法外面做些啥,其实外围逻辑还是非常简单的:算出须要多少个 pod,而后通过更新 deployment 让 pod 数量达到要求,在此外围的根底上再把创立 deployment 和 service、更新 status 这些琐碎的事件做好,就完事儿了;
  • 这里将整个业务逻辑的流程图给进去如下所示,用于领导开发:

  • 至此,咱们实现了整个 elasticweb 的需要和设计,聪慧的您必定曾经胸有成竹,而且急不可待的想启动开发了,好的,下一篇咱们正式开始编码!

参考资料

  • 您可能会奇怪,小欣对 kubernetes 不理解,怎么会晓得 docker 镜像的制作,还有单个 pod 的 QPS 她是怎么测的呢?
  • 其实她是程序员欣宸的粉丝,曾经浏览过以下博客:
  • 《SpringBoot-2.3 镜像计划为什么要做多个 layer》
  • 《体验 SpringBoot(2.3) 利用制作 Docker 镜像 (官网计划)》
  • 《详解 SpringBoot(2.3) 利用制作 Docker 镜像 (官网计划)》
  • 《Kubernetes 下 web 服务的性能测试三部曲之一:筹备工作》
  • 《Kubernetes 下 web 服务的性能测试三部曲之二:纵向扩容》
  • 《Kubernetes 下 web 服务的性能测试三部曲之三:横向扩容》

你不孤独,欣宸原创一路相伴

  1. Java 系列
  2. Spring 系列
  3. Docker 系列
  4. kubernetes 系列
  5. 数据库 + 中间件系列
  6. DevOps 系列

欢送关注公众号:程序员欣宸

微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游 Java 世界 …
https://github.com/zq2599/blog_demos

正文完
 0