k8s 基于MutatingWebhookConfiguration实现node超卖和sidecar注入

这篇具有很好参考价值的文章主要介绍了k8s 基于MutatingWebhookConfiguration实现node超卖和sidecar注入。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

k8s 基于MutatingWebhookConfiguration实现node超卖和sidecar注入

源码在:https://github.com/Seaiii/MutatingWebhook我写了几个脚本,可以直接运行。

一、MutatingWebhookConfiguration原理

MutatingWebhookConfiguration 是 Kubernetes 中的一种资源对象,用于配置 Mutating Admission Webhook。Mutating Admission Webhook 是一种 Kubernetes 的扩展机制,用于在对象被持久化到 etcd 存储之前,对其进行动态修改或补充。

MutatingWebhookConfiguration 定义了一个或多个 Mutating Admission Webhook 的配置信息,包括 Webhook 的 URL、服务名称、路径等。当 Kubernetes API Server 接收到创建、更新或删除对象的请求时,它将触发适用于该对象类型的 Mutating Admission Webhook。

Mutating Admission Webhook 在对象持久化之前,对对象进行拦截并进行修改或补充。它可以在不改变原始请求的情况下,通过返回修改后的对象副本来实现动态的对象转换。这使得用户能够通过自定义的逻辑对 Kubernetes 对象进行自动化的修改,例如自动注入额外的标签、注解、容器、卷等。

MutatingWebhookConfiguration 的工作原理如下:

创建 MutatingWebhookConfiguration 对象并将其提交到 Kubernetes 集群。这个对象定义了一个或多个 Mutating Admission Webhook 的配置。

Kubernetes API Server 在接收到创建、更新或删除对象的请求时,会检查适用于该对象类型的 Mutating Admission Webhook 配置。

Kubernetes API Server 将请求发送到 Mutating Admission Webhook 的 Webhook URL。

Mutating Admission Webhook 接收到请求后,根据预定义的逻辑对请求中的对象进行修改或补充,并生成修改后的对象副本。

Mutating Admission Webhook 将修改后的对象副本作为响应返回给 Kubernetes API Server。

Kubernetes API Server 使用修改后的对象副本进行后续的持久化操作。

MutatingWebhookConfiguration 和 Mutating Admission Webhook 提供了一种可扩展的方式,允许用户根据自定义的业务需求对 Kubernetes 对象进行自动化修改。这在实践中被广泛应用于诸如自动注入 sidecar、自动配置密钥等场景中。
k8s 资源超卖,kubernetes,kubernetes,云原生,go,超卖

二、超卖/sidecar思路

1.场景
超卖的场景可以很容易避免。只要设置了resource最低和适当的limits,就可以避免超卖。但是有种场景就是用户不知道这个值,本来1M内存使用量,但是设置了resource为3M。这样就导致pod占用了3M的内存,然而有2M是闲置状态。这时候就可以使用动态超卖来把那浪费的2M内存使用出来
2.思路
节点Node的Status种有两个字段,分别是Allocatable(可分配)和Capacity(总量)结构体。实现资源超卖的关键在于动态修改节点Node对象的allocatable字段值。如果使用clinet-go动态的修改这个字段,是无法实现的。因为修改后只是短暂的,Node资源对象比较特殊,计算节点会不断给ApiServer发送心跳(默认每隔10s发一次),将带有Status字段的真实信息发送给ApiServer,并更新到etcd中。也就是无论你怎么通过patch/put方法去修改Node的Status字段,计算节点都会定时通过发送心跳将真实的Status数据覆盖你修改的数据,也就是说我们无法通过直接调用RESTful API修改Node对象中的Status数据。所以这时候需要引入MutatingWebhookConfiguration资源对象,在apiserver发送给etcd之前,会先发送给MutatingWebhookConfiguration。然后通过我们注册的回调函数,来修改status,在发送给etcd,骗过etcd。

三、实现MutatingWebhookConfiguration

可以简单介绍下MutatingWebhookConfiguration流程步骤
流程步骤介绍:我们需要创建service、MutatingWebhookConfiguration、deployment来实现流程。当apiserver发起心跳后,在MutatingWebhookConfiguration中rule注册的规则中会触发。然后通过MutatingWebhookConfiguration中的service触发到我们的service,通过service转发到deployment的pod,然后实现回调。

这三个yaml在github中都有存在。

