Kubernetes之十八---K8s准入控制基础应用

1、访问控制概述

       API Server 作为 Kubernetes 集群系统的网关,是访问及管理资源对象的唯一人口,余 下所有需要访问集群资源的组件,包括 kube-controller-manager、 kube-scheduler、 kubelet 和 kube-proxy 等集群基础组件、 CoreDNS 等集群的附加组件以及此前使用的 kubectl 命令等都 要经由此网关进行集群访问和管理。 这些客户端均要经由 API Server 访问或改变集群状态并 完成数据存储,并由它对每一次的访问请求进行合法性检验,包括用户身份鉴别、 操作权限 验证以及操作是否符合全局规范的约束等。 所有检查均正常完成且对象配置信息合法性检验 无误之后才能访问或存人数据于后端存储系统 etcd 中。

 

2、准入控制基础

 1)为了核验用户的操作许可,成功通过身份认证后的操作请求还需要转交给授权插件进 行许可权限检查,以确保其拥有执行相应的操作的许可。 API Server 主要支持使用四类内建 的授权插件来定义用户的操作权限。 

  • Node : 基于 Pod 资源的目标调度节点来实现的对 kubelet 的访问控制。
  • ABAC: attribute-based access control, 基于属性的访问控制。
  • RBAC: role-based access control,基于角色的访问控制。
  • Webhook: 基于 HTTP 回调机制通过外部 REST 服务检查确认用户授权的访问控制。 

        另外,还有 AlwaysDeny 和 AlwaysAllow 两个特殊的授权插件,其中 AlwaysDeny (总 是拒绝)仅用于测试,而 AlwaysAllow (总是允许) 则用于不期望进行授权检查时直接于授 权检查阶段放行的所有操作请求。 启动 API Server 时, “ --authorization-mode”选项用于定 义要启用的授权机制,多个选项彼此之间以逗号分隔。 

 

  2)而准入控制器 ( Admission Controller)则用于在客户端请求经过身份验证和授权检查之 后,但在对象持久化存储 etcd 之前拦截请求,用于实现在资源的创建、 更新和删除操作期 间强制执行对象的语义验证等功能 ,读取资源信息的操作请求不会经由准入控制器的检查。 API Server 内置了许多准入控制器,常用的包含如下几种。 不过, 其中的个别控制器仅在较 新版本的 Kubernetes 中才受支持。 

  1. AlwaysAdmit:允许所有请求。
  2. AlwaysDeny:拒绝所有请求 ,仅应该用于测试。
  3. AlwaysPulllmages :总是下载镜像,即每次创建 Pod 对象之前都要去下载镜像,常用于多租户环境中以确保私有镜像仅能够被拥有权限的用户使用。
  4. NamespaceLifecycle :拒绝于不存在的名称空间中创建资源,而删除名称空间将会 级联删除其下的所有其他资源。
  5. LimitRanger :可用资源范围界定,用于监控对设置了 LimitRange 的对象所发出的 所有请求,以确保其资源、请求不会超限。
  6. ServiceAccount :用于实现 Service Account 管控机制的自动化,实现创建 Pod 对象 时自动为其附加相关的 Service Account 对象。
  7. PersistentVolumeLabel :为那些由云计算服务商提供的 PV 自动附加 region 或 zone 标签,以确保这些存储卷能够正确关联且仅能关联到所属的 region 或 zone。
  8. DefaultStorageClass :监控所有创建 PVC 对象的请求,以保证那些没有附加任何专 用 Storag巳Class 的请求会自动设定一个默认值。
  9. ResourceQuota : 用于对名称空间设置可用资源的上限,并确保在其中创建的任何设 置了资源限额的对象都不会超出名称空间的资源配额。
  10. DefaultTolerationSeconds :如果 Pod 对象上不存在污点宽容期限,则为它们设置默 认的宽容期,以宽容“ notready:N oExecute”和“ unreachable:N oExctute ”类的污点 5 分钟 时间。
  11. ValidatingAdmission Webhook :并行调用匹配当前请求的所有验证类的 Webhook, 任何一个校验失败,请求即失败。
  12. MutatingAdmissionWebhook :串行调用匹配当前请求的所有变异类的 Webhook, 每个调用都可能会更改对象。

  3)在经由认证插件和授权插件分别完成身份认证和权限检查之后,准入控制器将拦截 那些创建、 更新和删除相关的操作请求以强制实现控制器中定义的功能,包括执行对象的 语义验证、设置缺失字段的默认值、 限制所有容器使用的镜像文件必须来 自 某个特定的 Registry、检查 Pod 对象的资源需求是否超出了指定的限制范围等。

       在具体运行时,准入控制可分为两个阶段, 第一个阶段串行运行各变异型控制器, 第 二个阶段串行运行各验证型控制器,在此过程中,一旦任一阶段中的任何控制器拒绝请求, 则立即拒绝整个请求,并向用户返回错误。

 

