大家好,我是张晋涛。

在我之前发布的文章 《云原生时代下的容器镜像安全》(系列)中,我提到过 Kubernetes 集群的核心组件 --  kube-apiserver,它允许来自终端用户或集群的各组件与之进行通信(例如,查询、创建、修改或删除 Kubernetes 资源)。

本篇我们将聚焦于 kube-apiserver 请求处理过程中一个很重要的部分 -- 准入控制器(Admission Controller)

K8s 的准入控制器是什么

K8s 中的请求处理流程

在聊 K8s 准入控制器是什么之前,让我们先来回顾一下 Kubernetes API 的处理具体请求的过程。

img

图 1 ,Kubernetes API 处理请求的过程 (从 API Handler 到 etcd 持久化的过程)

如上图所示,每个 API 的请求从开始被 kube-apiserver 接收到最终持久化到 ETCD 的过程,即为 Kubernetes API 的请求处理流程。

它主要包含了以下几个部分:

  • API Handler -- 主要负责提供服务,接收请求。

对于其内部实现而言,请求会先到 FullHandlerChain (它是由 DefaultBuildHandlerChain 构建出来的)是一个 director 对象

type director struct {name               stringgoRestfulContainer *restful.ContainernonGoRestfulMux    *mux.PathRecorderMux
}

director根据配置进行初始化,如果 goRestfulContainer的 WebServices 的 RootPath 是 /apis,或者请求前缀与 RootPath 匹配,则进入 Restful 处理链路。

  • Authentication -- 认证的流程。

在TLS 连接建立后,会进行认证处理,如果请求认证失败,会拒绝该请求并返回 401 错误码;如果认证成功,将进行到鉴权的部分。目前支持的客户端认证方式有很多,例如:x509 客户端证书、Bearer Token、基于用户名密码的认证、OpenID 认证等。由于这些内容不是本篇的重点我们暂且跳过,感兴趣的小伙伴可以在评论区留言讨论。

  • Authorization -- 鉴权的流程。

对于 Kubernetes 而言,支持多种的鉴权模式,例如,ABAC 模式,RBAC 模式和 Webhook 模式等。我们在创建集群时,可以直接为 kube-apiserver 传递参数进行配置,这里也不赘述了。

  • Mutating Admission -- 指执行可用于变更操作的准入控制器,下文中会详细介绍。

  • Object Schema Validation -- 对资源对象的 schema 校验。

  • Validating Admission -- 指执行可用于验证操作的准入控制器,下文中会详细介绍。

  • ETCD -- ETCD 实现资源的持久化存储。

上面便是一个请求的处理流程,其中 Mutating Admission 和 Validating Admission 便是我们今天的主角。我们来详细的看一看。

什么是准入控制器(Admission Controller)

准入控制器是指在请求通过认证和授权之后,可用于对其进行变更操作或验证操作的一些代码或功能。

准入控制的过程分为两个阶段:

  • 第一阶段,运行变更准入控制器(Mutating Admission)。它可以修改被它接受的对象,这就引出了它的另一个作用,将相关资源作为请求处理的一部分进行变更;

  • 第二阶段,运行验证准入控制器(Validating Admission)。它只能进行验证,不能进行任何资源数据的修改操作;

需要注意的是,某些控制器可以既是变更准入控制器又是验证准入控制器。如果任一个阶段的准入控制器拒绝了该请求,则整个请求将立即被拒绝,并向终端用户返回错误。

为什么需要准入控制器 Admission Controller

我们主要从两个角度来理解为什么我们需要准入控制器:

  • 从安全的角度

    • 我们需要明确在 Kubernetes 集群中部署的镜像来源是否可信,以免遭受攻击;

    • 一般情况下,在 Pod 内尽量不使用 root 用户,或者尽量不开启特权容器等;

  • 从治理的角度

    • 比如通过 label 对业务/服务进行区分,那么可以通过 admission controller 校验服务是否已经有对应的 label 存在之类的;

    • 比如添加资源配额限制 ,以免出现资源超卖之类的情况;

准入控制器

考虑到这些需求比较有用 & 确实也比较需要,所以 Kubernetes 目前已经实现了很多内置的 Admission Controller 。可以参考官方文档来获取详细列表:https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do

这些内置的 Admission Controller 都是以插件的方式与 kube-apiserver 构建到一起的,你可以对其进行启用和关停。比如用如下参数进行控制:

