Kubernetes 准入控制器

news2024/12/26 14:25:49

Kubernetes 极大地提高了当今生产中后端集群的速度和可管理性。由于灵活、可扩展、易用,Kubernetes 已成为容器编排的事实标准。Kubernetes 还提供了一系列保护功能。而 Admission Controllers(准入控制器) 是一组安全相关的插件,启用后能进一步使用 Kubernetes 更高级的安全功能。

什么是准入控制器?

简而言之,Kubernetes 准入控制器是管理和强制定义集群使用方式的插件。可以将它们看作拦截(经过认证的)API 请求的守门员,可以更改请求对象或完全拒绝请求。准入控制的过程分为两步:先变异(mutate)后验证(validate)。举个例子,LimitRanger 准入控制器在变异阶段使用默认的资源配置来限制容器对资源的使用,并在验证阶段确保容器的资源限制不超过预期的。
在这里插入图片描述值得一提的是,许多用户认为内置的 Kubernetes 操作的某些方面实际上由准入控制器管理。举个例子,当一个命名空间被删除随后进入 Terminating(终止) 状态时,NamespaceLifecycle 准入控制器将阻止任何对象在此命名空间内被创建。

在30多种准入控制器中,ValidatingAdmissionWebhooks 和 MutatingAdmissionWebhooks (从1.13版开始两者都处于beta状态)比较特殊。它们有着无限的灵活性,但本身并没有实现任何决策逻辑,而是从集群内运行的 webhook 服务获取相应的操作。无论何时在 Kubernetes 集群中创建、更新或删除资源,都允许用户实现自定义逻辑。

mutating admission webhooks 可以变异(篡改)API 对象,validating admission webhooks 不行。虽然 mutating admission webhooks 也可以做到拒绝请求,但是 validating admission webhooks 与前者相比有两个主要优点:第一,出于安全方面的考虑可能得禁用 MutatingAdmissionWebhook 准入控制器(或者设置严格的 RBAC 限制),因为可能引起混乱甚至有危险的副作用。第二,如上图所示,validating admission 控制器在 mutating admission 之后运行,因此,validating admission webhook 看到的任何请求对象都是即将被保存到 etcd 中的最终版。

如何开启准入控制器?

在 Kubernetes API server 的启动参数中带上:

--enable-admission-plugins=ValidatingAdmissionWebhook,MutatingAdmissionWebhook

–-admission-control 在 1.10 版本中就被废除,取而代之的是 –-enable-admission-plugins

建议默认启用以下准入控制器:

--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota,PodSecurityPolicy

点击官方文档中查看中完整准入控制器以及说明。

为什么需要准入控制器?

  • 安全:准入控制器可以通过在整个命名空间或集群中强制使用合理的安全基准来提高安全性。内置的 PodSecurityPolicy 准入控制器是典型的例子:禁止容器以 root 身份运行,或者确保容器的 rootfs 始终以只读的权限挂载。当然也可以通过基于 webkook 的准入控制器来实现:
    • 只允许从特定的 registry 拉取镜像,拒绝访问未知的 registry。
    • 拒绝不符合安全标准的部署。
  • 管控:准入控制器强制你遵循某些格式,比如良好的标签、注释、资源限制等等。
    • 对不同对象强制执行标签验证,确保标签与对象正确吻合。
    • 自动给对象添加 annotation。
  • 配置管理:准入控制器验证集群中运行的对象的配置,防止任何显式的错误配置直接生效。
    • 自动添加或验证资源限制
    • 确保 pod 被添加了合理的标签
    • 确保生产部署中不使用最新 (latest) 的镜像版本

通过这种方式,准入控制器和策略管理有助于确保应用程序在不断变化的控制环境中保持合法。

编写和部署 Admission Controller Webhook