3、限制CPU使用大小

3.1 LimitRange 资源与 LimitRanger 准入控制器

        虽然用户可以为容器指定资源需求及资源限制,但未予指定资源限制属性的容器 应用很有可能因故吞掉所在工作节点上的所有可用计算资源,因此妥当 的做法是使用 LimitRange 资源在每个名称空间中为每个容器指定最小及最大计算资源用量,甚至是设置 默认的计算资源需求和计算资源限制。 在名称空间上定义了 LimitRange 对象之后, 客户端 提交创建或修改的资源对象将受到 LimitRanger 控制器的检查,任何违反 LimitRang巳对象 定义的资源最大用量的请求将被直接拒绝。 

        LimitRange 资源支持限制容器、 Pod 和 PersistentVolumeClaim 三种资源对象的系统资 源用量,其中 Pod 和容器主要用于定义可用的 CPU 和内存资源范围,而 PersistentVolumeClaim 则主要定义存储空间的限制范围。 下面的配置清单以容器的 CPU 资源为例, default 用于定义默认的资源限制 , defaultRequest 定义默认的资源需求, min 定义最小的资源用量,而最大的资源用量既可以使用 max 给出固定值, 也可以使用 maxLimitRequestRatio 设定为 最小用量的指定倍数:

 

1、创建限制CPU大小规则

1、创建一个使用CPU限制的yaml文件,可以看出此时使用的最小CPU为500m,最大是2000m,maxLimitRequestRatio表示最大和最小的CPU倍数,如果创建的pod没指定使用CPU大小,默认就是1000m。 

[root@master ~]# kubectl create ns myns   # 创建myns名称空间,方便做实验
namespace/myns created

[root@master ~]# cat limitrange-demo.yaml  # 创建限制CPU信息
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-limit-range
spec:
  limits:
  - default:
      cpu: 1000m
    defaultRequest:
      cpu: 1000m
    min:
      cpu: 500m
    max:
      cpu: 2000m
    maxLimitRequestRatio:                   # 限制最大CPU和最小CPU的倍数
      cpu: 4
    type: Container

  

2、基于limitrange-demo.yaml文件,创建限制CPU大小的规则

[root@master ~]# kubectl apply -f limitrange-demo.yaml -n myns
limitrange/cpu-limit-range created

  

3、查看此时创建limitrange详细信息

[root@master ~]# kubectl get limitrange  -n myns  # 查看此时的limitrange信息
NAME              CREATED AT
cpu-limit-range   2020-08-09T02:10:21Z

[root@master ~]# kubectl describe limitrange -n myns
Name:       cpu-limit-range
Namespace:  myns
Type        Resource  Min   Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---  ---------------  -------------  -----------------------
Container   cpu       500m  2    1                1              4

  

2、自定义一个默认pod资源

1、定义一个pod,此时我们并未做任何的资源限制,就会创建默认的1000m的CPU,目的只是为了验证默认CPU占用效果

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp

  

2、基于yaml文件创建pod

[root@master ~]# kubectl apply -f pod-demo.yaml -n myns
pod/pod-demo created

  

3、查看此时Pod运行的CPU大小和状态

