Kubernetes-准入控制

news2024/11/19 11:30:58

在这里插入图片描述

一. 准入控制

Webhook 官方demo

  • 默认准时控制器

    • NamespaceLifecycle
    • LimitRanger
    • ServiceAccount
    • TaintNodesByCondition
    • Priority
    • DefaultTolerationSeconds
    • DefaultStorageClass
    • StorageObjectInUseProtection
    • PersistentVolumeClaimResize
    • RuntimeClass
    • CertificateApproval
    • CertificateSigning
    • CertificateSubjectRestriction
    • DefaultIngressClass
    • MutatingAdmissionWebhook
    • ValidatingAdmissionWebhook
    • ResourceQuota
  • Mutating admission webhooks 用于在资源存储之前通过 mutating webhooks 进行修改

  • Validating admission webhooks 用于在资源存储之前通过 validating webhooks 自定义策略验证资源

  • 当 API 请求进入时,mutating 和 validating 控制器使用配置中的外部 webhooks 列表并发调用,规则如下:

    • 如果所有的 webhooks 批准请求,准入控制链继续流转, 第一阶段,运行变更准入控制器, Mutating Admission, 它可以修改被它接受的对象,这就引出了它的另一个作用,将相关资源作为请求处理的一部分进行变更, 第二阶段,运行验证准入控制器 Validating Admission它只能进行验证,不能进行任何资源数据的修改操作
    • 如果有任意一个 webhooks 阻止请求,那么准入控制请求终止,并返回第一个 webhook 阻止的原因。其中,多个 webhooks 阻止也只会返回第一个 webhook 阻止的原因
    • 如果在调用 webhook 过程中发生错误,那么请求会被终止或者忽略 webhook
  • Admission webhooks 可以使用如下几个场景:

    • 通过 mutating webhook 注入 side-car 到 Pod(istio 的 side-car 就是采用这种方式注入的)
    • 限制项目使用某个资源(如限制用户创建的 Pod 使用超过限制的资源等)
    • 自定义资源的字段复杂验证(如 CRD 资源相关字段的规则验证等)
  • 准入控制可以通过Webhook是一个HTTP回调,通过一个条件触发HTTP POST请求发送到Webhook 服务端,服务端根据请求数据进行处理

1. Webhook准备

  • webhook核心就是处理apiservers发送的AdmissionReview请求,并将其决定作为AdmissionReview对象发送回去, 也就是修改mutating和验证validating
  • Webhook和controller类似,既能在kubernetes环境中运行,也能在kubernetes环境之外运行

2. 自定义webhook

  • 要完成一个自定义admission webhook需要两个步骤
    • 将相关的webhook config注册给kubernetes,也就是让kubernetes知道你的webhook
    • 准备一个http server来处理 apiserver发过来验证的信息
1. 向kubernetes注册webhook对象
  • kubernetes将这种形式抽象为两种资源, 这两种资源是没有namespace限制的,是全局资源
    • ValidatingWebhookConfiguration
    • MutatingWebhookConfiguration
  • 创建两个钩子,/mutate/validate
    • /mutate 将在创建deployment资源时,基于版本,给资源加上 webhook.example.com/allow: trueannotations(注释)
    • /validate 将对 /mutate 增加了 allow:true 的注释批准通行,否则拒绝
# 获得集群的ca证书base64
cat /etc/kubernetes/pki/ca.crt | base64 | tr -d '\n'

# 获得当前上下文中的CA base64 信息
kubectl config view --raw --flatten -o json | jq -r '.clusters[] | .cluster."certificate-authority-data"'
# webhook会对资源进行修改,需要一个sa
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admission-webhook-example-sa
  labels:
    app: admission-webhook-example

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: admission-webhook-example-cr
  labels:
    app: admission-webhook-example
rules:
- apiGroups:
  - qikqiak.com
  resources:
  - "*"
  verbs:
  - "*"
- apiGroups:
  - ""
  resources:
  - pods
  - events
  verbs:
  - "*"
