Kubernetes 可扩展 Admission 进入 Beta 阶段

2023年 7月 9日 31.5k 0

Kubernetes API Server 中有一个功能,能让用户(对工作负载)进行决策,这一功能在 1.9 中已经走入成熟期。

Admission 是 Kubernetes 中最强大的工具之一,可以通过限制创建对象的方式来增强 Kubernetes 集群的安全性,这部分一直是编译在代码之中的。在 1.9 中,我们将 Admission 的 Webhook 升级成 Beta,让用户可以在 API Server 之外对 Admission 施加影响。

Admission 是什么?

Admission(注1),是在认证之后,资源持久化之前 的一个处理 API Server 请求的步骤。Admission 能获取到和认证过程一致的信息(用户、URL 等),以及绝大多数 API 请求的完整报文。

Admission 阶段由不同插件组成,每个 Admission 都会对一个侧面进行观察和操作。例如:影响调度决策的PodNodeSelector、阻止恶意容器的PodSecurityPolicy以及实现 Namespace 资源分配的ResourceQuota。

Admission 内部分为两个阶段:

  • 变更(Mutation,突变?):能够修改 API 请求的报文,还可以拒绝 API 请求。
  • 验证:允许进行查询,以及拒绝 API 请求。
  • Admission 插件可以在这两个阶段起作用,但是变更总是在验证之前。

    Mutation

    Admission 的变更功能可以在资源生成之前进行修改。在 Admission 链条上可以多次修改同一个字段,因此插件不是无序的。

    PodNodeSelector就是一个例子,他使用 Namespace 的一个注解namespace.annotations[“scheduler.alpha.kubernetes.io/node-selector”],在其中查找标签选择器,并将其加入pod.spec.nodeselector字段。这一功能限制某个 Namespace 的 Pod,只能运行在指定节点上,同 Taint 的功能正好相反(也是 Admission 插件)。

    验证

    Admission 的验证阶段用来对特定 API 资源进行验证。这一阶段会在所有变更执行结束之后,API 资源不再发生变化的情况下进行。

    PodNodeSelector插件同样演示了这一活动,他确保 Pod 的spec.nodeSelector字段符合该 Namespace 的限制。如果变更链上有其他 Admission 尝试在PodNodeSelector之后修改了资源的spec.nodeSelector,就会在验证阶段因为不符合限制而被拒绝创建。

    Admission Webhook 是什么?

    Admission webhook 允许 Kubernetes 安装者或集群管理员无需重新编译就可以加入 Admission 插件,像其他基于 k8s.io/apiserver 1.9 的扩展 API Server(例如 metrics(注 2), service-catalog(注 3) 、以及 kube-projects(注 4))一样。两种 Admission Webhook 都在各自的链条尾端运行,和编译的 Admission 插件具有同样的能力和限制。

    有什么好处?

    Webhook Admission 插件允许对任何 API Server 的任何资源进行变更和验证,所以可能有多种形态的应用,比较普通的用例包括:

  • 修改 Pod 这样的资源。Istio 使用这一功能来把 Sidecar 注入到 Pod 之中。当然也可以编写插件强制把 Image Tag 改写为 Image SHA。
  • 在多租户系统中,保留命名空间是一个常见情况。
  • 复杂的 CustomResource 校验。对插件来说,整个资源都是可见的,因此可以对依赖字段甚至外部依赖资源进行复杂的校验(例如 LimitRanges)。
  • 安全响应。可以编写一个插件,强制将 Image Tag 转换为 Image SHA,并阻止特定的 Image 运行。
  • 注册

    Webhook Admission 插件需要注册,所有的 API Server(Kube API server 以及所有扩展 API Server)都共享一个配置。在注册过程中插件需要提供如下信息:

  • 如何连接到 Webhook Admission 服务。
  • 如何验证 Webhook Admission Server。
  • 把请求发送到这个服务器的哪里(URL)。
  • 处理哪些资源和 HTTP 动词。
  • 如果连接失败,API Server 怎么办。
  • apiVersion: admissionregistration.k8s.io/v1beta1
    kind: ValidatingWebhookConfiguration
    metadata:
      name: namespacereservations.admission.online.openshift.io
    webhooks:
    - name: namespacereservations.admission.online.openshift.io
      clientConfig:
        service:
          namespace: default
         name: kubernetes
        path: /apis/admission.online.openshift.io/v1alpha1/namespacereservations
       caBundle: KUBE_CA_HERE
     rules:
     - operations:
       - CREATE
       apiGroups:
       - ""
       apiVersions:
       - "*"
       resources:
       - namespaces
     failurePolicy: Fail

    name:Webhook 的名称。变更类的 Hook 会使用名称进行排序。 clientConfig:如何连接,证书信任,以及如何向 Webhook Admission 服务器发送数据。 rules:API Server 应该在什么时机调用 Webhook。这里只有创建 Namespace 的时候才触发。这里可以指定任何资源,例如serviceinstances.servicecatalog.k8s.io的create操作也是可以定义的。 failurePolicy:如果 Webhook Admission 服务器无法连接,如何处置?有两个选项分别是 ”Ignore“(失败就通过) 和 ”Fail“(失败就拒绝)。失败则通过的设置,可能会导致无法预测的行为。

    认证和信任

    因为 Webhoo Admission 插件能够获取任何发送过来的请求资源的内容,并且能进行变更,所以很有必要回答下面的问题:

    • API Server 如何检验 Webhook Admission Server。
    • Webhook Server 如何精确认证接入进来的 API Server。
    • 接入的 API Server 是否被授权发送请求。

    连接主要分为三种:

  • 从 Kube API Server 以及扩展 API Server 到外部的 Admission Webhook(可能是部署在集群之外)。
  • 从 Kube API Server 到自有 Admission Webhooks。
  • 从扩展 API Server 到自有 Admission Webhooks。
  • 要支持这些类别,Webhook Admission 插件可以用一个 kubeconfig 文件来得知如何连接到独立的服务器。为了和外部的 Admission Webook 进行通信,因为认证、授权都是外部服务器处理的,因此只能手工指定,别无他法。

    自有服务来说,一个明智的插件会提供缺省的安全设施,提供简单、安全、可移植、零配置,并可以在各个 API Server 运行的能力。

    简单、安全、可移植、零配置

    如果把 Webhook Admission 服务器构建成扩展 API Server 的模式,就有可能把它聚合为一个普通的 API 服务器,会收到如下益处:

    • 你的 Webhook 会和其他 API 一样,以类似 kube-apiserver kubernetes.default.svc (例如 https://kubernetes.default.svc/apis/admission.example.com/v1/mymutatingadmissionreviews)服务的面目出现。可以使用kubectl进行测试。
    • 无需任何配置,你的 Webhook 自动具有了集群内置的认证和授权能力,可以使用 RBAC 规则进行访问控制。
    • API Server 和 Webhook 之间可以直接使用内置认证进行通信。
    • 因为通过 Kube API Server 代理通信,因此扩展 API Server 不会泄露 Service Account Token。

    简单说来,这一安全拓扑可以使用 API Server 的所有安全机制,并且无需额外配置。

    其他用法也是可以的,不过就需要附加的手工配置,以及大量的额外工作来完成同等目标。

    如何开发 Webhook admission 服务器?

    编写一个具有认证和鉴权能力的完整的服务是个令人生畏的任务。为简化这一工作,有些基于 Kubernetes 1.9 的项目提供了库支持,能把代码量缩减到两百行甚至更少。可以参考 generic-admission-apiserver(注 5)以及 kubernetes-namespace-reservation(注 6)作为创建自己的安全、可移植的 Webhook Server 的示例。

    在 1.9 中有了 Admission Webhook,让 Kubernetes 更加贴近用户需求,我们希望 Red Hat 和 Google 的这一工作能让支持更多的工作负载,为整体生态贡献更多(例如 Istio),现在是时候试一试了!

    如果有兴趣做出贡献或者反馈,请加入 SIG API machinery(注 7)

    注:

  • https://kubernetes.io/docs/admin/admission-controllers/#what-are-they
  • https://github.com/kubernetes/metrics
  • https://github.com/kubernetes-incubator/service-catalog
  • https://github.com/openshift/kube-projects
  • https://github.com/openshift/generic-admission-server
  • https://github.com/openshift/kubernetes-namespace-reservation
  • https://github.com/kubernetes/community/tree/master/sig-api-machinery
  • 相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论