CKA 10_Kubernetes工作负载与调度 资源调度 资源限制 LimitRanger 资源配额 ResourceQuota

文章目录

  • 1. 资源调度
    • 1.1 资源限制
      • 1.1.1 namespace 设置 资源限制
    • 1.2 资源配额
      • 1.2.1 namespace 设置 资源配额
        • 1.2.1.1 限制 内存 和 CPU
        • 1.2.1.2 限制 Pod 数量

1. 资源调度

官方文档: 概念 | 策略 | 限制范围

官方文档: 概念 | 策略 | 资源配额

1.1 资源限制

  • 默认情况下, Kubernetes 集群上的容器运行使用的计算资源没有限制。 使用资源配额,集群管理员可以以名字空间为单位,限制其资源的使用与创建。 在命名空间中,一个 Pod 或 Container 最多能够使用命名空间的资源配额所定义的 CPU 和内存用量。 有人担心,一个 Pod 或 Container 会垄断所有可用的资源。 LimitRange 是在命名空间内限制资源分配(给多个 Pod 或 Container)的策略对象。

  • 一个 LimitRange(限制范围) 对象提供的限制能够做到:

    • 在一个命名空间中实施对每个 Pod 或 Container 最小和最大的资源使用量的限制。
    • 在一个命名空间中实施对每个 PersistentVolumeClaim 能申请的最小和最大的存储空间大小的限制。
    • 在一个命名空间中实施对一种资源的申请值和限制值的比值的控制。
    • 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个 Container 中。
  • 限制范围总览

    • 管理员在一个命名空间内创建一个 LimitRange 对象。
    • 用户在命名空间内创建 Pod ,Container 和 PersistentVolumeClaim 等资源。
    • LimitRanger 准入控制器对所有没有设置计算资源需求的 Pod 和 Container 设置默认值与限制值, 并跟踪其使用量以保证没有超出命名空间中存在的任意 LimitRange 对象中的最小、最大资源使用量以及使用量比值。
    • 若创建或更新资源(Pod、 Container、PersistentVolumeClaim)违反了 LimitRange 的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码 403 FORBIDDEN 与描述哪一项约束被违反的消息。
    • 若命名空间中的 LimitRange 启用了对 cpu 和 memory 的限制, 用户必须指定这些值的需求使用量与限制使用量。否则,系统将会拒绝创建 Pod。
    • LimitRange 的验证仅在 Pod 准入阶段进行,不对正在运行的 Pod 进行验证。

1.1.1 namespace 设置 资源限制

  1. 设置资源限制
  • 内存中不能有 swap 分区
  • 内存是不可压缩的资源,而 CPU 可以压缩。如果内存超出了限制,那么会被直接杀死,但是 CPU 不会
[root@k8s-1 ~]# vim limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-demo
spec:
  limits:				// 上限
  - default:			// 当 limit 不设置时,cpu 和 memory 的上限默认为 0.5 和 512Mi
      cpu: 0.5			
      memory: 512Mi
    defaultRequest:		// 当默认不设置时,cpu 和 memory 最小为 0.1 和 256Mi
      cpu: 0.1
      memory: 256Mi
    max:				// 最大不能超过这个值
      cpu: 1
      memory: 1Gi
    min:				// 最小不能低于这个值
      cpu: 0.1
      memory: 100Mi
    type: Container
  1. 生效后,查看资源限制的状态信息
[root@k8s-1 ~]# kubectl apply -f limitrange.yaml 
limitrange/limitrange-demo created
[root@k8s-1 ~]# kubectl get limitranges 
NAME              CREATED AT
limitrange-demo   2022-05-11T12:19:14Z
  • 限制的信息就是 YAML 清单中设置的
[root@k8s-1 ~]# kubectl describe limitranges 
Name:       limitrange-demo
Namespace:  default
Type        Resource  Min    Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---    ---  ---------------  -------------  -----------------------
Container   cpu       100m   1    100m             500m           -
Container   memory    100Mi  1Gi  256Mi            512Mi          -
  1. 测试资源限制,创建名为 demo 的 Pod
