开发一个MutatingWebhook

news/2024/9/12 23:02:34/文章来源:https://www.cnblogs.com/leason001/p/18373222

介绍

Webhook就是一种HTTP回调,用于在某种情况下执行某些动作,Webhook不是K8S独有的,很多场景下都可以进行Webhook,比如在提交完代码后调用一个Webhook自动构建docker镜像

准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制。 可以定义两种类型的准入 Webhook, 即验证性质的准入 Webhook 和变更性质的准入 Webhook。 变更性质的准入 Webhook 会先被调用。它们可以修改发送到 API 服务器的对象以执行自定义的设置默认值操作。

在完成了所有对象修改并且 API 服务器也验证了所传入的对象之后, 验证性质的 Webhook 会被调用,并通过拒绝请求的方式来强制实施自定义的策略。

Admission Webhook使用较多的场景如下

  1. 在资源持久化到ETCD之前进行修改(Mutating Webhook),比如增加init Container或者sidecar Container
  2. 在资源持久化到ETCD之前进行校验(Validating Webhook),不满足条件的资源直接拒绝并给出相应信息

组成

  1. webhook 服务
  2. webhook 配置
  3. webhook 证书

创建核心组件Pod的Webhook

使用kubebuilder新建webhook项目

kubebuilder init --domain test.com --repo gitlab.qima-inc.com/test-operator
(base) (⎈ |kubernetes-admin@qa-u03:qa)➜  test-operator kubebuilder init --domain test.com --repo gitlab.qima-inc.com/test-operator
INFO Writing kustomize manifests for you to edit...
INFO Writing scaffold for you to edit...
INFO Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.17.2
INFO Update dependencies:
$ go mod tidy
go: go.mod file indicates go 1.21, but maximum version supported by tidy is 1.19
Error: failed to initialize project: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v4": exit status 1

因为我默认是是go1.19所以版本达不到要求,这里两种处理方式

  1. 指定 --plugins go/v3 --project-version 3
  2. 切换高版本golang 这里我切换了go1.22
(base) (⎈ |kubernetes-admin@qa-u03:qa)➜  test-operator kubebuilder init --domain test.com --repo gitlab.qima-inc.com/test-operator                                    
INFO Writing kustomize manifests for you to edit... 
INFO Writing scaffold for you to edit...          
INFO Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.17.2 
INFO Update dependencies:
$ go mod tidy           
Next: define a resource with:
$ kubebuilder create api

生成核心组件Pod的API

(base) (⎈ |kubernetes-admin@qa-u03:qa)➜  test-operator kubebuilder create api --group core --version v1 --kind Pod                                                    
INFO Create Resource [y/n]                        
n
INFO Create Controller [y/n]                      
n
INFO Writing kustomize manifests for you to edit... 
INFO Writing scaffold for you to edit...          
INFO Update dependencies:
$ go mod tidy        

这里有两个选项,创建资源和创建控制器
因为是内置资源Pod所以不需要创建资源,也不需要控制器
假如是自定义资源,需要创建资源,创建控制器

创建webhook

(base) (⎈ |kubernetes-admin@qa-u03:qa)➜  test-operator kubebuilder create webhook --group core --version v1 --kind Pod --defaulting --programmatic-validation
INFO Writing kustomize manifests for you to edit... 
ERRO Unable to find the target(s) #- path: patches/webhook/* to uncomment in the file config/crd/kustomization.yaml. 
ERRO Unable to find the target(s) #configurations:
#- kustomizeconfig.yaml to uncomment in the file config/crd/kustomization.yaml. 
INFO Writing scaffold for you to edit...          
INFO api/v1/pod_webhook.go                        
INFO api/v1/pod_webhook_test.go                   
INFO api/v1/webhook_suite_test.go                 
INFO Update dependencies:
$ go mod tidy           
INFO Running make:
$ make generate                
mkdir -p /Users/xxxx/test-operator/bin
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0
/Users/xxxx/test-operator/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
Next: implement your new Webhook and generate the manifests with:
$ make manifests

代码结构

