官方文档: 概念 | 策略 | 限制范围
官方文档: 概念 | 策略 | 资源配额
默认情况下, Kubernetes 集群上的容器运行使用的计算资源没有限制。 使用资源配额,集群管理员可以以名字空间为单位,限制其资源的使用与创建。 在命名空间中,一个 Pod 或 Container 最多能够使用命名空间的资源配额所定义的 CPU 和内存用量。 有人担心,一个 Pod 或 Container 会垄断所有可用的资源。 LimitRange 是在命名空间内限制资源分配(给多个 Pod 或 Container)的策略对象。
一个 LimitRange(限制范围) 对象提供的限制能够做到:
限制范围总览
[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
[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
[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 -
[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
[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: {}
[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
[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 -
当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。
资源配额是帮助管理员解决这一问题的工具。
资源配额,通过 ResourceQuota 对象来定义,对每个命名空间的资源消耗总量提供限制。 它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命令空间中的 Pod 可以使用的计算资源的总上限。
资源配额的工作方式如下:
不同的团队可以在不同的命名空间下工作,目前这是非约束性的,在未来的版本中可能会通过 ACL (Access Control List 访问控制列表) 来实现强制性约束。
集群管理员可以为每个命名空间创建一个或多个 ResourceQuota 对象。
当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会 跟踪集群的资源使用情况,以确保使用的资源用量不超过 ResourceQuota 中定义的硬性资源限额。
如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。
如果命名空间下的计算资源 (如 cpu 和 memory)的配额被启用,则用户必须为 这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 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
[root@k8s-1 ~]# kubectl apply -f quota.yaml
resourcequota/mem-cpu-demo created
[root@k8s-1 ~]# kubectl delete -f limitrange.yaml
limitrange "limitrange-demo" deleted
[root@k8s-1 ~]# kubectl get limitranges
No resources found in default namespace.
[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
[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
[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
[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
[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
[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
[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
[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"
[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
[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
[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