➜  bin ./kube-apiserver --help |grep admission-plugins    --admission-control strings              Admission is divided into two phases. In the first phase, only mutating admission plugins run. In the second phase, only validating admission plugins run. The names in the below list may represent a validating plugin, a mutating plugin, or both. The order of plugins in which they are passed to this flag does not matter. Comma-delimited list of: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurity, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. (DEPRECATED: Use --enable-admission-plugins or --disable-admission-plugins instead. Will be removed in a future version.)--disable-admission-plugins strings      admission plugins that should be disabled although they are in the default enabled plugins list (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, PodSecurity, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurity, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.--enable-admission-plugins strings       admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, PodSecurity, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurity, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.

这么多的准入控制器中有两个比较特别,分别是 MutatingAdmissionWebhookValidatingAdmissionWebhook。它们并没有真正执行相应的策略,而是为 kube-apiserver 提供了一种可扩展的方式, 用户可以通过配置 MutatingAdmissionWebhookValidatingAdmissionWebhook 来使用自构建的服务, 而且这种方式是无需对 kube-spiserver 执行编译或者重启,完全是动态的,非常的方便。

我们来具体看一下。

动态准入控制器

利用上文中提到的 MutatingAdmissionWebhookValidatingAdmissionWebhook 进行运行时配置的,以 Webhook 形式调用的 Admission Controller 即为动态准入控制器。

它是一种用于接收准入请求并对其进行处理的 HTTP 回调机制,就是一个 Web 服务。当前的两种类型的准入 webhook:

  • validating admission webhook

  • mutating admission webhook

mutating admission webhook 会优先被调用,这个过程中可以对资源进行修改。

如果我们需要确保对象的最终状态以执行某些操作应该考虑使用  validating admission webhook *,*因为到达这个阶段的请求不会再被修改。

使用条件

  • 确保 Kubernetes 集群版本至少为 v1.16(以便使用 admissionregistration.k8s.io/v1 API) 或者 v1.9 (以便使用 admissionregistration.k8s.io/v1beta1 API);

  • 确保已经启用 MutatingAdmissionWebhookValidatingAdmissionWebhook 准入控制器;

  • 确保启用了 admissionregistration.k8s.io/v1beta1 或者 admissionregistration.k8s.io/v1 API;

Admission Webhook 是什么

它其实就是一个普通的 HTTP Server,需要处理的就是 AdmissionReview 类型的资源,我们来看个示例,比如说要对 Ingress资源进行准入校验:

func (ia *IngressAdmission) HandleAdmission(obj runtime.Object) (runtime.Object, error) {review, isV1 := obj.(*admissionv1.AdmissionReview)if !isV1 {return nil, fmt.Errorf("request is not of type AdmissionReview v1")}if !apiequality.Semantic.DeepEqual(review.Request.Kind, ingressResource) {return nil, fmt.Errorf("rejecting admission review because the request does not contain an Ingress resource but %s with name %s in namespace %s",review.Request.Kind.String(), review.Request.Name, review.Request.Namespace)}status := &admissionv1.AdmissionResponse{}status.UID = review.Request.UIDingress := networking.Ingress{}codec := json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, json.SerializerOptions{Pretty: true,})codec.Decode(review.Request.Object.Raw, nil, nil)_, _, err := codec.Decode(review.Request.Object.Raw, nil, &ingress)if err != nil {klog.ErrorS(err, "failed to decode ingress")status.Allowed = falsestatus.Result = &metav1.Status{Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonBadRequest,Message: err.Error(),}review.Response = statusreturn review, nil}if err := ia.Checker.CheckIngress(&ingress); err != nil {klog.ErrorS(err, "invalid ingress configuration", "ingress", fmt.Sprintf("%v/%v", review.Request.Name, review.Request.Namespace))status.Allowed = falsestatus.Result = &metav1.Status{Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonBadRequest,Message: err.Error(),}review.Response = statusreturn review, nil}klog.InfoS("successfully validated configuration, accepting", "ingress", fmt.Sprintf("%v/%v", review.Request.Name, review.Request.Namespace))status.Allowed = truereview.Response = statusreturn review, nil
}

核心处理逻辑其实就是处理请求 Webhook 时候发送的 AdmissionReview ,它会包含着我们待校验的资源对象。然后我们就按照实际的需要对资源对象进行校验或者修改了。

这里需要注意几个点:

  • Mutating Webhook 的处理是串行的,而 Validating Webhook 是并行处理的;

  • Mutating Webhook 虽然处理是串行的,但是并不保证顺序;

  • 注意对 Mutating Webhook 的处理做到幂等性,以免结果不符合预期;

  • 请求处理时,注意要处理资源对象的所有 API 版本;

如何部署 Admission Webhook

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:labels:app.kubernetes.io/name: ingress-nginxname: ingress-nginx-admission
webhooks:- name: validate.nginx.ingress.kubernetes.iomatchPolicy: Equivalentrules:- apiGroups:- networking.k8s.ioapiVersions:- v1operations:- CREATE- UPDATEresources:- ingressesfailurePolicy: FailsideEffects: NoneadmissionReviewVersions:- v1clientConfig:service:namespace: ingress-nginxname: ingress-nginx-controller-admissionpath: /networking/v1/ingresses