我们用一个 Kubernetes 的缺点来说明如何利用准入控制器 webhook 来建立自定义安全策略:许多默认设置为了易于使用并减少冲突而优化,不免牺牲一定的安全性。其中之一就是默认允许容器以 root 身份运行(而且,如果没有在 Dockerfile 中使用 USER 命令配置,也将是这样)。尽管容器有一定程度隔离,以 root 身份运行还是会增加风险——这在生产环境中应当被避免。之前被曝光的 runC 漏洞 (CVE-2019-5736),只有在以 root 身份运行容器时才会搞事。

你可以使用自定义 mutating admission controller webhook 来应用更安全的默认配置:除非明确要求,webhook 将确保 pod 以非 root 用户运行(如果没有明确说明,我们将分配 uid 为1234)。注意,这个设置不会阻止你在集群中部署任何工作负载,包括那些需要以 root 身份运行的合法应用。只需要在部署配置中明确启用此风险程序操作模式。

repo: https://github.com/stackrox/admission-controller-webhook-demo

Mutating Webhook Configuration

创建 MutatingWebhookConfiguration 对象来定义 mutating admission controller webhook:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  name: demo-webhook
webhooks:
  - name: webhook-server.webhook-demo.svc
    clientConfig:
      service:
        name: webhook-server
        namespace: webhook-demo
        path: "/mutate"
      caBundle: ${CA_PEM_B64}
    rules:
      - operations: [ "CREATE" ]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]

这份配置定义了 webhook-server.webhook-demo.svc 这个 webhook,当 pod 创建时 Kubernetes API server 将发送 HTTP POST 请求至 /mutate 路径。

Webhook REST API

API server 向指定接口发送 HTTP POST 请求,请求体中带上 JSON 格式的 AdmissionReview(Request 字段)。同样响应也是 JSON 格式的 AdmissionReview(Response 字段)。

demo repo 中包含了一个序列化/反序列化的函数,你只需要专注于实现操作 Kubernetes API 对象的逻辑就行了。在这个例子中,实现准入控制器逻辑的函数是 applySecurityDefaults,并在 HTTPS 服务中与 /mutate 路由绑定:

mux := http.NewServeMux()
mux.Handle("/mutate", admitFuncHandler(applySecurityDefaults))
server := &http.Server{
  Addr:    ":8443",
  Handler: mux,
}
log.Fatal(server.ListenAndServeTLS(certPath, keyPath))

创建一个 Service 对象来将443端口映射至容器的8443端口:

apiVersion: v1
kind: Service
metadata:
  name: webhook-server
  namespace: webhook-demo
spec:
  selector:
    app: webhook-server  # specified by the deployment/pod
  ports:
    - port: 443
      targetPort: webhook-api  # name of port 8443 of the container

对象变异逻辑

mutating admission controller webhook 通过 JSON 补丁 来变异。下面的 Go 数据结构大致描述了一下:

type patchOperation struct {
  Op    string      `json:"op"`
  Path  string      `json:"path"`
  Value interface{} `json:"value,omitempty"`
}

要把 pod 的 .spec.securityContext.runAsNonRoot 字段设置为 true,我们构建下面的 patchOperation 对象:

patches = append(patches, patchOperation{
  Op:    "add",
  Path:  "/spec/securityContext/runAsNonRoot",
  Value: true,
})

TLS 证书

由于必须走 HTTPS,需要提供 TLS 证书。自签名证书也可以(由一个自签名的 CA 签名),但是我们需要 Kubernetes 在于 webhook 服务器通信时指定相应的 CA 证书。此外,证书的 CN 要和 Kubernetes API server 所使用的服务器名称匹配,内部的 Service 域名为 ..svc,在我们的例子中为 webhook-server.webhook-demo.svc。由于自签名 TLS 证书的生成方法 Google 上一大把,我们就在示例中引用相应的 shell 脚本了。

前面的 Webbook 配置包含了占位符 ${CA_PEM_B64}。在我们创建它之前,需要替换成 BASE64 编码后的 CA PEM 证书。openssl base64 -A 命令可以做到。

测试