1.需要修改api-server的配置。如果是kubeadm安装的,可以如下修改

vi /etc/kubernetes/manifests/kube-apiserver.yaml 

修改以下配置开启MutatingAdmissionWebhook。
- --enable-admission-plugins=NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook

2.配置签名证书
github中的cfssl.sh已经帮助生产证书(要修改以下你的apiserver的ca位置)

#生成key,用k8s的ca证书进行签名,注意:-ca和-ca-key=的目录是你k8s的master主机存放CA文件的位置

cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -hostname=webhook.default.svc -profile=server server-csr.json | cfssljson -bare server

生成证书后需要生成secret资源,后续deployment需要挂载这个secret

kubectl create secret tls admission-registry-tls  --key=server-key.pem --cert=server.pem

3.生成必要的三个yaml
github中的statr.sh脚本中可以快速运行pod并触发node更新操作。(要修改以下你本机的deployment位置)
MutatingWebhookConfiguration.yaml

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: demo-webhook
webhooks:
  - sideEffects: None
    admissionReviewVersions:
      - v1
      - v1beta1
    name: webhook.default.svc
    clientConfig:
      service:
        name: webhook#你的server服务的名字
        namespace: default
        path: "/webhook"
      caBundle: #这个是你的k8s集群的的ca证书base64加密后的值。可以使用“kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}'”获取
    rules:
      - operations: [ "UPDATE" ]
        apiGroups: [ "*" ]
        apiVersions: [ "v1" ]
        resources: [ "nodes/status"]

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webhook-example-deployment
  labels:
    app: webhook-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webhook-example
  template:
    metadata:
      labels:
        app: webhook-example
    spec:
      nodeName: k8s-master
      containers:
        - name: webhook-example
          image: webhook-example:20230517-144113
          command: [ "/node" ]
          ports:
            - containerPort: 8443
              name: webhook-api
          args:
            - -v=4
            - -log_dir=log -alsologtostderr
          volumeMounts:
            - name: webhook-certs
              mountPath: /etc/webhook/certs
              readOnly: true
            - name: kubeconfig
              mountPath: /etc/
      volumes:
        - name: webhook-certs #这个是上面生成的secret
          secret:
            secretName: admission-registry-tls
        - name: kubeconfig
          hostPath:
              path: /root/.kube/ #这个要改成你本地的kubeconfig的位置,用于client-go的客户端连接
              type: Directory


service.yaml

apiVersion: v1
kind: Service
metadata:
  name: webhook
  labels:
    app: admission-webhook-example
spec:
  ports:
    - port: 443
      targetPort: webhook-api
  selector:
    app: webhook-example

执行github中的start.sh可以一步生成,或者你可以根据里面的步骤手动生成,我都做了注释。
**注:**我们需要获得node的实际使用量,所以需要Metrics,需要跑起来这个pod,后续的代码中才可以使用这个Metrics客户端。百度下载components.yaml执行即可了(可以百度获取很多)。
k8s 资源超卖,kubernetes,kubernetes,云原生,go,超卖

四、代码实现

1.代码的逻辑很简单,创建server接受https请求,需要tls校验证书。

cert, err := tls.LoadX509KeyPair("/etc/webhook/certs/tls.crt", "/etc/webhook/certs/tls.key")
	if err != nil {
		glog.Errorf("get cert fail.err is :", err)
		panic(err)
	}

	// Creating a TLS Configuration
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}
	// Create an HTTP server
	server := &http.Server{
		Addr:      ":8443",
		TLSConfig: tlsConfig,
	}

	// start services
	http.Handle("/webhook", New(&applyNode{}))
	client.NewClientK8s()
	if err := server.ListenAndServeTLS("", ""); err != nil {
		glog.Errorf("server start fail,err is:", err)
		panic(err)
	}

2.证书校验成功后,将收到apiserver发过来的消息,对接受消息进行校验,并拿到Node.Status.Capacity的值和MetricsApi的值

	//...省略
	node := corev1.Node{}
	obj, _, err := Codecs.UniversalDecoder().Decode(admissionReviewReq.Request.Object.Raw, nil, &node)
	//...省略
    if _, ok := obj.(*corev1.Node); ok {
		bytes, err = nodePatch(admissionReviewReq, node)
	}

3.拿到我们该有的数据后,做校验和自己的业务就可以了。
全部代码在github中。感兴趣的可以给个stat

