当前位置: 首页 > news >正文

k8s webhook实例,java springboot程序实现 对Pod创建请求添加边车容器 ,模拟istio实现日志文件清理

k8s webhook实例,java springboot程序实现 对Pod创建请求添加边车容器 ,模拟istio实现日志文件清理

大纲

  • 背景与原理
  • 实现流程
  • 开发部署my-docker-demo-sp-user服务模拟业务项目
  • 开发部署my-sidecar服务模拟边车程序
  • 开发部署服务my-docker-demo-k8s-operator 提供webhook功能
  • 创建MutatingWebhookConfiguration 动态准入配置
  • 测试边车注入效果

背景与原理

背景:

程序容器运行期间会大量产生日志文件,久而久之会消耗大量的硬盘空间(除非程序重新部署)
如果手动的去删除比较麻烦,如果把程序文件夹挂载到主机需要手动去配置磁盘卷挂载比较麻烦

原理:

由于业务程序镜像统一把日志写入到/data/service/logs, 所以在开发一个程序专门定时清理/data/service/logs文件夹下的文件,利用k8s webhook 把这个定时程序作为边车挂载到业务程序中
利用边车的方式还可以实现很多对业务增强的功能

涉及项目

  • my-docker-demo-sp-user 模拟业务项目
  • my-sidecar 模拟边车程序
  • my-docker-demo-k8s-operator 模拟webhook

实现流程

step1 开发部署my-docker-demo-sp-user服务模拟业务项目

my-docker-demo-sp-user是一个springboot项目主要代码如下

在这里插入图片描述

调用一个接口可以创建随机文件,模拟生成大量日志文件

my-docker-demo-sp-user 部署文件 deploy.yaml 如下

apiVersion: v1
kind: Namespace  #类型 指定为Namespace
metadata:name: my-sidecar-webhook  #namespace的名称 注意只能是英文小写和数字 labels: my-sidecar-inject: enabled #注意: 命名空间需要带有namespaceSelector中匹配的标签
---apiVersion: v1
kind: Pod
metadata: name: user-service-podnamespace: my-sidecar-webhook
spec: # 容器配置       containers: - image: registry.cn-hangzhou.aliyuncs.com/jimliu/user-service:v5imagePullPolicy: IfNotPresent  #Alwaysname: user-serviceports: - containerPort:  5588name: httpprotocol: TCP

可以看到这是一个极简的部署文件,创建一个命名空间和一个Pod, Pod只有一个容器user-service,执行部署文件deploy.yaml 可以看到只有一个容器在运行

在这里插入图片描述

测试发现功能正常并且Pod中只有一个容器

step2 开发部署my-sidecar服务模拟边车程序

my-sidecar (代码写在my-docker-demo-k8s-operator中打包的时候改了下jar包的名字)是一个springboot项目主要代码如下

在这里插入图片描述

有一个接口可以查看/data/service/logs文件夹下所有文件和一个接口和删除文件的接口
后续改造可以将删除功能做成定时任务执行

将my-sidecar服务打包制作成镜像推送到私库待用

在这里插入图片描述

step3 开发部署服务my-docker-demo-k8s-operator 提供webhook功能