- apiGroups:
  - apps
  resources:
  - deployments
  - daemonsets
  - replicasets
  - statefulsets
  verbs:
  - "*"
- apiGroups:
  - autoscaling
  resources:
  - '*'
  verbs:
  - '*'

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: admission-webhook-example-crb 
  labels:
    app: admission-webhook-example
subjects:
- kind: ServiceAccount
  name: admission-webhook-example-sa
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admission-webhook-example-cr
apiVersion: v1
kind: Service
metadata:
  name: admission-webhook-example-svc
  labels:
    app: admission-webhook-example
spec:
  ports:
  - port: 443
    targetPort: 443
  selector:
    app: admission-webhook-example
# rbac文件由个ServiceAccount, 会创建一个secret, 
[root@webhook ~/webhood]# kubectl get secrets 
NAME                                       TYPE                                  DATA   AGE
admission-webhook-example-sa-token-s4jbv   kubernetes.io/service-account-token   3      3m49s
  • K8S集群默认是HTTPS通信的,所以APiserver调用webhook的过程也是HTTPS的
  • k8s集群1.22版本以后此脚本需要修改,具体参考 官网
# 证书签发脚本, 因为K8S集群默认是HTTPS通信的,所以APiserver调用webhook的过程也是HTTPS的,所以需要进行证书认证, 通过 CertificateSigningRequest 签发, --secret一定要指定自己的(如上面创建的sa)
#!/bin/bash

set -e

usage() {
    cat <<EOF
Generate certificate suitable for use with an sidecar-injector webhook service.

This script uses k8s' CertificateSigningRequest API to a generate a
certificate signed by k8s CA suitable for use with sidecar-injector webhook
services. This requires permissions to create and approve CSR. See
https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster for
detailed explantion and additional instructions.

The server key/cert k8s CA cert are stored in a k8s secret.

usage: ${0} [OPTIONS]

The following flags are required.

       --service          Service name of webhook.
       --namespace        Namespace where webhook service and secret reside.
       --secret           Secret name for CA certificate and server certificate/key pair.
EOF
    exit 1
}

while [[ $# -gt 0 ]]; do
    case ${1} in
        --service)
            service="$2"
            shift
            ;;
        --secret)
            secret="$2"
            shift
            ;;
        --namespace)
            namespace="$2"
            shift
            ;;
        *)
            usage
            ;;
    esac
    shift
done

# 如果不想传递参数,可以直接在这改
[ -z ${service} ] && service=admission-webhook-example-svc
[ -z ${secret} ] && secret=admission-webhook-example-sa-token-s4jbv
[ -z ${namespace} ] && namespace=default

if [ ! -x "$(command -v openssl)" ]; then
    echo "openssl not found"
    exit 1
fi

csrName=${service}.${namespace}
tmpdir=$(mktemp -d)
echo "creating certs in tmpdir ${tmpdir} "

cat <<EOF >> ${tmpdir}/csr.conf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${service}
DNS.2 = ${service}.${namespace}
DNS.3 = ${service}.${namespace}.svc
EOF

openssl genrsa -out ${tmpdir}/server-key.pem 2048
openssl req -new -key ${tmpdir}/server-key.pem -subj "/CN=${service}.${namespace}.svc" -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf

# 清理之前为我们的服务创建的任何 CSR。 如果不存在则忽略错误
kubectl delete csr ${csrName} 2>/dev/null || true