测试案例:

  • 未指定安全上下文的 pod。我们期望这个 pod 以 uid 为1234的非 root 用户身份运行。
  • 指定安全上下文的 pod,显示地以 root 用户运行。
  • 配置冲突的 pod,指定了必须以非 root 用户运行,但是 uid 为0。
    通过执行 kubectl create -f examples/.yaml 来创建这些 pod。在前两个例子中,验证用户身份:
$ kubectl create -f examples/pod-with-defaults.yaml
$ kubectl logs pod-with-defaults
I am running as user 1234

第三个例子中,创建操作会被拒绝:

$ kubectl create -f examples/pod-with-conflict.yaml
Error from server (InternalError): error when creating "examples/pod-with-conflict.yaml": Internal error occurred: admission webhook "webhook-server.webhook-demo.svc" denied the request: runAsNonRoot specified, but runAsUser set to 0 (the root user)

引用

  • https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
  • https://docs.okd.io/latest/architecture/additional_concepts/dynamic_admission_controllers.html
  • https://kubernetes.io/blog/2018/01/extensible-admission-is-beta/
  • https://medium.com/ibm-cloud/diving-into-kubernetes-mutatingadmissionwebhook-6ef3c5695f74
  • https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/webhook/main.go
  • https://github.com/istio/istio
  • https://www.stackrox.com/post/2019/02/the-runc-vulnerability-a-deep-dive-on-protecting-yourself/

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

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

相关文章

Failed to start application ‘/LM/W3SVC/7/ROOT‘, ErrorCode ‘0x800700c1‘.解决方案

dll相互干扰所致 关闭整个IIS服务 发布选项勾选删除现有文件 即可

Seata AT模式源码解析二(Seata Client端启动流程)

文章目录 初始化TM和RM数据源代理 由于我们一般都是在springboot中使用的,而与springboot集成的我们一般就先看starter的spring.factories文件,看看它的自动装配 这里面主要关注SeataAutoConfiguration和SeataDataSourceAutoConfiguration。 SeataAutoCo…

C# WPF窗体设计器显示以及App.xaml文件打不开

问题描述: 在项目中遇到了App.xaml设计器打不开以及窗体设计器不显示,只有代码,如图所示: 可以明显的看见左下角的设计器不见,但是用户控件又有设计器 解决方法: ①清理项目 ②将不能正常打开的文件右…

Android Studio 2022.3 新版 flamingo 安装步骤及遇到的问题

下载地址: https://developer.android.google.cn/studio D盘中新建一个 Android 文件夹, 用来存储 Android studio 和 SDK 文件. 下载好之后, 运行 exe 文件, 点击 next 注意这个路径最好不要有空格,比如 program files这种目录,不然后面安装sdk的时候会有问题. 点击 instal…

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑 IWR6843AOPEVM-G版本可以直接与DCA1000EVM连接 进行数据获取 不需要连接MMWAVEICBOOST版 直接使用 DCA1000mmWave Studio 软件进行数据采集 在官方手册中 User’s Guide 60GHz 毫米波传感器EVM 有相关模式的开…

基于RetinaNet和TensorFlow Object Detection API实现目标检测(附源码)

文章目录 一、RetinaNet原理二、RetinaNet实现1. tf.train.CheckPoint简介2. RetinaNet的TensorFlow源码 一、RetinaNet原理 待补充 二、RetinaNet实现 1. tf.train.CheckPoint简介 待补充 2. RetinaNet的TensorFlow源码 Step 1:安装Tensorflow 2 Object Detect…

ORB-SLAM3整体流程详解

0. 简介 在之前,作者曾经转过一篇《一文详解ORB-SLAM3》的文章。那篇文章中提到了ORB-SLAM3是一个支持视觉、视觉加惯导、混合地图的SLAM系统,可以在单目,双目和RGB-D相机上利用针孔或者鱼眼模型运行。与ORB-SLAM2相比,ORB-SLAM3…

软件系统三基座之一:权限管理

软件系统三基座包含:权限管理、组织架构、用户管理。 何为基座,即是有了这些基础,任一相关的“建筑”就能逐步搭建起来。 万丈高楼平地起 一、为什么要权限管理 权限管理,一般指根据系统设置的安全规则或者安全策略,…