[root@master ~]# kubectl get pods -n myns
NAME       READY   STATUS    RESTARTS   AGE
pod-demo   1/1     Running   0          41s

[root@master ~]# kubectl describe pods pod-demo -n myns         # 查看pod的详细信息
Containers:
  myapp:
    Container ID:   
    .........  # 省略信息
    State:          Running
      Started:      Sun, 09 Aug 2020 10:15:51 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:  1        # 限制CPU个数为1
    Requests:        # 限制CPU请求个数为1
      cpu:        1

  

3、自定义限制最小CPU请求

1、删除前面未限制的CPU请求的pod

[root@master ~]# kubectl delete -f pod-demo.yaml -n myns
pod "pod-demo" deleted

  

2、开始创建限制CPU使用大小的数量,限制最小请求数为200m。

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 200m

  

3、执行yaml文件,创建新的pod,此时创建pod就会报错,是因为前面我们对容器限制最小请求500m,而我们只限制请求了200m,小于最小请求的大小,就无法创建pod。

[root@master ~]# kubectl apply -f pod-demo.yaml 
Error from server (Forbidden): error when creating "pod-demo.yaml": pods "pod-demo" is forbidden: [minimum cpu usage per Container is 500m, but request is 200m, cpu max limit to request ratio per Container is 4, but provided ratio is 5.000000]

  

4、限制最大请求CPU数

1、将CPU请求的值设置为最小请求3000m

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 3000m

  

2、执行yaml文件并创建pod,此时由于我们设置的最大CPU是2000m,而我们创建pod时,设置到了最小请求为3000m,也无法创建pod。

[root@master ~]# kubectl apply -f pod-demo.yaml 
The Pod "pod-demo" is invalid: spec.containers[0].resources.requests: Invalid value: "3": must be less than or equal to cpu limit

  

4、自定义一个合理范围内的CPU数

1、创建一个与limitrange限制最小请求CPU数一样,最大请求书比自定义limitrange限制CPU大的pod

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
      limits:
        cpu: 1500m

  

2、基于yaml文件创建Pod,此时定义在正常的范围内,上限比容器限制的大也无所谓,也可以运行,取决于运行pod的实际占用CPU大小

[root@master ~]# kubectl apply -f pod-demo.yaml -n myns
pod/pod-demo created

  

4、ResourceQuota 资源与准入控制器

       尽管 LimitRange 资源能限制单个容器、 Pod 及 PVC 等相关计算资源或存储资源的用量, 但用户依然可以创建数量众多的此类资源对象进而侵占所有的系统资源。 于是, Kubernetes 提供了 ResourceQuota 资源用于定义名称空间的对象数量或系统资源配额,它支持限制每种 资源类型的对象总数,以及所有对象所能消耗的计算资源及存储资源总量等。 ResourceQuota 准入控制器负责观察传入的请求,并确保它没有违反相应名称空间中 ResourceQuota 对象定 义的任何约束。 

      于是,管理员可为每个名称空间分别创建一个 ResourceQuota 对象,随后 ,用户在名 称空间中创建资源对象, ResourceQuota 准入控制器将跟踪使用情况以确保它不超过相应 ResourceQuota 对象中定义的系统资源限制。 用户创建或更新资源的操作违反配额约束将导 致请求失败, API Server 以 HTTP 状态代码“403 FORBIDDEN ”作为响应,并显示一条消 息以提示可能违反的约束。 不过,在名称空间上启用了 CPU 和内存等系统资源的配额后, 用户创建 Pod 对象时必须指定资源需求或资源限制,否则,会触发 ResourceQuota 准入控制 器拒绝执行相应的操作。

ResourceQuota 对象可限制指定名称空间中非终止状态的所有 Pod 对象的计算资源需求 及计算资源限制总量。 

  • cpu 或 requests.cpu: CPU 资源需求的总量限额。
  • memory 或 requests.cpu:内存资源需求的总量限额。
  • limits.cpu: CPU 资源限制的总量限额。
  • limits.memory:内存资源限制的总量限额。 