# 创建服务器证书/密钥 CSR 并发送到 k8s API
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: ${csrName}
spec:
  groups:
  - system:authenticated
  request: $(cat ${tmpdir}/server.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF

# verify CSR has been created
while true; do
    kubectl get csr ${csrName}
    if [ "$?" -eq 0 ]; then
        break
    fi
done

# 批准并获取签名证书
kubectl certificate approve ${csrName}
# verify certificate has been signed
for x in $(seq 10); do
    serverCert=$(kubectl get csr ${csrName} -o jsonpath='{.status.certificate}')
    if [[ ${serverCert} != '' ]]; then
        break
    fi
    sleep 1
done
if [[ ${serverCert} == '' ]]; then
    echo "ERROR: After approving csr ${csrName}, the signed certificate did not appear on the resource. Giving up after 10 attempts." >&2
    exit 1
fi

# 写入到证书中
echo ${serverCert} | openssl base64 -d -A -out ${tmpdir}/server-cert.pem


# create the secret with CA cert and server cert/key
kubectl create secret generic ${secret} \
        --from-file=key.pem=${tmpdir}/server-key.pem \
        --from-file=cert.pem=${tmpdir}/server-cert.pem \
        --dry-run -o yaml |
    kubectl -n ${namespace} apply -f -
# 查看生成的证书
[root@webhook ~/webhood]# kubectl get csr
NAME                                    AGE   SIGNERNAME                     REQUESTOR          CONDITION
admission-webhook-example-svc.default   5s    kubernetes.io/legacy-unknown   kubernetes-admin   Approved,Issued


# 将证书放在特定位置,这也是我们启动 deployment必须的 用于和api-server通信
mkdir -p /etc/webhook/certs

kubectl get secret ${secret} -o json | jq -r '.data."key.pem"' | base64 -d > /etc/webhook/certs/key.pem
kubectl get secret ${secret} -o json | jq -r '.data."cert.pem"' | base64 -d > /etc/webhook/certs/cert.pem
  • MutatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  name: mutating-webhook-example-cfg
  labels:
    app: admission-webhook-example
webhooks:
  - name: mutating-example.qikqiak.com
    clientConfig:
      service:
        name: admission-webhook-example-svc
        namespace: default
        path: "/mutate"			# 和代码中路径一致
      caBundle: ${CA_BUNDLE}	# ca base64信息
    rules:
      - operations: [ "CREATE" ]
        apiGroups: ["apps", ""]
        apiVersions: ["v1"]
        resources: ["deployments","services"]
    namespaceSelector:
      matchLabels:
        # namespace具有该标签才作用于资源对象
        admission-webhook-example: enabled
  • ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: validation-webhook-example-cfg
  labels:
    app: admission-webhook-example
webhooks:
  - name: required-labels.qikqiak.com
    clientConfig:
      service:
        name: admission-webhook-example-svc
        namespace: default
        path: "/validate"		# 和代码中路径一致
      caBundle: ${CA_BUNDLE}	# ca base64信息
    rules:
      - operations: [ "CREATE" ]
        apiGroups: ["apps", ""]
        apiVersions: ["v1"]
        resources: ["deployments","services"]
    namespaceSelector:
      matchLabels:
         # namespace具有该标签才作用于资源对象
        admission-webhook-example: enabled
# 给要使用的 namespace 打标签
kubectl label namespace default admission-webhook-example=enabled

2. Webhook代码

code

go build -o admission-webhook-example

3. webhook-deployment

FROM alpine:latest

WORKDIR /
ADD ./cert.pem  /etc/webhook/certs/cert.pem
ADD ./key.pem /etc/webhook/certs/key.pem

ADD ./admission-webhook-example /admission-webhook-example
RUN chmod +x /admission-webhook-example
ENTRYPOINT ["./admission-webhook-example"]
# 编译好的go程序admission-webhook-example也放在这
cd /etc/webhook/certs
cp /etc/webhook/certs/* .


# build
docker build -t admission-webhook:v1 .
# deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: admission-webhook-example-deployment
  labels:
    app: admission-webhook-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: admission-webhook-example
  template:
    metadata:
      labels:
        app: admission-webhook-example
    spec:
      serviceAccount: admission-webhook-example-sa
      containers:
        - name: admission-webhook-example
          image: admission-webhook:v1
          imagePullPolicy: IfNotPresent
          # 证书位置改为自己的
          args:
            - -tlsCertFile=/etc/webhook/certs/cert.pem
            - -tlsKeyFile=/etc/webhook/certs/key.pem
            - -alsologtostderr
            - -v=4
            - 2>&1
          volumeMounts:
            - name: webhook-certs
              mountPath: /etc/webhook/certs
              readOnly: true
      volumes:
        - name: webhook-certs
          secret:
          # 名字改为创建的sa的secret名字
            secretName: admission-webhook-example-sa-token-s4jbv

4. 测试

apiVersion: apps/v1
kind: Deployment
metadata:
  name: reject
  annotations:
    admission-webhook-example.qikqiak.com/mutate: "false"
spec:
  selector:
    matchLabels:
      app: reject
  template:
    metadata:
      labels:
        app: reject
    spec:
      containers:
        - name: reject
          image: tutum/curl
          command: ["/bin/sleep","infinity"]
          imagePullPolicy: IfNotPresent
# yaml中的注释 admission-webhook-example.qikqiak.com/mutate: "false", value 为 false,准入控制就拒绝, 去掉 annotations 就可以创建
[root@webhook ~/webhood/debug]# kubectl apply -f jujue.yaml 
Error from server (required labels are not set): error when creating "jujue.yaml": admission webhook "required-labels.qikqiak.com" denied the request: required labels are not set

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

若依项目的table列表中对每一个字段增加排序按钮(单体版和前后端分离版)

一、目标&#xff1a;每一个字段都添加上下箭头用来排序 只需要更改前端代码&#xff0c;不需要更改后端代码&#xff0c;后面会讲解原理 二、单体版实现方式&#xff1a; 1.在options中添加sortable:true 2.在需要排序的字段中添加sortable:true 三、前后端分离版 1.el-tab…

RHCE9学习指南 第17章 进程管理

17.1 进程介绍 在Windows下打开任务管理器就可以查看到系统所有进程&#xff0c;如图17-1所示。 图17-1 Windows下的任务管理器 这里列出了系统中所有的进程。不过也可以使用命令行工具来查看进程。每个进程都会有一个process ID&#xff0c;简称为pid。 17.2 查看进程 也可…

使用numpy处理图片——镜像翻转和旋转

在《使用numpy处理图片——基础操作》一文中&#xff0c;我们介绍了如何使用numpy修改图片的透明度。本文我们将介绍镜像翻转和旋转。 镜像翻转 上下翻转 from PIL import Image import numpy as np img Image.open(example.png) data np.array(img)# axis0 is vertical, a…

B端产品经理学习-权限管理

目录 权限管理的原则 常见的权限管理模型 总结 对企业而言&#xff0c;最重要的一个资源就是有价值的专有信息&#xff0c;也就是自己知道&#xff0c;而其他企业不知道的信息&#xff0c;因此&#xff0c;专有信息是企业的重要竞争力&#xff0c;权限管理的价值体现在专有信…

Spring基于注解的AOP控制事务

首先在.xml中开启sprong对注解事务的支持 applicationContext.xml <tx:annotation-driven transaction-manager"transactionManager"/> 然后再Service中加上注解 service Service Transactional(readOnlytrue,propagation Propagation.SUPPORTS) public cl…

【Java集合篇】HashMap的remove方法是如何实现的?

HashMap的remove方法是如何实现的 ✔️典型解析✔️拓展知识仓✔️HashMap的remove方法的注意事项✔️HashMap的remove方法的参数类型✔️ 删除键和值的参数类型有什么区别✔️删除键值对的场景是什么 ✔️HashMap remove方法是阻塞队列的吗✔️HashMap remove方法是线程安全的…

行为型设计模式——模板方法模式

学习难度&#xff1a;⭐ &#xff0c;比较常用 模板方法模式 在面向对象程序设计过程中&#xff0c;程序员常常会遇到这种情况&#xff1a;设计一个系统时知道了算法所需的关键步骤&#xff0c;而且确定了这些步骤的执行顺序&#xff0c;但某些步骤的具体实现还未知&#xff0…

前端面试题集合七(ES6、ES7、ES8、ES9、ES10、ES11、ES12)

ES6&#xff08;2015&#xff09; 1. 类&#xff08;class&#xff09; class Man {constructor(name) {this.name 小豪;}console() {console.log(this.name);} } const man new Man(小豪); man.console(); // 小豪 2. 模块化(ES Module) // 模块 A 导出一个方法 export …

@FunctionalSpringBootTest 和@SpringBootTest注解的区别

FunctionalSpringBootTest 和 SpringBootTest 是Spring框架中用于测试的两个不同注解。下面是它们之间的主要区别&#xff1a; 用途和范围&#xff1a; SpringBootTest&#xff1a;这个注解用于需要测试Spring应用程序上下文的场合。它会加载完整的应用程序上下文&#xff0c;适…

AI教我学编程之C#入门程序详解与拓展

与AI肩并肩 前言一、一个简单的C#程序补充说明对话AI 二、标识符三、关键字四、Main五、空白1. 缩进2. 代码块的间距3. 操作符的空格4. 换行5. 一致性 六、语句七、从程序输出文本主题&#xff1a;从程序中输出文本1. Write 和 WriteLine 方法2. 格式字符串3. 多重标记和值4. 格…

阿里云国际服务器设置安全防护程序

阿里云云服务器&#xff08;ECS&#xff09;提供弹性、安全、高性能、高性价比的虚拟云服务器&#xff0c;满足您的所有需求。立即在这里免费注册&#xff01; 常见 Web 应用程序 请勿对 Web 服务控制台&#xff08;如 WDCP、TOMCAT、Apache、Nginx、Jekins、PHPMyAdmin、Web…

浅谈有源滤波在某棉纺企业低压配电室节能应用

叶根胜 安科瑞电气股份有限公司 上海嘉定 201801 0引言 在电力系统中&#xff0c;谐波的根本原因是非线性负载。由于电子设备、变频器、整流器等。在棉纺企业的大部分设备中被广泛使用&#xff0c;因此会产生大量的谐波电流。我公司的环锭纱线和筒车间的配电设备受到谐波的影…

【C语言】time.h——主要函数介绍(附有几个小项目)

time.h是C标准函数库中获取时间与日期、对时间与日期数据操作及格式化的头文件。返回值类型 size_t&#xff1a;适合保存sizeof的结果&#xff0c;类型为unsigned int&#xff08;%u&#xff09;clock_t&#xff1a;适合存储处理器时间的类型&#xff0c;一般为unsigned long&…

day 43动态规划(5)

day 43 代码随想录 2024.1.10 发烧中。。。简单过一遍等二刷DP问题&#xff01;&#xff08;最近赶一篇paper&#xff01;&#xff09; 1. 1049最后一块石头的重量 dp[j]表示容量&#xff08;这里说容量更形象&#xff0c;其实就是重量&#xff09;为j的背包&#xff0c;最多…

51单片机介绍

1 单片机简介 单片机&#xff0c;英文Micro Controller Unit&#xff0c;简称MCU 内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能 单片机的任务是信息采集&#xff08;依靠传感器&#xff09;、处理&#xff08;依靠CPU&#xff09;和硬件设…

基于JavaWeb+BS架构+SpringBoot+Vue校园一卡通系统的设计和实现

基于JavaWebBS架构SpringBootVue校园一卡通系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 第一章 概述 4 1.1 研究背景 4 1.2研究目的及意义 4 1.3国内外发展现状 4 1…

DePIN:重塑物理资源网络的未来

点击查看TechubNews更多相关推荐 一、DePIN&#xff1a;物理资源的新整合方式 Depin赛道的项目如雨后春笋般涌现&#xff0c;为市场注入了新的活力。作为先行者&#xff0c;Coinmanlabs已经深入布局Depin赛道&#xff0c;其中最引人注目的项目当属Grass。 什么是DePIN DePIN…

Java项目:114SSM图书管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 图书管理系统基于SpringSpringMVCMybatis开发&#xff0c;系统主要实现了图书馆借书还书功能&#xff0c;系统分为管理员和读者两种角色。 管理员功能如下…

A股风格因子看板 (2024.01 第4期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴 露等。 今日为该因子跟踪第4期&#xff0c;指数组合数据截止日2024-12-01&#xff0c;要点如下 近1年A股风格因子检验统…

Linux内存管理:(七)页面回收机制

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 触发页面回收 Linux内核中触发页…