五、sidecar注入pod
代码中并没有介绍sidecar模式,其实看到这里相信也都明白原理了,只要在MutatingWebhookConfiguration.yaml中的resources中加入“pods”,operations加入“CREATE”即可。这样当pod有创建时候,就会调用MutatingWebhookConfiguration的回调。文章来源地址https://www.toymoban.com/news/detail-660774.html

到了这里,关于k8s 基于MutatingWebhookConfiguration实现node超卖和sidecar注入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设置k8s中节点node的ROLES值,K8S集群怎么修改node1的集群ROLES

    其实这个Roles就是一个标签,执行以下命令给node1 和 node2 打上worker标签 k8s-node1 打上标签为worker1 k8s-node2 打上标签为worker2

    2024年02月02日
    浏览(47)
  • 【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架构、Master节点 Node节点 K8S架构图

    一、docker的问世         在LXC(Linux container)Linux容器虚拟技术出现之前,业界网红是虚拟机。虚拟机技术的代表,是VMWare和OpenStack。 虚拟机是什么?         虚拟机其实就是 在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。

    2024年03月26日
    浏览(71)
  • K8S node磁盘清理

    K8S的部署形式相比传统非容器部署,会消耗更多的磁盘,在运行时可能会把磁盘占满。 这里以使用containerd运行时的K8S node为例,说明磁盘会用到那里了和如何清理磁盘 磁盘清理: 查看是什么占用磁盘多 另外也可以采用Node exporter去持续收集节点的磁盘使用信息,但针对非PV效

    2024年04月14日
    浏览(32)
  • k8s node NotReady

    If a Kubernetes node is notReady, it means that the node is not able to perform its intended functions and is not available for scheduling new workloads. There are several reasons why a node may be notReady, including: Network issues: If the node loses its network connectivity, it may become notReady. Resource exhaustion: If the node runs out of resources li

    2023年04月18日
    浏览(41)
  • k8s删除node节点

    如果不做上面的操作的话会导致这个节点上的pod无法启动,具体报错信息为:networkPlugin cni failed to set up pod \\\"alertmanager-main-1_monitoring\\\" network: failed to set bridge ad has an IP address different from 10.244.5.1/24 ,意思是已经集群网络cni已经有一个不同于10.244.51.1/24 的网络地址,所以需要执行

    2024年02月08日
    浏览(37)
  • k8s如何给node添加标签

    k8s集群如果由大量节点组成,可将节点打上对应的标签,然后通过标签进行筛选及查看,更好的进行资源对象的相关选择与匹配 [root@master01 ~]# kubectl label node worker02 region=guanzhou node/worker02 labeled [root@master01 ~]# kubectl get nodes -L region NAME       STATUS   ROLES                  AGE  

    2024年02月07日
    浏览(33)
  • k8s删除node节点的方法

    2024年02月16日
    浏览(46)
  • 基于k8s job设计与实现CI/CD系统

    方案一:Jenkins+k8s+CICD 方案二:kaniko+k8s job+CICD CICD 基于K8s Job设计流水线 CI方案 工具镜像 云原生镜像打包工具 kaniko的使用 与Jenkins对比  可用性与易用性 Jenkins存在Master调度瓶颈 企业研发流程的自定义 添加自定义流程 代码合并漏了的问题 CI系统:drone ci CI系统:argo cd 设计方

    2024年02月12日
    浏览(48)
  • K8S 设置node最大pod数量

    1.默认情况下k8s 一个node最多起110个pod 2.在node上设置打开文件/var/lib/kubelet/config.yaml 3.修改参数maxPods为指定的值(例子为180) 4.node端重启kubelet: systemctl restart kubelet 5.查看kht125节点上支持的最大pod数量: kubectl describe node kht125 | grep -i \\\"Capacity|Allocatable\\\" -A 6 6.如果以上方法不生效,

    2024年02月07日
    浏览(42)
  • k8s 维护node与驱逐pod

    1.维护node节点 设置节点状态为不可调度状态,执行以下命令后,节点状态会多出一个SchedulingDisabled的状态,即新建的pod不会往该节点上调度,本身存在node中的pod保持正常运行 kubectl cordon k8s-node01 kubectl get node 2.驱逐pod 在node节点设置为不可调度状态后,就可以开始驱逐本节点

    2024年02月06日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包