webhooks 中配置 webhook 的具体连接信息,以及触发规则。rules中可指定对哪些资源的具体行为生效。

总结

本篇主要介绍了 Kubernetes 中的 Admission Controller ,默认情况下有一些已经以插件形式与 kube-apiserver 编译到了一起,另外我们也可以通过自己编写动态准入控制器来完成相关的需求。

当然,目前在 K8s 生态中已经有很多现成的工具可以帮我们完成对应的这些事情了,很多情况下不需要再自行开发对应的服务了。后续我来为大家分享当前一些比较主流的,可用于进行 Mutating 和 Validating 准入控制的工具, 欢迎关注。

理清 Kubernetes 中的准入控制(Admission Controller)相关推荐

  1. Kubernetes API Server 准入控制

    前面说了k8s如何做认证,如何做鉴权,分别判断你是谁,你有什么样的操作权限,你有某个对象的操作权限但是并不代表这个对象是合法的,所以apiserver里面会有更加深层次的一个行为,它还是需要去校验你的 ...

  2. kube-apiserver源码-动态准入控制 admission webhook

    动态配置admission webhook举例(详情见官方文档:https://kubernetes.io/zh/docs/reference/access-authn-authz/extensibl ...

  3. K8s安全管理:认证、授权、准入控制

    1. K8s安全管理:认证.授权.准入控制 k8s 对我们整个系统的认证,授权,访问控制做了精密的设置:对于 k8s 集群来说,apiserver 是整 个集群访问控制的唯一入口,我们在 k8s 集群 ...

  4. 准入控制_Kubernetes动态准入控制示例

    准入控制 A walk-through of creating a webhook for Kubernetes dynamic admission control. 创建用于Kubernetes动态 ...

  5. k8s-身份认证与权限 认证鉴权准入控制- 各种方式带例子-推荐-2023

    # 认证 鉴权 准入控制 ACL 了解 原文:k8s认证.授权与准入控制 - 哪都通临时工 - 博客园 (cnblogs.com) 认证(Authentication):API Server 可以支持 ...

  6. HCIE-datacom | 网络准入控制

    一.前言 之前提供网络技术咨询服务时,有一位实习生同学向我咨询了有关网络准入的相关情景,在这里我结合华为HCIE-datacom中"网络准入控制"这一节等相关资料,对网络准入技术进 ...

  7. kubernetes API 访问控制之:准入控制

    文章目录 API访问控制 准入控制 运行准入控制插件 API访问控制 可以使用kubectl.客户端库方式对REST API的访问,Kubernetes的普通账户和Service帐户都可以实现授权访问 ...

  8. kubernetes集群安全——认证、鉴权、准入控制

    机制说明 Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务.API Server 是集群内部各个组件通信的中介,也是外部控制的入口.所以 Kubernetes 的 ...

  9. [4G/5G/6G专题基础-154]: 5G无线准入控制RAC(Radio Admission Control)+ 其他准入控制

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

最新文章

  1. apiCloud中的数据库操作mcm-js-sdk的使用
  2. 我国中等收入群体为应付生活压力 透支半生财富
  3. Envoy为什么能战胜Ngnix——线程模型分析篇
  4. codelite 教程
  5. python 傅里叶_基于python的图像傅里叶处理
  6. JavaScript学习总结(六)——JavaScript判断数据类型总结
  7. sort()函数、C++
  8. 在新版本caffe里添加新的一层(向旧格式中加)
  9. 多线程TCP的socket通信
  10. java中计算明年今天的日期_计算今天之后的下一个周年日
  11. 玩转 Springboot 2 之热部署(DevTools)
  12. 机器学习-吴恩达-笔记-5-神经网络学习
  13. 一维卷积神经网络原理,卷积神经网络原理简述
  14. 产品流程、开发流程、测试流程、运维流程、售前流程改进建议
  15. C#利用JScript自动计算字符串公式方法
  16. 使用EndNote对Word论文的参考文献进行管理
  17. Python进行Excel数据统计
  18. OPENGL OSG setNearFarRatio可以动态调节远近剪裁面
  19. 正交采样 matlab,MATLAB数值积分(正交)
  20. Android实现TTS语音播报

热门文章

  1. ALPU加密芯片应用技术解答
  2. hexo-添加图片,音乐,链接,视频
  3. 这个学期,110多所高校把AI和大模型带进校园
  4. 莫言十一学校演讲:阅读是创作最好的老师
  5. 你用什么方法做副业赚钱?
  6. 一文读懂最新区块链游戏资产平台 Enjin Platform
  7. Qt和wxWidgets 比较 以及其他GUI库
  8. 明清专题数据库:企业匹配官办书局距离、科举考试、商帮文化变量等
  9. FCU1104嵌入式控制单元对空气环境监测系统的解决方案
  10. jenkins introduction