ResourceQuota 对象支持限制特定名称空间中可以使用的 PVC 数量和这些 PVC 资源 的空间大小总量,以及特定名称空间中可在指定的 StorageC!ass 上使用的 PVC 数量和这些 PVC 资源的总数: 

  • requests.storage :所有 PVC 存储需求的总量限额。
  • persistentvolumeclaims :可以创建的 PVC 总数。
  • <stor吨e-class-name>.storagecl ass. storage.k8s. io/requests. storage :指定存储类上可使 用的所有 PVC 存储需求的总量限额。
  • <storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims :指定存储类 上可使用的 PVC 总数。
  • requests.ephemeral-storage :所有 Pod 可用的本地临时存储需求的总量。
  • limits.ephemeral-storage :所有 Pod 可用的本地临时存储限制的总量。

 

1、创建ResourceQuota控制规则

1、创建限制内存和CPU大小的yaml文件

[root@master ~]# cat resoucequota-demo.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-example
spec:
  hard:
    pods: "5"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    count/deployments.apps: "2"
    count/deployments.extensions: "2"
    persistentvolumeclaims: "2"

  

2、基于yaml文件创建规则

[root@master ~]# kubectl apply -f resoucequota-demo.yaml -n myns
resourcequota/quota-example created

  

3、查看 resourcequota规则详细信息

[root@master ~]# kubectl get resourcequota -n myns
NAME            CREATED AT
quota-example   2020-08-09T02:54:33Z

[root@master ~]# kubectl describe resourcequota quota-example -n myns   # 查看详细信息
Name:                         quota-example
Namespace:                    myns
Resource                      Used   Hard
--------                      ----   ----
count/deployments.apps        0      2
count/deployments.extensions  0      2
limits.cpu                    1500m  2      # CPU最大使用了1500m,1500m代表1.5,硬限制到2
limits.memory                 0      2Gi    # 硬限制内存多少
persistentvolumeclaims        0      2
pods                          1      5
requests.cpu                  500m   1      # CPU下限多少
requests.memory               0      1Gi

  

2、创建一个新pod,进行测试

1、此时创建一个新的上限为1000m的cpu限制pod

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo-2
  labels:
    app: pod-demo
    rel: stable
  annotations:
    ik8s.io/project: hello
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
        memory: 500Mi
      limits:
        cpu: 1000m       # 创建一个上限为1000m的pod
        memory: 1Gi

  

2、此时由于前面最大已经使用了1500m,这里创建的新pod的CPU使用设置最大上限值为1000m,超过了硬限制的hard值2,此时就无法创建新的pod资源

[root@master ~]# kubectl apply -f  pod-demo1.yaml -n myns
Error from server (Forbidden): error when creating "pod-demo1.yaml": pods "pod-demo-2" is forbidden: exceeded quota: quota-example, requested: limits.cpu=1, used: limits.cpu=1500m, limited: limits.cpu=2

  

3、创建合理大小的Pod资源

1、此时将此Pod的最大CPU使用个数改为500m,与前面已经使用了1500m相加,刚好是2个CPU,就可以创建新的Pod

[root@master ~]# cat  pod-demo1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo-2
  labels:
    app: pod-demo
    rel: stable
  annotations:
    ik8s.io/project: hello
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
        memory: 500Mi
      limits:
        cpu: 500m
        memory: 1Gi

  

2、此时执行yaml文件,就可以创建新的pod

[root@master ~]# kubectl apply -f  pod-demo1.yaml -n myns
pod/pod-demo-2 unchanged

  

3、查看resourcequota详细信息,此时创建的2个pod使用的最大值就是2G,硬限制也是2G

[root@master ~]# kubectl describe resourcequota quota-example -n myns
Name:                         quota-example
Namespace:                    myns
Resource                      Used   Hard
--------                      ----   ----
count/deployments.apps        0      2
count/deployments.extensions  0      2
limits.cpu                    2      2    # 此时使用的最大值就是2G,硬限制也是2G
limits.memory                 1Gi    2Gi
persistentvolumeclaims        0      2
pods                          2      5
requests.cpu                  1      1
requests.memory               500Mi  1Gi

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章