0


【云原生开发】k8s后台管理系统开发接口优化方案

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:云原生开发
景天的主页:景天科技苑

在这里插入图片描述

文章目录

接口优化

观察前面我们开发的代码,我们发现,每种资源都有类似的增删改查逻辑,如果我们把这些类似的逻辑,做成统一的接口,就不用每种资源都需要写重复的代码了。

该怎么设计呢?
我们基于命名空间的struct,写增删改查方法,然后让各类资源去调用
我们使用一个接口工具来优化代码
接口工具地址:https://github.com/littlefun91/kubeutils
在这里插入图片描述

功能使用方法
在这里插入图片描述

1. 首先先安装下kubeutils

go get -u github.com/littlefun91/kubeutils

在这里插入图片描述

2. 使用接口改造controllers.go

创建各种资源,都可以使用这里面通用的增删改查方法

// Package controllers 控制器层,实现路由的逻辑处理package controllers

import("errors""github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/config""jingtian/krm-backend/utils/logs""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd""net/http")// BasicInfo 定义全局的数据结构type BasicInfo struct{//使用form标签指定参数名,以便正确地绑定参数 get请求使用功能form标签
    ClusterId  string`json:"clusterId" form:"clusterId"`
    Namespace  string`json:"namespace" form:"namespace"`
    Name       string`json:"name" form:"name"`
    Item       interface{}`json:"item"`//用来接收前端传来的更新资源的json串
    DeleteList []string`json:"deleteList"`//用来接收前端传来的删除资源的json串,可以删一个,也可以删多个}type Info struct{
    BasicInfo
    ReturnData    config.ReturnData
    LabelSelector string`json:"labelSelector" form:"labelSelector"`
    FieldSelector string`json:"fieldSelector" form:"fieldSelector"`// 判断是否是强制删除
    Force bool`json:"force" form:"force"`}// NewInfo 定义一个函数,用来返回kubeconfigfuncNewInfo(c *gin.Context, info *Info, returnDataMsg string)(kubeconfig string){// 首先获取请求的类型
    requestMethod := c.Request.Method
    var err error// var returnData config.ReturnData
    info.ReturnData.Msg = returnDataMsg
    info.ReturnData.Status =200if requestMethod =="GET"{
        err = c.ShouldBindQuery(&info)}elseif requestMethod =="POST"{
        err = c.ShouldBindJSON(&info)}else{
        err = errors.New("不支持的请求类型")}
    logs.Debug(map[string]interface{}{"info": info},"数据绑定结果")if err !=nil{
        msg :="请求出错: "+ err.Error()
        info.ReturnData.Msg = msg
        info.ReturnData.Status =400
        logs.Error(nil, msg)
        c.JSON(http.StatusOK, info.ReturnData)return}// 获取kubeconfig
    kubeconfig = config.ClusterKubeconfig[info.ClusterId]//我们的接口工具只需要接收个kubeconfig文件就可以实现增删改查了return kubeconfig
}// Create Info中的增删改查方法,重写kubeutils中的增删改查方法func(i *Info)Create(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){//Create里面传参是namespace
    err := kubeUtilsInterface.Create(i.Namespace)if err !=nil{
        msg :="创建失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}
    c.JSON(200, i.ReturnData)}func(i *Info)Update(r *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
    err := kubeUtilsInterface.Update(i.Namespace)if err !=nil{
        msg :="更新失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}
    r.JSON(200, i.ReturnData)}func(i *Info)List(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
    items, err := kubeUtilsInterface.List(i.Namespace, i.LabelSelector, i.FieldSelector)if err !=nil{
        msg :="查询失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}else{
        i.ReturnData.Data =make(map[string]interface{})
        i.ReturnData.Data["items"]= items
    }
    c.JSON(200, i.ReturnData)}func(i *Info)Get(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
    item, err := kubeUtilsInterface.Get(i.Namespace, i.Name)if err !=nil{
        msg :="查询失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}else{
        i.ReturnData.Data =make(map[string]interface{})
        i.ReturnData.Data["item"]= item
    }
    c.JSON(200, i.ReturnData)}func(i *Info)Delete(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){var gracePeriodSeconds int64if i.Force {// 强制删除var s int64=0
        gracePeriodSeconds = s
    }
    err := kubeUtilsInterface.Delete(i.Namespace, i.Name,&gracePeriodSeconds)if err !=nil{
        msg :="删除失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}
    c.JSON(200, i.ReturnData)}func(i *Info)DeleteList(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){var gracePeriodSeconds int64if i.Force {// 强制删除var s int64=0
        gracePeriodSeconds = s
    }
    err := kubeUtilsInterface.DeleteList(i.Namespace, i.BasicInfo.DeleteList,&gracePeriodSeconds)if err !=nil{
        msg :="删除失败: "+ err.Error()
        i.ReturnData.Msg = msg
        i.ReturnData.Status =400
        logs.Error(nil, msg)}
    c.JSON(200, i.ReturnData)}// BasicInit 这个函数用来返回通用的clientset,集群信息和errorfuncBasicInit(c *gin.Context, item interface{})(clientset *kubernetes.Clientset, basicInfo BasicInfo, err error){
    basicInfo = BasicInfo{}//根据传参,来确定Item的类型,可以接收任意的资源
    basicInfo.Item = item
    // 首先获取请求的类型,根据不同的请求类型来使用不同的方式绑定数据
    requestMethod := c.Request.Method
    if requestMethod =="GET"{
        err = c.ShouldBindQuery(&basicInfo)}elseif requestMethod =="POST"{
        err = c.ShouldBindJSON(&basicInfo)}else{
        err = errors.New("不支持的请求类型")}
    logs.Debug(map[string]interface{}{"basicInfo": basicInfo},"数据绑定结果")if err !=nil{
        msg :="请求出错: "+ err.Error()returnnil, basicInfo, errors.New(msg)}//如果前端不传namespace,就用默认的命名空间if basicInfo.Namespace ==""{
        basicInfo.Namespace ="default"}// 获取kubeconfig
    kubeconfig := config.ClusterKubeconfig[basicInfo.ClusterId]
    restConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeconfig))if err !=nil{
        msg :="解析kubeconfig错误: "+ err.Error()returnnil, basicInfo, errors.New(msg)}//创建客户端
    clientset, err = kubernetes.NewForConfig(restConfig)if err !=nil{
        msg :="创建clientset失败: "+ err.Error()returnnil, basicInfo, errors.New(msg)}return clientset, basicInfo,nil}