本次实验webhook使用部署在k8s集群外部的方式 webhook可以参考(k8s Webhook 使用java springboot实现webhook 学习总结

   @RequestMapping("/mutate/v3")public String mutateV2(HttpServletRequest req ,HttpServletResponse rep) throws Exception {System.out.println("use mutate java k8s client lib [io.fabric8] @@@");InputStream in = req.getInputStream();/*** io.fabric8库 内置AdmissionReview对象* 使用 Serialization.unmarshal把输入流直接转化为对象*/AdmissionReview admissionReview = Serialization.unmarshal(in, AdmissionReview.class);System.out.println(Serialization.asJson(admissionReview));/*** 需要给原始的Pod 添加一个边车容器用于管理原始容器中生成的文件* Pod配置文件修改* 1 添加一个空临时存储卷* 2 添加一个边车容器并挂载存储卷* 3 修改原始容器添加挂载存储卷* *///1 准备一个空临时存储卷对象//Volume与EmptyDirVolumeSource对象是 io.fabric8库 内置对象Volume v = new Volume();v.setName("data");EmptyDirVolumeSource emptyDir = new EmptyDirVolumeSource();v.setEmptyDir(emptyDir);//2 准备一个边车容器并挂载存储卷对象//Container对象是 io.fabric8库 内置对象Container sidecar = new Container();sidecar.setImage("registry.cn-hangzhou.aliyuncs.com/jimliu/sidecar:v1"); //边车程序镜像sidecar.setImagePullPolicy("IfNotPresent");sidecar.setName("sidecar");ContainerPort cp = new ContainerPort();cp.setContainerPort(5533);cp.setName("http");cp.setProtocol("TCP");sidecar.setPorts(Arrays.asList(cp));//VolumeMount对象是 io.fabric8库 内置对象VolumeMount vm = new VolumeMount();vm.setMountPath("/data/service/logs"); //将容器内部的/data/service/logs 与 data 卷挂载vm.setName("data");sidecar.setVolumeMounts(Arrays.asList(vm));//3 修改原始容器添加挂载存储卷//Pod对象是 io.fabric8库 内置对象Pod pod = (Pod) admissionReview.getRequest().getObject();List<Container> containers =  pod.getSpec().getContainers();for(Container container : containers) {VolumeMount vmt = new VolumeMount();vmt.setMountPath("/data/service/logs");vmt.setName("data");container.getVolumeMounts().add(vmt);}//将边车容器加入containers.add(sidecar);/*** 开始制作jsonpatch* 对Pod的修改需要利用jsonpatch 提供的add 和 replace* JsonPatchBean为自定义的一个对象*/List<JsonPatchBean> patchs = new ArrayList<>();//添加卷patchs.add(new JsonPatchBean("add","/spec/volumes",Arrays.asList(v)));//替换容器加入边车容器patchs.add(new JsonPatchBean("replace","/spec/containers",containers));/*** patchs转换为字符串* 需要把字符串转换为base64编码*/String patchStr = JSON.toJSONString(patchs);System.out.println(patchStr);Base64 base64= new Base64();  String patch = new String(base64.encode(patchStr.getBytes()));/*** uid,从发送到 Webhook 的 request.uid 中复制而来*/String uid = admissionReview.getRequest().getUid();/*** io.fabric8库 内置AdmissionResponse对象*/AdmissionResponse response = new AdmissionResponse();response.setAllowed(true);response.setUid(uid);response.setPatch(patch);response.setPatchType("JSONPatch");/*** 填充Response*/admissionReview.setResponse(response);return Serialization.asJson(admissionReview);}/*** 封装一个JsonPatch 操作对象* @author liuyijiang*/public static class JsonPatchBean {private String op;private String path;private Object value;public JsonPatchBean(String op,String path,Object value) {this.op = op;this.path = path;this.value = value;}... get set 省略}

这里 my-docker-demo-k8s-operator 项目需要使用https方式访问

如何配置证书与域名可参考 k8s Webhook 使用java springboot实现webhook 学习总结

这里默认相关的证书配置,k8s master节点的域名映射都完成,本地eclipse启动my-docker-demo-k8s-operator 成功

在这里插入图片描述

step4 创建MutatingWebhookConfiguration 动态准入配置

MutatingWebhookConfiguration 内容如下

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata: name: my-test-webhook1 #创建MutatingWebhookConfiguration 的名称
webhooks:
- admissionReviewVersions:  #指定可接受的 AdmissionReview 对象版本 这里支持v1beta1 v1- v1beta1- v1clientConfig:# CA根证书内容caBundle: LS0tLS1CRUdJTiBDR...略# 只支持https请求url: "https://webhooktest.liuyijiang.com/mutate/v3"  #webhook web服务访问的地址failurePolicy: FailmatchPolicy: Exact #精确匹配name: webhooktest.liuyijiang.com #名称随意但是必须是域名格式namespaceSelector:matchLabels:my-sidecar-inject: enabled  #必须匹配标签为my-sidecar-inject=enabled的命名空间内的资源才会被拦截rules:- apiGroups:- ""apiVersions: #匹配的版本- v1operations:  #拦截CREATE操作- CREATEresources:  #拦截执行类型是pod- podsscope: '*'  #所有命名空间sideEffects: None  #配置是否有副作用,None表示调用 Webhook 没有副作用timeoutSeconds: 30 #请求超时时间

caBundle根证书内容生成 可参考 k8s Webhook 使用java springboot实现webhook 学习总结

部署MutatingWebhookConfiguration

在这里插入图片描述

step5 测试边车注入效果

再次部署my-docker-demo-sp-user项目 此时 我本机上已接收到k8s webhook请求

在这里插入图片描述

查看部署后的Pod 发现出现两个容器,边车容器与业务容器实现了共享存储空间,并可以清除日志文件,后续只需改造为定时任务即可

在这里插入图片描述

kubectl -n my-sidecar-webhook get pods -o json

在这里插入图片描述

相关文章:

k8s webhook实例,java springboot程序实现 对Pod创建请求添加边车容器 ,模拟istio实现日志文件清理

k8s webhook实例&#xff0c;java springboot程序实现 对Pod创建请求添加边车容器 &#xff0c;模拟istio实现日志文件清理 大纲 背景与原理实现流程开发部署my-docker-demo-sp-user服务模拟业务项目开发部署my-sidecar服务模拟边车程序开发部署服务my-docker-demo-k8s-opera…...

关于electron的问题汇总

1. electron-builder打包慢出错的问题 由于网络原因&#xff0c;在进行builder打包时&#xff0c;可能会等很长时间&#xff0c;直到最后还是以失败告终。 如果是第一次进行builder打包&#xff0c;会去下载winCodeSign、nsis、nsis-resources&#xff0c;往往都是第一个就卡住…...

ps 给衣服换色

可以通过色相饱和度来改变颜色 但如果要加强对比 可以通过色阶或曲线来调整 针对整体 调整图层-色相/饱和度 着色 给整个画面上色 选区-遮罩-取出来 然后调整图层-色相/饱和度也可以 或者以有图层-色相饱和度后 选区 按ctrli使其遮罩 同时按alt鼠标左键单机 ctrli反相…...

AI人工智能未来在哪里?2023年新兴产业人工智能有哪些就业前景?

AI人工智能未来在哪里&#xff1f;2023年新兴产业人工智能有哪些就业前景&#xff1f; 随着科技的不断发展&#xff0c;人工智能技术也在不断地进步。在数字化时代&#xff0c;人工智能技术已经渗透到了我们生活的各个方面。2023年为止中国产业80%已经实现半自动化&#xff0c;…...

组件间通信案例练习

1.实现父传子 App.vue <template><div class"app"><tab-control :titles["衣服","鞋子","裤子"]></tab-control><tab-control :titles["流行","最新","优选","数码&q…...

【matlab】机器人工具箱快速上手-正运动学仿真(代码直接复制可用)

安装好机器人工具箱&#xff0c;代码复制可用&#xff0c;按需修改参数 1.建模 %%%%%%%%SCARA机器人仿真模型 l[0.457 0.325]; L(1) Link(d,0,a,l(1),alpha,0,standard,qlim,[-130 130]*pi/180);%连杆1 L(2)Link(d,0,a,l(2),alpha,pi,standard,qlim,[-145 145]*pi/180);%连杆…...

论文解读|PF-Net:用于 3D 点云补全的点分形网络

原创 | 文 BFT机器人 01 背景 从激光雷达等设备中获取的点云往往有所缺失&#xff08;反光、遮挡等&#xff09;&#xff0c;这给点云的后续处理带来了一定的困难&#xff0c;也凸显出点云补全作为点云预处理方法的重要性。 点云补全&#xff08;Point Cloud Completion&#x…...

网络安全(零基础)自学

一、网络安全基础知识 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知识&#xff0c;可以帮助您更好地理解网络安全的概念和技术。 2.网络基础知识 了解了网络的结构、协议、服务和安全问题&#xff0c;可以帮助您更好地解决网络安全的原理和技术…...

Spring Security 身份验证的基本类/架构

目录 1、SecurityContextHolder 核心类 2、SecurityContext 接口 3、Authentication 用户认证信息接口 4、GrantedAuthority 拥有权限接口 5、AuthenticationManager 身份认证管理器接口 6、ProviderManager 身份认证管理器的实现 7、AuthenticationProvider 特定类型的…...

市值超300亿美金,SaaS独角兽Veeva如何讲好中国故事?

“全球前50的药企&#xff0c;有47家正在使用Veeva。” 提到Veeva Systems&#xff08;以下简称“Veeva”&#xff09;&#xff0c;可能很多人并不熟悉。但是生命科学业内人士都知道&#xff0c;Veeva是全球头部的行业SaaS服务商。以“为生命科学行业构建行业云”为使命&#x…...

编译内联导致内存泄漏的问题定位修复

作者&#xff1a;0x264 问题 线上长时间存在一个跟异步 inflate 相关的量级较大的内存泄漏&#xff0c;如下所示&#xff1a; 第一次分析 从内存泄漏粗略看有几个信息&#xff1a; 被泄漏的Activity有很多&#xff0c;所以可能跟某个具体业务的关系不大引用链特别短&#xf…...

基于WebSocket实现的后台服务

基于WebSocket实现的后台服务&#xff0c;用于接收客户端的心跳消息&#xff0c;并根据心跳消息来维护客户端连接。 具体实现中&#xff0c;服务启动后会创建一个HttpListener对象&#xff0c;用于监听客户端的WebSocket连接请求。当客户端连接成功后&#xff0c;服务会为每个…...

Go语言中的结构体详解

关于 Golang 结构体 Golang 中没有“类”的概念&#xff0c;Golang 中的结构体和其他语言中的类有点相似。和其他面向对 象语言中的类相比&#xff0c;Golang 中的结构体具有更高的扩展性和灵活性。 Golang 中的基础数据类型可以表示一些事物的基本属性&#xff0c;但是当我们…...

pytest自动化测试指定执行测试用例

1、在控制台执行 打开cmd,进入项目目录 指定执行某个模块 pytest testcases\Logistics\Platform\CarSource\test_CarSourceList.py 指定执行某个目录及其子目录的所有测试文件 pytest testcases\Logistics\Platform\CarSource 指定执行某个模块的某个类的某个测试用例 pyte…...

英伟达 H100 vs. 苹果M2,大模型训练,哪款性价比更高?

M1芯片 | Uitra | AMD | A100 M2芯片 | ARM | A800 | H100 关键词&#xff1a;M2芯片&#xff1b;Ultra&#xff1b;M1芯片&#xff1b;UltraFusion&#xff1b;ULTRAMAN&#xff1b;RTX4090、A800;A100&#xff1b;H100&#xff1b;LLAMA、LM、AIGC、CHATGLM、LLVM、LLM、LLM…...

var、let和const的区别

先简单了解一下 var声明的变量会挂载在window上&#xff0c;而let和const声明的变量不会&#xff1a; var a 100; console.log(a,window.a); // 100 100let b 10; console.log(b,window.b); // 10 undefinedconst c 1; console.log(c,window.c); // 1 undefined v…...

(css)AI智能问答页面布局

(css)AI智能问答页面布局 效果&#xff1a; html <!-- AI框 --><div class"chat-top"><div class"chat-main" ref"chatList"><div v-if"!chatList.length" class"no-message"><span>欢迎使…...

【Pytorch学习】pytorch中的isinstance() 函数

描述 isinstance() 函数来判断一个对象是否是一个已知的类型&#xff0c;类似 type()。 isinstance() 与 type() 区别&#xff1a; type() 不会认为子类是一种父类类型&#xff0c;不考虑继承关系。 isinstance() 会认为子类是一种父类类型&#xff0c;考虑继承关系。 如果要判…...

(树) 剑指 Offer 07. 重建二叉树 ——【Leetcode每日一题】

❓剑指 Offer 07. 重建二叉树 难度&#xff1a;中等 输入某二叉树的 前序遍历 和 中序遍历 的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,20,15,7], inorder [9,3,15,20,7] …...

Gitlab 合并分支与请求合并

合并分支 方式一&#xff1a;图形界面 使用 GitGUI&#xff0c;右键菜单“GitExt Browse” - 菜单“命令” - 合并分支 方式二&#xff1a;命令行 在项目根目录下打开控制台&#xff0c;注意是本地 dev 与远程 master 的合并 // 1.查看本地分支&#xff0c;确认当前分支是否…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...