当前位置:   article > 正文

Controlling Access to the Kubernetes API 和 dynamic Admission control

dynamic admission control

我们通过 kubectl、或者自己写程序,是可以调用apiserver的api接口的,但是我这里有两个问题:
1)访问apiserver的时候,我们需要做哪些事情?apiserver对访问的用户有没有什么需求?

首先,需要说明的是,在k8s中可以使用两种用户来访问apiserver,分别是普通用户和k8s的service account. 对于普通用户来说,他只是对于外部来说的,并不是k8s的对象,也不会在k8s中部署。而对于普通用户来说,会给这个用户绑定指定证书的权限,之后普通用户既可以访问apiserver的api.
但是对于service account,会通过给这个serviceaccount,绑定指定的权限让他有权限来访问service api. 一般来说,部署在k8的pod会使用service account这种用户来访问apiserver指定的资源。

2)当apiserver收到client的请求时,apiserver自己又做了哪些事情呢?

When a request reaches the API, it goes through several stages, illustrated in the following diagram:
当访问apiserver, apiserver会经过如下几个阶段,也可以看下面这个图。
access kubernetes api step
Human User/kubernetes serviceAccount—–>Transport Security -->Authentication—>Authorization---->Admission Control---->存入存储。
在这里插入图片描述

1)Authentication(认证)

一旦开启了tls,所有的请求都需要先通过认证,可以为apiserver配置很多 Authenticator Modulers,这些模块会被依次执行。只要有一个通过了,就表示认证成功了。之后会进入授权模块

2)Authorization(授权)

授权和认证相同,在k8中,也有很多种授权方式,例如ABAC模式,RBAC模式和Webhook模式。 管理员创建集群时,他们配置了应该在API服务器中使用的授权模块。 如果配置了多个授权模块,则Kubernetes会检查每个模块,如果有任何模块授权该请求,则该请求可以继续进行。 如果所有模块均拒绝该请求,则该请求将被拒绝(HTTP状态码403)。
目前一般基于RBAC的比较多一点,感兴趣可以看这个https://kubernetes.io/docs/reference/access-authn-authz/authorization
After the request is authenticated as coming from a specific user, the request must be authorized.
将请求验证为来自特定用户后,这个特定用户会有权限。

例如,如果Bob具有以下策略,那么他只能在名称空间projectCaribou中读取pod:

{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "projectCaribou",
        "resource": "pods",
        "readonly": true
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

If Bob makes the following request, the request is authorized because he is allowed to read objects in the projectCaribou namespace:
如果Bob发出如下的请求,则该请求将会被授权,因为它允许在projectCaribou ns中读取对象。但是如果Bob想发生写的请求,则将会被拒绝。

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "namespace": "projectCaribou",
      "verb": "get",
      "group": "unicorn.example.org",
      "resource": "pods"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3)admision control

Admission Control Modules are software modules that can modify or reject requests.
In addition to the attributes available to Authorization Modules, Admission Control Modules can access the contents of the object that is being created or updated. They act on objects being created, deleted, updated or connected (proxy), but not reads.

准入控制模块是可以修改或拒绝请求的软件模块。 除授权模块可用的属性外,准入控制模块还可以访问正在创建或更新的对象的内容。 它们作用于正在创建,删除,更新的对象,但不读取。
控制器遵循如下几个原则:

  • 可以配置多个准入控制器,每个被依次调用。
  • 如果有任何一个控制器被拒绝,则该请求会立即被拒绝
  • 准入模块可以为操作的对象,加上一些默认值,或进行一些校验
  • 请求通过所有准入控制器后,将使用相应API对象的验证例程对其进行验证,然后将其写入对象存储(如步骤4所示)。

Using Admission Controllers

准入控制器是一段代码,用于在对象持久化之前但在请求得到验证和授权之后,截取对Kubernetes API服务器的请求。
controllers 有很多controller组成,且都内置于 kube-apiserver的 binary,且只能由集群管理员配置。

在这些控制器中,有两个特殊的控制器:MutatingAdmissionWebhook和ValidatingAdmissionWebhook。 它们分别执行在API中配置的Mutating(变异)和验证准入控制Webhook。

准入控制过程分为两个阶段。 在第一阶段,运行变异许可控制器。 在第二阶段,运行验证准入控制器。

Kubernetes中的许多高级功能都需要启用接纳控制器才能正确支持该功能。 因此,未正确配置正确的访问控制器集的Kubernetes API服务器是不完整的服务器,将不支持您期望的所有功能。

可以通过命令行的方式让apiserver启动admission controller,默认会启动如下的几个:

kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
  • 1

禁用admission controller

kube-apiserver --disable-admission-plugins=PodNodeSelector,
  • 1