集成chatgpt4和midjourney的超强镜像站

昨天发现一个镜像站,和之前发的镜像站不一样,这个集成了midjourney和chatgpt,且免翻,相信给很多很多用户都提供了便利吧! 先把网站贴出来,有兴趣的伙伴可以玩一玩 http://mtw.so/5EoyYy http://mtw.so/5E…

如何在上架App之前设置证书并上传应用

App上架教程 在上架App之前想要进行真机测试的同学,请查看《iOS- 最全的真机测试教程》,里面包含如何让多台电脑同时上架App和真机调试。 P12文件的使用详解 注意: 同样可以在Build Setting 的sign中设置证书,但是有点麻烦&…

浅析 Redis 中 String 数据类型及其底层编码

从 RedisObject 说起 在 Redis 中,任意数据类型的键和值都会被封装为一个 RedisObject ,也叫做Redis对象,源码如下 c 复制代码 /*server.h*/ typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:LRU_BITS;…

springboot+vue之java学习平台(java项目源码+文档)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的java学习平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:风歌&a…

档案库房太乱了怎么办?这个方法秒变高级!

全国有数以万计的大大小小的档案馆,其中有许多非常重要的机要档案,其历史和社会价值非常高,而档案保存的质量、档案的物理寿命、档案的防虫防霉都与库房的空气质量、温湿度息息相关。 解决档案高效管理及利用的安全问题越来越迫切&#xff0c…

在Ubuntu22.04上安装QQ~Linux

在Ubuntu22.04上安装QQ~Linux 0. 前言1. 下载deb安装包2. 使用dpkg安装deb包3. 安装完成,启动QQ3.1 点击图标打开3.2 使用命令行的方式打开 0. 前言 换Ubuntu当主力生产力了,并不是太喜欢vmware,所以我直接装到了硬盘里边,需要移…

SSM 如何使用 Kafka 实现消息队列?

SSM 如何使用 Kafka 实现消息队列? Kafka 是一个高性能、可扩展、分布式的消息队列系统,它支持多种数据格式和多种操作,可以用于实现数据传输、消息通信、日志处理等场景。在 SSM(Spring Spring MVC MyBatis)开发中…

iOS-最全的App上架教程

App上架教程 在上架App之前想要进行真机测试的同学,请查看《iOS- 最全的真机测试教程》,里面包含如何让多台电脑同时上架App和真机调试。 P12文件的使用详解 注意: 同样可以在Build Setting 的sign中设置证书,但是有点麻烦&…

软件开发项目成本控制的4大策略

1、构建责权利相结合的成本控制机制 需要对每个部门与个人的工作范围和工作职业有明确的界定,并赋予相应的权利以充分履行职责。在责任支配下高效完成工作进度时,需要给予一定的物质奖励。通过这样层层落实,逐级负责,从而做到责权…

VanillaNet:深度学习极简主义的力量

摘要 基础模型的核心是“更多不同”的理念,计算机视觉和自然语言处理方面的出色表现就是例证。然而,Transformer模型的优化和固有复杂性的挑战要求范式向简单性转变。在本文中,我们介绍了VanillaNET,这是一种设计优雅的神经网络架…

学会提问,ChatGPT可以帮你写出高质量论文

前言 ChatGPT 很火,火到大家以为他可以上天入地,上到天文,下到地理无所不能,但实际使用大家是不是会遇到如下的情况。 写论文步骤 今天,我们来探讨下怎样问ChatGPT,才能帮你写出一篇优秀的论文,…

【Java-Crawler】爬取动态页面(HtmlUnit、WebMagic)

爬取动态页面(WebMagic、HtmlUnit) 一、HtmlUnit的基本使用引入依赖一般使用步骤WebClient 的一些配置(上述一般步骤中的第二步) 二、案例(爬取CSDN首页)测试(WebMagicHtmlUnit)三、…