[root@k8s-1 ~]# kubectl run demo --image=nginx
pod/demo created
[root@k8s-1 ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
demo   1/1     Running   0          90s
  • 查看 Pod 的上线状态,发现 Pod 的资源被限制

  • 因为 Pod 没有设定 limit 和 request,所以,限制是跟着 Default 走的

  • 上限为 500m 的 CPU 和 512Mi 的 内存

  • 最小的请求量为 100m 的 CPU 和 256Mi 的 内存

  • 以上限制内容都是 资源限制 limitranger 中设置的

[root@k8s-1 ~]# kubectl describe pod demo
    Limits:
      cpu:     500m
      memory:  512Mi
    Requests:
      cpu:        100m
      memory:     256Mi

Volumes:
  kube-api-access-j8c98:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
  1. 删除该 Pod 后,创建设置了资源限制的 Pod
  • 快速生成 Pod 的 YAML 模板
[root@k8s-1 ~]# kubectl run demo --image=nginx --dry-run=client -o yaml > pod.yaml
[root@k8s-1 ~]# kubectl run demo --image=nginx --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: demo
  name: demo
spec:
  containers:
  - args:
    - pod.yaml
    image: nginx
    name: demo
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 修改 Pod.yaml
  • CPU 最小不能低于 1
  • CPU 最大不能超过 2
[root@k8s-1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: demo
  name: demo
spec:
  containers:
  - image: nginx
    name: demo
    resources: 
      requests:
        cpu: 1
      limits:
        cpu: 2
  • 生效时,出现报错。
  • 因为 Pod 的 request 设置的是 1 ,limit 设置的是 2
  • 而 资源限制 limitranger 要求当Pod 设置限制时, 其 CPU 最小不能低于 100m,最大不能超过 1
  • 当前 Pod 的 CPU limit 超出了 limitranger 的限制
[root@k8s-1 ~]# kubectl apply -f pod.yaml 
Error from server (Forbidden): error when creating "pod.yaml": pods "demo" is forbidden: maximum cpu usage per Container is 1, but limit is 2
[root@k8s-1 ~]# kubectl describe limitranges 
Name:       limitrange-demo
Namespace:  default
Type        Resource  Min    Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---    ---  ---------------  -------------  -----------------------
Container   cpu       100m   1    100m             500m           -
Container   memory    100Mi  1Gi  256Mi            512Mi          -
  1. LimitRange 在 namespace 中施加的最小和最大内存限制只有在创建和更新 Pod 时才会被应用。改变 LimitRange 不会对之前创建的 Pod 造成影响。

1.2 资源配额

  • 当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。

  • 资源配额是帮助管理员解决这一问题的工具。

  • 资源配额,通过 ResourceQuota 对象来定义,对每个命名空间的资源消耗总量提供限制。 它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命令空间中的 Pod 可以使用的计算资源的总上限。

  • 资源配额的工作方式如下:

    • 不同的团队可以在不同的命名空间下工作,目前这是非约束性的,在未来的版本中可能会通过 ACL (Access Control List 访问控制列表) 来实现强制性约束。

    • 集群管理员可以为每个命名空间创建一个或多个 ResourceQuota 对象。

    • 当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会 跟踪集群的资源使用情况,以确保使用的资源用量不超过 ResourceQuota 中定义的硬性资源限额。

    • 如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。

    • 如果命名空间下的计算资源 (如 cpu 和 memory)的配额被启用,则用户必须为 这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 Pod 设置默认值。

1.2.1 namespace 设置 资源配额

1.2.1.1 限制 内存 和 CPU

  1. 设置资源配额
  • CPU 最少不能低于 1
  • 内存 最少不能低于 1Gi
  • CPU 最大不能超过 2
  • 内存 最大不能超过 2Gi
[root@k8s-1 ~]# vim quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
  1. 生效 资源配额
[root@k8s-1 ~]# kubectl apply -f quota.yaml 
resourcequota/mem-cpu-demo created
  1. 对 namespace 加了 资源配额 之后,创建的 Pod 都必须设置 资源限制 limitranger ,不设置会报错
  2. 模拟故障:删除 limitranger 资源限制,令当前处于只有 资源配额 ,没有 资源限制 的状态
  • 假设删除了 limitranger ,那么当前 namespace 是没有任何 资源限制
[root@k8s-1 ~]# kubectl delete -f limitrange.yaml 
limitrange "limitrange-demo" deleted
[root@k8s-1 ~]# kubectl get limitranges 
No resources found in default namespace.
  • 创建 Pod 发现报错,无法创建
  • 因为 Pod 没有 资源限制
[root@k8s-1 ~]# kubectl run demo --image=nginx
Error from server (Forbidden): pods "demo" is forbidden: failed quota: mem-cpu-demo: must specify limits.cpu,limits.memory,requests.cpu,requests.memory
  • 生效 资源限制
[root@k8s-1 ~]# kubectl apply -f limitrange.yaml 
limitrange/limitrange-demo created
  • 再次 创建 Pod ,发现创建成功
  • 因为创建了 资源限制 limitrange 的 namespace 会自动为 Pod 施加限制
  • limitranger 限制 Pod 的 资源如下,在 资源配额 的要求范围内
[root@k8s-1 ~]# kubectl run demo --image=nginx
pod/demo created
[root@k8s-1 ~]# kubectl describe pod demo
    Limits:
      cpu:     500m
      memory:  512Mi
    Requests:
      cpu:        100m
      memory:     256Mi
  1. 查看 资源配额 中 已使用部分和未使用部分
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used   Hard
--------         ----   ----
limits.cpu       500m   2
limits.memory    512Mi  2Gi
requests.cpu     100m   1
requests.memory  256Mi  1Gi
  1. 资源配额也限制了 Pod 的数量
[root@k8s-1 ~]# kubectl run demo2 --image=nginx
pod/demo2 created
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used   Hard
--------         ----   ----
limits.cpu       1      2
limits.memory    1Gi    2Gi
requests.cpu     200m   1
requests.memory  512Mi  1Gi
[root@k8s-1 ~]# kubectl run demo3 --image=nginx
pod/demo3 created
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used    Hard
--------         ----    ----
limits.cpu       1500m   2
limits.memory    1536Mi  2Gi
requests.cpu     300m    1
requests.memory  768Mi   1Gi
  • 当前已经有 4 个 Pod 了,资源配额已使用完
[root@k8s-1 ~]# kubectl run demo4 --image=nginx
pod/demo4 created
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used  Hard
--------         ----  ----
limits.cpu       2     2
limits.memory    2Gi   2Gi
requests.cpu     400m  1
requests.memory  1Gi   1Gi
  • 再次创建 Pod 会报错,因为已经没有足够的资源配额了
[root@k8s-1 ~]# kubectl run demo5 --image=nginx
Error from server (Forbidden): pods "demo5" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=500m,limits.memory=512Mi,requests.memory=256Mi, used: limits.cpu=2,limits.memory=2Gi,requests.memory=1Gi, limited: limits.cpu=2,limits.memory=2Gi,requests.memory=1Gi
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used  Hard
--------         ----  ----
limits.cpu       2     2
limits.memory    2Gi   2Gi
requests.cpu     400m  1
requests.memory  1Gi   1Gi
  1. 留下一个 Pod
[root@k8s-1 ~]# kubectl delete pod demo2 --force 
[root@k8s-1 ~]# kubectl delete pod demo3 --force 
[root@k8s-1 ~]# kubectl delete pod demo4 --force 
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used   Hard
--------         ----   ----
limits.cpu       500m   2
limits.memory    512Mi  2Gi
requests.cpu     100m   1
requests.memory  256Mi  1Gi
  1. 配额资源限制资源限制 范围大。
    资源限制 是指限制 Pod 每次使用的资源;
    而 配额资源限制 是指限制所有 Pod 使用的资源总和;
    如果只创建了 配额资源限制,没有创建 资源限制,
    那么可能创建的第一个 Pod 就把所有的 配额资源 使用了,导致不能再创建多余的 Pod

1.2.1.2 限制 Pod 数量

  1. 修改 资源配额 的 YAML 清单
  • 限制只能创建 2 个 Pod
[root@k8s-1 ~]# vim quota.yaml 
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    pods: "2"
  1. 生效后,查看资源配额
  • 总共可以创建 2 个 Pod,已经存在了 1 个 Pod
[root@k8s-1 ~]# kubectl apply -f quota.yaml 
resourcequota/mem-cpu-demo configured
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used   Hard
--------         ----   ----
limits.cpu       500m   2
limits.memory    512Mi  2Gi
pods             1      2
requests.cpu     100m   1
requests.memory  256Mi  1Gi
  1. 再次创建一个 Pod,可以创建成功。当前已经有 2 个 Pod 了
[root@k8s-1 ~]# kubectl run demo2 --image=nginx
pod/demo2 created
[root@k8s-1 ~]# kubectl describe resourcequotas 
Name:            mem-cpu-demo
Namespace:       default
Resource         Used   Hard
--------         ----   ----
limits.cpu       1      2
limits.memory    1Gi    2Gi
pods             2      2
requests.cpu     200m   1
requests.memory  512Mi  1Gi
  1. 再创建第 3 个 Pod,发现创建失败。已经超出 资源配额 的限制了
[root@k8s-1 ~]# kubectl run demo3 --image=nginx
Error from server (Forbidden): pods "demo3" is forbidden: exceeded quota: mem-cpu-demo, requested: pods=1, used: pods=2, limited: pods=2

你可能感兴趣的:(kubernetes,kubernetes,docker,容器,运维)