Kubernetes 准入控制器

这篇具有很好参考价值的文章主要介绍了Kubernetes 准入控制器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

什么是准入控制器?

简而言之,Kubernetes 准入控制器是管理和强制定义集群使用方式的插件。可以将它们看作拦截(经过认证的)API 请求的守门员,可以更改请求对象或完全拒绝请求。准入控制的过程分为两步:先变异(mutate)后验证(validate)。举个例子,LimitRanger 准入控制器在变异阶段使用默认的资源配置来限制容器对资源的使用,并在验证阶段确保容器的资源限制不超过预期的。
Kubernetes 准入控制器值得一提的是,许多用户认为内置的 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

第三个例子中,创建操作会被拒绝:文章来源地址https://www.toymoban.com/news/detail-463909.html

$ 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/

到了这里,关于Kubernetes 准入控制器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【云原生】kubernetes控制器deployment的使用

        目录 ​编辑 1 Controller 控制器 1.1 什么是 Controller 1.2 常见的 Controller 控制器 1.3 Controller 如何管理 Pod 2 Deployment 2.1 创建 deployment 2.2 查看 deployment 2.3 扩缩 deployment 2.4 回滚 deployment 2.5 删除 deployment 1 Controller 控制器 官网: 控制器 | Kubernetes 1.1 什么是 Controller Kubernetes 通常不会

    2024年02月13日
    浏览(36)
  • Linux6.39 Kubernetes Pod控制器

    第三章 LINUX Kubernetes Pod控制器 一、Pod控制器及其功用 Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源 二.pod控制器有多种类型 1.Replic

    2024年02月12日
    浏览(43)
  • 【云原生|Kubernetes】14-DaemonSet资源控制器详解

    ​ 在 Kubernetes 中,DaemonSet 是一种用于在节点上运行指定的 Pod 的控制器(Controller)。与 ReplicaSet 或 Deployment 不同,DaemonSet 不是为了扩展 Pod 数量而创建的,而是为了在每个节点上运行一个实例或多个实例的 Pod。 ​ DaemonSet 通常用于在 Kubernetes 集群中运行一些系统级别的服务

    2024年02月13日
    浏览(33)
  • 【Kubernetes资源篇】DaemonSet控制器入门实战详解

    中文官方文档参考: 1、DaemonSet控制器是什么? Kubernetes中的DaemonSet(简写ds)控制器是一种 用来运行守护进程应用程序的控制器,它确保每个Node节点都运行具有指定配置的 Pod副本,当Node节点的加入或删除DaemonSet控制器会自动创建或删除相应的 Pod副本。 特点: 每个节点只运行

    2024年02月10日
    浏览(69)
  • 5、Kubernetes核心技术 - Controller控制器工作负载

    目录 一、Deployments - 控制器应用 二、Deployment升级回滚和弹性收缩 2.1、创建一个 1.14 版本的 pod 2.2、应用升级 2.3、查看升级状态 2.4、查看历史版本 2.5、应用回滚 2.6、弹性伸缩  三、StatefulSet - 有状态应用 四、DaemonSet - 守护进程 五、Job - 单次任务 六、Cronjob - 定时任务 Deplo

    2024年02月15日
    浏览(38)
  • 【云原生|Kubernetes】13-Deployment资源控制器详解

    kubernetes中有很多资源控制器,这些资源控制器我们只说一些重要且常用的。在介绍Deploymen之前,我们会逐个介绍这些控制器。 Pod控制器介绍 ​ Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效

    2024年02月16日
    浏览(43)
  • 【Kubernetes资源篇】Replicaset控制器入门实战详解

    官方中文参考文档: ReplicaSet是k8s中一种资源对象,简写 rs , 用于管理Pod副本数量和健康状态,在 spec.replicas 字段中可以定义Pod副本数量,ReplicaSet会始终保持Pod在指定数量 ,当发现Pod数量大于副本数量时,会移除多出的Pod,当发现Pod小于副本数量会自动创建Pod,使其始终维

    2024年02月09日
    浏览(44)
  • 【云原生 | 从零开始学Kubernetes】二十三、Kubernetes控制器Statefulset

    该篇文章已经被专栏《从零开始学k8s》收录 上一篇文章:kubernetes持久化存储下 点击跳转 StatefulSet 是为了管理有状态服务的问题而设计的 对于StatefulSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续

    2024年02月03日
    浏览(36)
  • 【探索 Kubernetes|作业管理篇 系列 11】控制器的核心功能

    大家好,我是秋意零。 上一篇结束了 Pod 对象的内容。 今天要探讨的内容是 “控制器”,它是 Kubernetes 编排最核心的功能。理解了 “控制器”,你就能理解 Deployment、StatefulSet、DaemontSet、Job、CroJob 控制器对象。 最近搞了一个扣扣群,旨在技术交流、博客互助,希望各位大佬

    2024年02月11日
    浏览(38)
  • Kubernetes技术--k8s核心技术Controller控制器

    1.Controller概述    Controller是在集群上管理和运行容器的对象。是一个实际存在的对象。 2.pod和Controller之间的关系 pod通过controller实现应用的运维,包括伸缩、滚动升级等操作。 这里pod和controller通过label标签来建立关系。如下所示: 3.Deployment控制器应用场景 -1:部署无状态的应

    2024年02月10日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包