kubebuilder实战之四:operator需求说明和设计

2021-06-24  本文已影响0人  程序员欣宸

欢迎访问我的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实战之八:知识点小记

本篇概览

需求背景

在这里插入图片描述 在这里插入图片描述

需求说明

在这里插入图片描述
  1. springboot应用已做成docker镜像;
  2. 通过压测得出单个pod的QPS为500;
  3. 估算得出上线后的总QPS会在800左右;
  4. 随着运营策略变化,QPS还会有调整;
  5. 总的来说,小欣手里只有三个数据: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了解不多,这事儿咱们就顺手做了吧);

自保声明

CRD设计之Spec部分

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

  1. image:业务服务对应的镜像
  2. port:service占用的宿主机端口,外部请求通过此端口访问pod的服务
  3. singlePodQPS:单个pod的QPS上限
  4. totalQPS:当前整个业务的总QPS

CRD设计之Status部分

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{})
}

业务逻辑设计

在这里插入图片描述

参考资料

  1. 《SpringBoot-2.3镜像方案为什么要做多个layer》
  2. 《体验SpringBoot(2.3)应用制作Docker镜像(官方方案)》
  3. 《详解SpringBoot(2.3)应用制作Docker镜像(官方方案)》
  4. 《Kubernetes下web服务的性能测试三部曲之一:准备工作》
  5. 《Kubernetes下web服务的性能测试三部曲之二:纵向扩容》
  6. 《Kubernetes下web服务的性能测试三部曲之三:横向扩容》

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

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

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

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

https://github.com/zq2599/blog_demos

上一篇下一篇

猜你喜欢

热点阅读