【云原生开发】namespace管理的后端开发设计与实现
✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:云原生开发
景天的主页:景天科技苑
文章目录
- namespace管理的后端开发设计与实现
- 1、设计理念
- 2、对增删改查的逻辑进行实现
- 3、创建命名空间
- 4、删除命名空间
- 5、查询命名空间列表
- 6、查询命名空间详情
- 7、更新namespace
namespace管理的后端开发设计与实现
1、设计理念
名称空间的增删改查,逻辑和集群的差不多,我们直接将集群的复制代码过来,改改
启动程序,通过postman先测试下接口
接口可以跑通
2、对增删改查的逻辑进行实现
如果对集群中的namespace进行管理,和上一章我们做的集群管理还是有区别的。
- 首先要知道对哪个集群中的哪个namespace进行管理,我们在管理集群的时候,我们需要接收clusterid的参数,管理namespace也同样需要clusterid
- kubeconfig的获取,之前我们把集群的信息都放到secret中,因此我们需要根据clusterid查出来是哪个secret,然后通过secret的data字段,得到kubeconfig,然后通过kubeconfig实例化出一个clientset。然后通过clientset就可以对集群的资源进行操作了。
- 但是,我们每次接收到clusterid的时候,都要经过第二步的整个流程,这个步骤是个需要重复使用的步骤,如果我们把kubeconfig存放在一个map[string]string变量中,{clusterId:xxx, name: xxxx, namespace:xxx}
我们拿到clusterid之后,直接就可以拿到kubeconfig文件了。 - 创建clientset
- 操作namespace
所以,经过上述分析,我们在config.go中创建个ClusterKubeconfig变量
我们希望程序启动时,就初始化该变量
//程序启动时,就初始化初始化ClusterKubeconfig
config.ClusterKubeconfig = make(map[string]string)
// 查询当前已经存在集群配置
listOptions := metav1.ListOptions{LabelSelector: config.ClusterConfigSecretLabelKey + "=" + config.ClusterConfigSecretLabelValue,
}
secretList, _ := config.InClusterClientSet.CoreV1().Secrets(config.MetadataNamespace).List(context.TODO(), listOptions)
for _, secret := range secretList.Items {// clusterIdclusterId := secret.Namekubeconfig := secret.Data["kubeconfig"] //得到的是字节,需要转换成字符串// clusterid作为key,kubeconfig作为value,存到config.ClusterKubeconfig之中config.ClusterKubeconfig[clusterId] = string(kubeconfig)
}
// 打印一个debug
//fmt.Println("当前集群配置:", config.ClusterKubeconfig)
logs.Debug(map[string]interface{}{"当前已存在的集群": config.ClusterKubeconfig}, "展示已存在的集群配置")
然后在添加,更新,删除集群时,都要针对这个变量做相应的操作
添加,更新集群
删除集群
3、创建命名空间
我们想象一下,如果想要前端操作创建一个命名空间,需要传递给后端什么数据呢?
是不是类似这样 {clusterId:xxx, name: xxxx, namespace:xxx…}
因此,我们需要创建个结构体来接收前端传来的数据,不管我们操作namespace、pod、deployment、daemonset等等,貌似都需要这些数据。
所以说,我们可以定义一个最基础的信息basicInfo来存放一些公用字段。这些公共信息可以在很多控制器中使用。
我们将这些公共信息与方法定义在controllers.go中
// Package controllers 控制器层,实现路由的逻辑处理
package controllersimport ("errors""github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/utils/logs""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd"
)// 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"`DeleteList []string `json:"deleteList"`
}// BasicInit 这个函数用来返回通用的clientset,集群信息和error
func BasicInit(c *gin.Context, item interface{}) (clientset *kubernetes.Clientset, basicInfo BasicInfo, err error) {basicInfo = BasicInfo{}basicInfo.Item = item// 首先获取请求的类型,根据不同的请求类型来使用不同的方式绑定数据requestMethod := c.Request.Methodif requestMethod == "GET" {err = c.ShouldBindQuery(&basicInfo)} else if requestMethod == "POST" {err = c.ShouldBindJSON(&basicInfo)} else {err = errors.New("不支持的请求类型")}logs.Debug(map[string]interface{}{"basicInfo": basicInfo}, "数据绑定结果")if err != nil {msg := "请求出错: " + err.Error()return nil, basicInfo, errors.New(msg)}if basicInfo.Namespace == "" {basicInfo.Namespace = "default"}// 获取kubeconfigkubeconfig := config.ClusterKubeconfig[basicInfo.ClusterId]restConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeconfig))if err != nil {msg := "解析kubeconfig错误: " + err.Error()return nil, basicInfo, errors.New(msg)}//创建客户端clientset, err = kubernetes.NewForConfig(restConfig)if err != nil {msg := "创建clientset失败: " + err.Error()return nil, basicInfo, errors.New(msg)}return clientset, basicInfo, nil
}
postman请求创建namespace
创建成功
4、删除命名空间
删除命名空间的危险系数是非常高的,要是在生产中,稍不留意删除了K8S系统自带的一些命名空间,将会造成无法挽回的损失。
因此我们删除namespace一定要谨慎,我们在开发时,也可以做一些规避,避免用户不小心删除掉关键命名空间。
我们做一些删除保护,当用户要删除kube-system或者krm时,禁止执行该操作,防止对集群造成不必要的风险。
删除namespace的时候,后端需要接收前端传来的clusterid和name。
delete.go
package namespaceimport ("context""github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)// Delete 删除命名空间
func Delete(c *gin.Context) {//删除namespace是非常危险的操作,一定要谨慎logs.Debug(nil, "删除namespace")clientset, basicInfo, err := controllers.BasicInit(c, nil)returnData := config.NewReturnData()if err != nil {returnData.Msg = err.Error()returnData.Status = 400c.JSON(200, returnData)return}//规避删除kube-system系统命名空间if basicInfo.Name == "kube-system" || basicInfo.Name == "krm" {returnData.Msg = "禁止删除系统命名空间kube-system,元数据命名空间krm"returnData.Status = 400c.JSON(200, returnData)logs.Error(nil, "系统命名空间kube-system不允许删除")return}//执行删除操作err = clientset.CoreV1().Namespaces().Delete(context.TODO(), basicInfo.Name, metav1.DeleteOptions{})if err != nil {msg := "删除Namespace失败: " + err.Error()returnData.Msg = msgreturnData.Status = 400logs.Error(map[string]interface{}{"message": msg}, basicInfo.Name+" 删除失败")} else {returnData.Msg = "删除成功"logs.Info(map[string]interface{}{"message": "namespace " + basicInfo.Name + " 删除成功"}, "删除成功")}c.JSON(200, returnData)
}
postman发送删除请求,删除成功
当用户要删除krm命名空间,提示用户不能删除
5、查询命名空间列表
查询命名空间列表,也是需要先拿到clientset
package namespaceimport ("context""github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""net/http"
)func List(c *gin.Context) {logs.Debug(nil, "列出namespace列表")clientset, _, err := controllers.BasicInit(c, nil)returnData := config.NewReturnData()if err != nil {returnData.Msg = err.Error()returnData.Status = 400c.JSON(http.StatusOK, returnData)return}//执行查询操作namespaceList, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})if err != nil {msg := "查询Namespace失败: " + err.Error()returnData.Msg = msgreturnData.Status = 400} else {returnData.Msg = "查询成功"returnData.Data["items"] = namespaceList.Items//如果只想查询命名空间的名字,可以如下循环获得//var nameList []string//for _, namespace := range namespaceList.Items {// namestr := namespace.Name// nameList = append(nameList, namestr)//}//returnData.Data["items"] = nameList}c.JSON(200, returnData)
}
查询的时候,需要传参clusterId,查询哪个集群的命名空间
6、查询命名空间详情
package namespaceimport ("context""github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""net/http"
)func Get(c *gin.Context) {logs.Debug(nil, "获取namespace详情")clientset, basicInfo, err := controllers.BasicInit(c, nil)returnData := config.NewReturnData()if err != nil {returnData.Msg = err.Error()returnData.Status = 400c.JSON(http.StatusOK, returnData)return}namespace, err := clientset.CoreV1().Namespaces().Get(context.TODO(), basicInfo.Name, metav1.GetOptions{})if err != nil {msg := "获取Namespace详情失败: " + err.Error()returnData.Msg = msgreturnData.Status = 400} else {returnData.Msg = "获取成功"returnData.Data["item"] = namespace}c.JSON(200, returnData)
}
postman请求,获取一个不存在的namespace
获取一个存在的namespace
7、更新namespace
更新命名空间一般是更新labels或者annotations,其他字段一般也不需要更新
后端接收一个namespace实例,做下update操作即可。
更新namespace和create namespace差不多
我们在BasicInfo中,定义一个变量Item用来接收前端传来的用于更新namespace的json串
这里为什么用空接口类型呢?因为后续我们更新deployment,pod,statefulset等都可以用到该字段,所以不能写死
package namespaceimport ("context""github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"corev1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)func Update(c *gin.Context) {logs.Debug(nil, "更新namespace")//先定义一个namespace变量var ns corev1.Namespace//创建clientset对象,将namespace指针传进去clientset, _, err := controllers.BasicInit(c, &ns)returnData := config.NewReturnData()if err != nil {returnData.Msg = err.Error()returnData.Status = 400c.JSON(200, returnData)return}//执行更新操作//更新直接用basicinfo中的Item是不行的,因为它是interface类型的,_, err = clientset.CoreV1().Namespaces().Update(context.TODO(), &ns, metav1.UpdateOptions{})if err != nil {msg := "更新Namespace失败: " + err.Error()returnData.Msg = msgreturnData.Status = 400} else {returnData.Msg = "更新成功"}c.JSON(200, returnData)}
发送更新的请求,将需要更新的namespace字段放入到item中传进去
添加一些标签,和annotations
"item": {"metadata": {"name":"jingtian","labels": {"kubernetes.io/metadata.name": "jingtian","ceshi":"ceshilabel"},"annotations":{"kubernetes.io/metadata.name": "true"}}
}
k8s集群查看更新成功
更新的时候,与其他几个在增删查方法不同的地方在于,需要将更新的资源传递给basicInfo,然后接收前端传参给item。再执行更新操作。
相关文章:

【云原生开发】namespace管理的后端开发设计与实现
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

威联通Docker Compose搭建NAS媒体库资源工具NAS Tools
文章目录 一、环境配置1-1 需要的配件1-2 环境安装及配置注意:获取PUID/PGID1-3 目录位置准备总结,这里我们要做5件事备注:Docker无法下载解决办法二、登录配件,进行配件连接和配置2-1 jackett设置2-2 qBittorrent设置!!!设置文件下载地址2-3 jellyfin设置2-4 NASTools设…...

【JAVA基础】MAVEN的安装及idea的引用说明
本篇文章主要讲解,maven的安装及集成在idea中进行构建项目的详细操作教程。 日期:2024年11月11日 作者:任聪聪 所需材料: 1、idea 2024版本及以上 2、maven 3.9.9安装包 3、一个空java springBoot项目,可以使用阿里云…...

【go从零单排】Rate Limiting限流
🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 中,速率限制(Rate Limiting)是一种控制…...
解析Eureka的架构
1. 引言 1.1 Eureka的定义与背景 Eureka是由Netflix开发的一个RESTful服务,用于服务发现。它是微服务架构中的一个核心组件,主要用于管理服务的注册和发现。Eureka允许服务提供者注册自己的服务信息,同时也允许服务消费者查询可用的服务&am…...

AI变现,做数字游民
在数字化时代,AI技术的迅猛发展不仅改变了各行各业的生产方式,还为普通人提供了前所未有的变现机会。本文将探讨如何利用AI技术实现变现,成为一名数字游民,享受自由职业带来的便利与乐趣。 一、AI技术的变现潜力 AI技术以其强大…...

linux-vlan
# VLAN # 1.topo # 2.创建命名空间 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns1-veth0 type veth peer name ns21-veth0 ip link add ns3-veth0 type veth peer name ns23-veth0 # 4.veth设备放入命名空间,启动接口 ip link set n…...
前端跨域~简述
前言 :绿蚁新醅酒,红泥小火炉 第一:前端跨域(粗谈概念) 1. 疑惑 当前端请求后端接口不通,浏览器控制台出现类似信息,则需要解决跨域 Access to XMLHttpRequest at ‘http://47.100.214.160:10…...

GIN:逼近WL-test的GNN架构
Introduction 在 图卷积网络GCN 中我们已经知道图神经网络在结点分类等任务上的作用,但GIN(图同构神经网络)给出了一个对于图嵌入(graph embedding)更强的公式。 GIN,图同构神经网络,致力于解…...

NIST密码学未来展望:Naughty Step 上的 SHA-1、3DES 和 SHA-224
1. 引言 NIST 几十年来一直致力于推动密码学标准的发展,2024年10月,其发布了Transitioning the Use of Cryptographic Algorithms and Key Lengths 草案: 概述了 SHA-1(为160位哈希算法) 将在不久的将来退役…...
go 集成gorm 数据库操作
一、什么是gorm GORM 是一个用于 Go 语言的 ORM(对象关系映射)库,它提供了一种简单而强大的方式来与数据库进行交互。GORM 支持多种数据库,包括 MySQL、PostgreSQL、SQLite、SQL Server 等,并且提供了丰富的功能&…...
进程 线程 和go协程的区别
进程和线程是操作系统中两个重要的执行单元,理解它们的区别对于编程和系统设计非常重要。以下是它们的主要区别: ### 进程(Process) 定义:进程是一个正在执行的程序的实例,具有独立的地址空间。 资源&…...

STM32获取SHT3X温湿度芯片数据
目录 一、概述 二、单次数据采集模式的测量 1、配置说明 2、代码实现方式 三、周期性数据采集模式的测量 1、配置说明 2、代码实现方式 四、完整代码下载链接 一、概述 SHT3X是Sensirion公司推出的一款高精度、完全校准的温湿度传感器,基于CMOSens技术。它提…...
卸载miniconda3
1. 找到miniconda目录,删除。 rm -rf miniconda3/ 2. 编辑bashrc sudo vim .bashrc setup路径改回anaconda3的,注释掉“>>> conda initialize >>>”和"<<< conda initialize <<<"之间的miniconda的语…...
游戏中的设计模式及杂项
概述 如果要做以下游戏功能会用到哪些设计模式。比如创建一个人物角色,这个角色可以装备刀,然后角色可以用刀砍怪物,造成流血。 对于这个游戏功能,可以使用以下设计模式: 工厂模式(Factory Pattern&#x…...

Docker网络和overlay的基础讲解
本人发现了两篇写的不错的文章:Docker网络 - docker network详解-CSDN博客,Docker 容器跨主机通信 overlay_docker overlay 网络-CSDN博客 因为这两篇文章中含有大量的例子,新手看起来毫不费力。于是我偷了个小懒,在本篇文章中没有…...
分布式数据库:深入探讨架构、挑战与未来趋势
引言 在数字化时代,数据已成为企业的核心资产。随着数据量的爆炸性增长和业务需求的多样化,传统的集中式数据库已难以满足现代应用对于高可用性、可扩展性和性能的需求。分布式数据库以其独特的优势,如数据的高可用性、容错性和可扩展性&…...

基于Springboot+Vue的仓库管理系统 (含源码数据库)
1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…...

基于立体连接与开源链动 2+1 模式的新商业路径探索
摘要:本文深入剖析了立体连接的内涵,包括其核心关键词、连接路径与主体,同时详细阐述了开源链动 2 1 模式、AI 智能名片和 S2B2C 商城小程序源码的特点与功能。在此基础上,深入研究这些要素的融合方式及其在商业实践中的应用&…...

开启鸿蒙开发之旅:核心组件及其各项属性介绍——布局容器组件
写在前面 组件的结构 rkTS通过装饰器 Component 和 Entry 装饰 struct 关键字声明的数据结构,构成一个自定义组件。 自定义组件中提供了一个 build 函数,开发者需在该函数内以链式调用的方式进行基本的 UI 描述 今天我们要学习的就是写在build 函数里的系…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...