在这里插入图片描述

3. 创建pod功能实现

pod/creaet.go

package pod

import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"
    corev1 "k8s.io/api/core/v1")// Create 创建namespace函数funcCreate(c *gin.Context){
    logs.Debug(nil,"创建pod")var pod corev1.Pod
    var info controllers.Info
    info.Item =&pod
    kubeconfig := controllers.NewInfo(c,&info,"pod创建成功")//改为接口形式的创建var kubeUtilser kubeutils.KubeUtilser
    instance := kubeutils.NewPod(kubeconfig,&pod)// 把实例复制给kubeUtilser
    kubeUtilser = instance
    // 使用kubeUtilser创建资源
    info.Create(c, kubeUtilser)}

在这里插入图片描述

执行创建请求

{
    "clusterId":"cluster01",
    "namespace":"jingtian","item":{"apiVersion":"v1","kind":"Pod","metadata":{"labels":{"app":"web6"},"name":"web6"},"spec":{"containers":[{"env":[{"name":"GIN_MODE","value":"release"},{"name":"LOG_LEVEL","value":"info"}],"image":"web:v4","imagePullPolicy":"IfNotPresent","name":"myweb","ports":[{"containerPort":8080,"protocol":"TCP"}]}]}}}

在这里插入图片描述

k8s集群查看,pod创建成功
在这里插入图片描述

4. 查询pod列表功能实现

package pod

import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")funcList(c *gin.Context){
    logs.Debug(nil,"列出pod列表")//声明结构体,用结构体的方法创建资源var info controllers.Info
    //newInfo里面传默认的returndata.msg
    kubeconfig := controllers.NewInfo(c,&info,"pod查询成功")var kubeUtilser kubeutils.KubeUtilser
    instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
    kubeUtilser = instance
    // 使用kubeUtilser查询资源
    info.List(c, kubeUtilser)}

查询成功
在这里插入图片描述

5. 获取pod详情功能实现

package pod

import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")funcGet(c *gin.Context){
    logs.Debug(nil,"获取pod详情")//声明结构体,用结构体的方法创建资源var info controllers.Info
    //newInfo里面传默认的returndata.msg
    kubeconfig := controllers.NewInfo(c,&info,"pod查询详情成功")var kubeUtilser kubeutils.KubeUtilser
    instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
    kubeUtilser = instance
    // 使用kubeUtilser查询资源
    info.Get(c, kubeUtilser)}

在这里插入图片描述

postman请求
在这里插入图片描述

6. 更新pod功能

一般,工作中我们也很少去更新pod。暂时不支持更新pod操作,响应给前端。

package pod

import("github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/utils/logs")funcUpdate(c *gin.Context){
    logs.Debug(nil,"更新pod")var returnData config.ReturnData
    returnData.Msg ="Pod暂不支持更新操作"
    returnData.Status =200
    c.JSON(200, returnData)}

在这里插入图片描述

7. 删除单个pod和批量删除pod功能

package pod

import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")// Delete 删除命名空间funcDelete(c *gin.Context){
    logs.Debug(nil,"删除单个pod")//声明结构体,用结构体的方法创建资源var info controllers.Info
    //newInfo里面传默认的returndata.msg
    kubeconfig := controllers.NewInfo(c,&info,"pod删除成功")var kubeUtilser kubeutils.KubeUtilser
    instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
    kubeUtilser = instance
    // 使用kubeUtilser查询资源
    info.Delete(c, kubeUtilser)}// DeleteList 批量删除funcDeleteList(c *gin.Context){
    logs.Debug(nil,"批量删除pod")//声明结构体,用结构体的方法创建资源var info controllers.Info
    //newInfo里面传默认的returndata.msg
    kubeconfig := controllers.NewInfo(c,&info,"pod批量删除成功")var kubeUtilser kubeutils.KubeUtilser
    instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
    kubeUtilser = instance
    // 使用kubeUtilser查询资源
    info.DeleteList(c, kubeUtilser)}

在这里插入图片描述

看下目前jingtian命名空间下的pod
在这里插入图片描述

postman执行删除单个pod
在这里插入图片描述

集群查看,删除单个pod成功
在这里插入图片描述

批量删除pod
在这里插入图片描述

集群查看,批量删除pod成功
在这里插入图片描述


本文转载自: https://blog.csdn.net/littlefun591/article/details/143803695
版权归原作者 景天科技苑 所有, 如有侵权,请联系我们删除。

“【云原生开发】k8s后台管理系统开发接口优化方案”的评论:

还没有评论