.
├── Dockerfile
├── Makefile
├── PROJECT
├── README.md
├── api
│   └── v1
│       ├── pod_webhook.go
│       ├── pod_webhook_test.go
│       └── webhook_suite_test.go
├── bin
│   └── controller-gen-v0.14.0
├── cmd
│   └── main.go
├── config
│   ├── certmanager
│   │   ├── certificate.yaml
│   │   ├── kustomization.yaml
│   │   └── kustomizeconfig.yaml
│   ├── crd
│   │   └── patches
│   │       ├── cainjection_in_pods.yaml
│   │       └── webhook_in_pods.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   ├── manager_config_patch.yaml
│   │   ├── manager_webhook_patch.yaml
│   │   └── webhookcainjection_patch.yaml
│   ├── manager
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── role.yaml
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   └── webhook
│       ├── kustomization.yaml
│       ├── kustomizeconfig.yaml
│       ├── manifests.yaml
│       └── service.yaml
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
└── test
├── e2e
│   ├── e2e_suite_test.go
│   └── e2e_test.go
└── utils
└── utils.go

实现Webhook相关代码

因为只有Webhook,没有Controller 所以只需要实现Webhook相关代码即可,同时需要注释掉一些代码如:
Dockerfile中的

# COPY internal/controller/ internal/controller/

修改api/v1/xxx_suite_test.go
因为核心组件Pod的Webhook和一般的CRD的webhook不一样,此处生成的pod_webhook.go只有Default()这个function,因此,我们需要直接重写整个代码,最重要的是Handle()方法。