What does each admission controller do? 我们可以看其中的一个例子
1)AlwaysPullImages
This admission controller modifies every new Pod to force the image pull policy to Always. 这个功能很有用,比如对于多租户的场景,可以确保用户拥有权限之后才能拉取镜像,而且每次都是从新拉,但是如果没有这个控制器,那么一旦镜像到了这个节点,就可以跑起来了,安全性就会做的很差。

其他详细的controller可以看这个地址 https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/

Dynamic Admission Control

什么是Dynamic Admission Control

我们来看官网对于Dynamic Admission Control的描述:

In addition to compiled-in admission plugins, admission plugins can be developed as extensions and run as webhooks configured at runtime.
  • 1

通俗地讲:即是,除了K8s内置的Admission plugin, 我们也可以自定义Admission plugin 作为扩展,自定义的Admission plugin可以配置给k8s集群,之后自定义插件可以作为 admission webhook来执行。

为什么需要Dynamic Admission Control(initializer)?

1) 我们来思考一个如下的场景,在就绪的kubernetes集群上,我们有如下需求,我们需要在创建pod前,给pod打上一些label或执行一些操作,那么我们需要修改apiserver代码,之后,重新编译,部署新的apiserver二进制,这样,线上的apiserver的服务,需要重启,显然是不合适的,所以k8s的apiserver提供了热插拔的机制,即是dynamic admission control。
2) webhook 可动态扩展 Admission 能力,满足自定义客户的需求

成功使用此功能的开源项目:
比如:istio的 sidecar 注入 就使用了apiserver的 Dynamic Admission Control,也叫Initializer. 会在pod创建前,给pod的spec中填充sidecar容器的相关属性。

如何使用Dynamic Admission Control?

在说如何使用之前,我们先了解一下admission webhook.且k8s集群必须满足如下条件:

  • 1)k8s v1.16 (to use admissionregistration.k8s.io/v1), or k8s v1.9 (to use admissionregistration.k8s.io/v1beta1).
  • 2)集群的MutatingAdmissionWebhook和ValidatingAdmissionWebhook admission controllers 已经启动。

一般情况下会启动如下几个controler:可以看到这两个controller是在里面启动的。

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
  • 1

Q1: 什么是admission webhook?

其实他就是一个http的callback,当收到admission request时,会执行一些操作。
k8s有两种类型的admission webhook,validate和mutating两种, mutating会优先执行,这种webhook会修改k8s的资源对象,之后可以通过validate来对修改后的对象进行校验。

Step 1: write an admission webhook server:

k8s 会创建AdmissionReview 对象发送给webhook server,webhook server处理之后会返回AdmissionReview对象。

准入webhook示例服务器将ClientAuth字段保留为空,默认为NoClientCert。 这意味着webhook服务器不会对客户端(假定为apiserver)的身份进行身份验证。 如果您需要双向TLS或其他方式来认证客户端,下面有认证方式。
可以参考官网 https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#authenticate-apiservers

Step 2: deploy the admission webhook service

可以将这个webhook service 部署在k8s集群内或k8s集群外.但是这个服务地址需要在admission controller的配置文件中配置。

Step 3: configure admission webhooks on the fly

You can dynamically configure what resources are subject to what admission webhooks via ValidatingWebhookConfiguration or MutatingWebhookConfiguration.
你可以动态的配置什么样的资源从属于,受什么样的adminssion webhooks 所管理。

注册此admission webhook, 告诉apiserver应该使用自己。方式是通过创建MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration API 对象。

下面是一个ValidatingWebhookConfiguration的配置,具体详细的配置使用参照k8s官方API

# Deprecated in v1.16 in favor of admissionregistration.k8s.io/v1
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: "pod-policy.example.com"
webhooks:
- name: "pod-policy.example.com"
  rules:
  - apiGroups:   [""]
    apiVersions: ["v1"]
    operations:  ["CREATE"]
    resources:   ["pods"]
    scope:       "Namespaced"
  clientConfig:
    service:
      namespace: "example-namespace"
      name: "example-service"
    caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate>...tLS0K"
  admissionReviewVersions: ["v1beta1"]
  timeoutSeconds: 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意下面的问题:

  • rules代表要处理的资源的限定,其中scope 有如下值,Cluster,Namespaced和*, cluster和*代表没有限制,namespaced代表是只处理namespace资源。
  • v1 API版本默认timeoutSeconds为10s,v1beta1为30s,从k8s 1.14之后可以设置timeout时间, 如果调用Webhook超时,则会根据Webhook的失败政策处理请求。
  • 当apiserver收到与其中一个规则匹配的请求时,该apiserver会按照clientConfig中指定的方式向webhook发送一个admissionReview请求。svcName.ns即是服务地址。需要注意的是,当创建webhook配置后,系统将花费几秒钟时间来接受新配置。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/478252
推荐阅读
相关标签
  

闽ICP备14008679号