/*
Copyright 2024.Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/package v1import ("fmt""net/http""sigs.k8s.io/controller-runtime/pkg/client"logf "sigs.k8s.io/controller-runtime/pkg/log""sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)// log is for logging in this package.
var podlog = logf.Log.WithName("pod-resource")// 定义核心组件pod的webhook的主struct,类似于java的Class
type PodWebhookMutate struct {Client  client.Clientdecoder *admission.Decoder
}// +kubebuilder:webhook:path=/mutate-core-v1-pod,mutating=true,failurePolicy=fail,sideEffects=None,groups=core,resources=pods,verbs=create;update,versions=v1,name=mpod.kb.io,admissionReviewVersions=v1
func (a *PodWebhookMutate) Handle(ctx context.Context, req admission.Request) admission.Response {pod := &corev1.Pod{}err := a.decoder.Decode(req, pod)if err != nil {return admission.Errored(http.StatusBadRequest, err)}// TODO: 变量marshaledPod是一个Map,可以直接修改pod的一些属性marshaledPod, err := json.Marshal(pod)if err != nil {return admission.Errored(http.StatusInternalServerError, err)}// 打印fmt.Println("======================================================")fmt.Println(string(marshaledPod))return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod)
}func (a *PodWebhookMutate) InjectDecoder(d *admission.Decoder) error {a.decoder = dreturn nil
}

修改main.go文件:

if os.Getenv("ENABLE_WEBHOOKS") != "false" {//if err = (&corev1.Pod{}).SetupWebhookWithManager(mgr); err != nil {//	setupLog.Error(err, "unable to create webhook", "webhook", "Pod")//	os.Exit(1)//}mgr.GetWebhookServer().Register("/mutate-core-v1-pod", &webhook.Admission{Handler: &v1.PodWebhookMutate{Client: mgr.GetClient()}})
}

生成mainfests

make manifests generate

证书

手动签发证书

https://cuisongliu.github.io/2020/07/kubernetes/admission-webhook/

自动签发证书

webhook 服务启动时自动生成证书,授权证书

  1. 创建CA根证书以及服务的证书
  2. 将服务端、CA证书写入 k8s Secret,并且支持find or create
  3. 本地写入证书
  4. 获取MutatingWebhookConfiguration和ValidatingWebhookConfiguration将caCert写入webhook config中的ClientConfig.CABundle(这里有个问题是webhook需要提前创建,CABundle可以写个临时值,等webhook server 启动覆盖)

自动签发证书参考项目: https://github.com/koordinator-sh/koordinator/blob/main/pkg/webhook/util/controller/webhook_controller.go#L187

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/785277.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量图像识别的快速遍历技巧

本周我们来介绍一下如何快速地批量遍历图片列表找到图片对应的位置或对应关系,也很感谢Q群2群lincoln同学的分享,感兴趣的同学可以戳推文详细阅读~此文章来源于项目官方公众号:“AirtestProject” 版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途一、前…

系统缓存可以删吗,删除系统缓存的方法有哪些

系统缓存是可以清理的,这些文件在长时间积累后可能会占用大量的磁盘空间,甚至影响电脑的性能。以下是一些清理C盘缓存的方法: 一、清理系统缓存 1.使用磁盘清理工具: 打开“此电脑”,右键点击C盘,选择“属性”。在“常规”选项卡中,点击“磁盘清理”。 系统将扫描C盘上的…

关于电脑晚上自动关机的问题,系统win11

前提:由于工作需要,有时需电脑在晚上仍能保持运行,但目前突然出现电脑晚上自动关机的情况,故需寻找解决方法。 解决方案:原文地址 方法:本次主要采取原文中所提及的方法二。 step1:搜索设备管理器step2:找到系统设备step3:在系统设备中找到Intel(R) Management Engine…

Vue 之混入(mixin)详细介绍

混入(mixin)提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项(如data、methods、mounted、filters等等)。 一、注册使用 1、在main.js中全局配置import mixin from ./mixinsVue.mixin(mixin)2、组件中配置 在日常的开发中,我…

Goby 漏洞发布|泛微 e-cology v10 appThirdLogin 权限绕过漏洞【漏洞复现】

漏洞名称:泛微 e-cology v10 appThirdLogin 权限绕过漏洞 English Name:Weaver e-cology v10 appThirdLogin Permission Bypass Vulnerability CVSS core: 7.5 漏洞描述: 泛微新一代数字化运营构建平台E10,是基于原eteams平台之上全新研发,同时融合了原E9产品的所有功能,…

[VS Code扩展]写一个代码片段管理插件(二):功能实现

@目录创建和插入代码片段代码片段列表代码片段预览代码片段编辑自定义映射默认映射自动完成项目地址 创建和插入代码片段 VS Code扩展提供了数据存储,其中globalState是使用全局存储的Key-Value方式来保存用户状态,支持在不同计算机上保留某些用户状态,详情请参考官方文档 若…

DLAFormer:微软提出多任务统一的端到端文本分析Transformer模型 | ICDAR 2024

论文提出新颖的基于Transformer的端到端方法DLAFormer,在统一的模型中集成多个文档布局分析任务,包括图形页面对象检测、文本区域检测、逻辑角色分类和阅读顺序预测。为了实现这一目标,将各种DLA子任务视为关系预测问题并提出了统一标签空间方法,使得统一关系预测模块能够有…

MySql Excel 数据导入

mysql工具:Navicat Premium 15 导入文件:file_Excel.xlsx 1.选择要导入到的表,右键选择导入向导,先择excel, 2.选择导入的数据文件,勾选excel的表名 3.设置字段选项,通配符 4.选择目标表,也可以自动新建表 5.字段对应关系展示,不匹配的会跳过 6.导入模式,追加或覆盖,…

Debian12+openresty1.25.3.2 部署 markdown在线编辑器 Editor.md

openresty的下载安装步骤参考: http://openresty.org/cn/linux-packages.html#debian 安装完成后:conf目录: /etc/openresty -> /usr/local/openresty/nginx/conf/html目录: /usr/local/openresty/nginx/htmlEditor.md 部署: cd /usr/local/openresty/nginx/htmlgit cl…

SLAB:华为开源,通过线性注意力和PRepBN提升Transformer效率 | ICML 2024

论文提出了包括渐进重参数化批归一化和简化线性注意力在内的新策略,以获取高效的Transformer架构。在训练过程中逐步将LayerNorm替换为重参数化批归一化,以实现无损准确率,同时在推理阶段利用BatchNorm的高效优势。此外,论文设计了一种简化的线性注意力机制,其在计算成本较…

神了!两个开源的高仿外卖项目!

大家好,我是 Java陈序员。 今天,给大家推荐两个高仿的外卖项目!关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。高仿饿了么 项目简介 vue2-elm —— 一个基于 Vue2 + Vuex 构建具有 45 个页面的高仿饿了么项目,涉及注册、登…

C++ wsl2 ubuntu 环境配置

目前学习C++,配合Ubuntu进行开发, IDE 使用Clion,这里记录一下环境准备 WSL2 C++一般是用在linux下,这里就用Ubuntu进行开发,考虑到window系统,这里准备用wsl2. 虚拟化 wsl2 要系统支持虚拟化,一般在bios中进行处理,成功之后,任务管理器 --> 性能适用于Linux的Wind…