本文个人博客地址:http://www.huweihuang.com/article/kubernetes/kubernetes-resource/
ResourceQuota
对象用来定义某个命名空间下所有资源的使用限额,其实包括:
如果集群的总容量小于命名空间的配额总额,可能会产生资源竞争。这时会按照先到先得来处理。
资源竞争和配额的更新都不会影响已经创建好的资源。
Kubernetes 的众多发行版本默认开启了资源配额的支持。当在apiserver的--admission-control
配置中添加ResourceQuota
参数后,便启用了。 当一个命名空间中含有ResourceQuota
对象时,资源配额将强制执行。
可以在给定的命名空间中限制可以请求的计算资源(compute resources)的总量。
资源名称 | 描述 |
---|---|
cpu | 非终止态的所有pod, cpu请求总量不能超出此值。 |
limits.cpu | 非终止态的所有pod, cpu限制总量不能超出此值。 |
limits.memory | 非终止态的所有pod, 内存限制总量不能超出此值。 |
memory | 非终止态的所有pod, 内存请求总量不能超出此值。 |
requests.cpu | 非终止态的所有pod, cpu请求总量不能超出此值。 |
requests.memory | 非终止态的所有pod, 内存请求总量不能超出此值。 |
可以在给定的命名空间中限制可以请求的存储资源(storage resources)的总量。
资源名称 | 描述 |
---|---|
requests.storage | 所有PVC, 存储请求总量不能超出此值。 |
persistentvolumeclaims | 命名空间中可以存在的PVC(persistent volume claims)总数。 |
.storageclass.storage.k8s.io/requests.storage | 和该存储类关联的所有PVC, 存储请求总和不能超出此值。 |
.storageclass.storage.k8s.io/persistentvolumeclaims | 和该存储类关联的所有PVC,命名空间中可以存在的PVC(persistent volume claims)总数。 |
资源名称 | 描述 |
---|---|
congfigmaps | 命名空间中可以存在的配置映射的总数。 |
persistentvolumeclaims | 命名空间中可以存在的PVC总数。 |
pods | 命名空间中可以存在的非终止态的pod总数。如果一个pod的status.phase 是 Failed, Succeeded , 则该pod处于终止态。 |
replicationcontrollers | 命名空间中可以存在的rc 总数。 |
resourcequotas | 命名空间中可以存在的资源配额(resource quotas)总数。 |
services | 命名空间中可以存在的服务总数量。 |
services.loadbalancers | 命名空间中可以存在的服务的负载均衡的总数量。 |
services.nodeports | 命名空间中可以存在的服务的主机接口的总数量。 |
secrets | 命名空间中可以存在的secrets 的总数量。 |
例如:可以定义pod的限额来避免某用户消耗过多的Pod IPs。
作用域 | 描述 |
---|---|
Terminating | 匹配 spec.activeDeadlineSeconds >= 0 的pod |
NotTerminating | 匹配 spec.activeDeadlineSeconds is nil 的pod |
BestEffort | 匹配具有最佳服务质量的pod |
NotBestEffort | 匹配具有非最佳服务质量的pod |
当分配计算资源时,每个容器可以为cpu或者内存指定一个请求值和一个限度值。可以配置限额值来限制它们中的任何一个值。
如果指定了requests.cpu
或者 requests.memory
的限额值,那么就要求传入的每一个容器显式的指定这些资源的请求。如果指定了limits.cpu
或者limits.memory
,那么就要求传入的每一个容器显式的指定这些资源的限度。
# 创建namespace
$ kubectl create namespace myspace
# 创建resourcequota
$ cat < compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
EOF
$ kubectl create -f ./compute-resources.yaml --namespace=myspace
# 查询resourcequota
$ kubectl get quota --namespace=myspace
NAME AGE
compute-resources 30s
# 查询resourcequota的详细信息
$ kubectl describe quota compute-resources --namespace=myspace
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 4
requests.cpu 0 1
requests.memory 0 1Gi
资源配额对象与集群容量无关,它们以绝对单位表示。即增加节点的资源并不会增加已经配置的namespace的资源。
ResourceQuota
对象是限制某个namespace下所有Pod(容器)
的资源限额
LimitRange
对象是限制某个namespace单个Pod(容器
)的资源限额
LimitRange
对象用来定义某个命名空间
下某种资源对象
的使用限额,其中资源对象包括:Pod
、Container
、PersistentVolumeClaim
。
如果在一个拥有默认内存或CPU限额的命名空间中创建一个容器,并且这个容器未指定它自己的内存或CPU的limit
, 它会被分配这个默认的内存或CPU的limit
。既没有设置pod的limit
和request
才会分配默认的内存或CPU的request
。
# 创建namespace
$ kubectl create namespace default-mem-example
# 创建LimitRange
$ cat memory-defaults.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 512Mi
defaultRequest:
memory: 256Mi
type: Container
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-defaults.yaml --namespace=default-mem-example
# 创建Pod,未指定内存的limit和request
$ cat memory-defaults-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: default-mem-demo
spec:
containers:
- name: default-mem-demo-ctr
image: nginx
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-defaults-pod.yaml --namespace=default-mem-example
# 查看Pod
$ kubectl get pod default-mem-demo --output=yaml --namespace=default-mem-example
containers:
- image: nginx
imagePullPolicy: Always
name: default-mem-demo-ctr
resources:
limits:
memory: 512Mi
requests:
memory: 256Mi
# 创建namespace
$ kubectl create namespace default-cpu-example
# 创建LimitRange
$ cat cpu-defaults.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limit-range
spec:
limits:
- default:
cpu: 1
defaultRequest:
cpu: 0.5
type: Container
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-defaults.yaml --namespace=default-cpu-example
# 创建Pod,未指定CPU的limit和request
$ cat cpu-defaults-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: default-cpu-demo
spec:
containers:
- name: default-cpu-demo-ctr
image: nginx
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-defaults-pod.yaml --namespace=default-cpu-example
# 查看Pod
$ kubectl get pod default-cpu-demo --output=yaml --namespace=default-cpu-example
containers:
- image: nginx
imagePullPolicy: Always
name: default-cpu-demo-ctr
resources:
limits:
cpu: "1"
requests:
cpu: 500m
request
和limit
,则创建的pod会使用LimitRange
对象定义的默认值(request和limit)limit
但未指定request
,则创建的pod的request
值会取limit
的值,而不会取LimitRange对象定义的request默认值。request
但未指定limit
,则创建的pod的limit
值会取LimitRange
对象定义的limit
默认值。默认Limit和request的动机
如果命名空间具有资源配额(ResourceQuota)
, 它为内存限额(CPU限额)设置默认值是有意义的。 以下是资源配额对命名空间施加的两个限制:
如果一个容器没有指定它自己的内存限额(CPU限额),它将被赋予默认的限额值,然后它才可以在被配额限制的命名空间中运行。
创建LimitRange
# 创建namespace
$ kubectl create namespace constraints-mem-example
# 创建LimitRange
$ cat memory-constraints.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: mem-min-max-demo-lr
spec:
limits:
- max:
memory: 1Gi
min:
memory: 500Mi
type: Container
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraints.yaml --namespace=constraints-mem-example
# 查看LimitRange
$ kubectl get limitrange cpu-min-max-demo --namespace=constraints-mem-example --output=yaml
...
limits:
- default:
memory: 1Gi
defaultRequest:
memory: 1Gi
max:
memory: 1Gi
min:
memory: 500Mi
type: Container
...
# LimitRange设置了最大最小值,但没有设置默认值,也会被自动设置默认值。
创建符合要求的Pod
# 创建符合要求的Pod
$ cat memory-constraints-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo
spec:
containers:
- name: constraints-mem-demo-ctr
image: nginx
resources:
limits:
memory: "800Mi"
requests:
memory: "600Mi"
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraints-pod.yaml --namespace=constraints-mem-example
# 查看Pod
$ kubectl get pod constraints-mem-demo --output=yaml --namespace=constraints-mem-example
...
resources:
limits:
memory: 800Mi
requests:
memory: 600Mi
...
创建超过最大内存limit的pod
$ cat memory-constraints-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-2
spec:
containers:
- name: constraints-mem-demo-2-ctr
image: nginx
resources:
limits:
memory: "1.5Gi" # 超过最大值 1Gi
requests:
memory: "800Mi"
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraints-pod-2.yaml --namespace=constraints-mem-example
# Pod创建失败,因为容器指定的limit过大
Error from server (Forbidden): error when creating "docs/tasks/administer-cluster/memory-constraints-pod-2.yaml":
pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.
创建小于最小内存request的Pod
$ cat memory-constraints-pod-3.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-3
spec:
containers:
- name: constraints-mem-demo-3-ctr
image: nginx
resources:
limits:
memory: "800Mi"
requests:
memory: "100Mi" # 小于最小值500Mi
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraints-pod-3.yaml --namespace=constraints-mem-example
# Pod创建失败,因为容器指定的内存request过小
Error from server (Forbidden): error when creating "docs/tasks/administer-cluster/memory-constraints-pod-3.yaml":
pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.
创建没有指定任何内存limit和request的pod
$ cat memory-constraints-pod-4.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-4
spec:
containers:
- name: constraints-mem-demo-4-ctr
image: nginx
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraints-pod-4.yaml --namespace=constraints-mem-example
# 查看Pod
$ kubectl get pod constraints-mem-demo-4 --namespace=constraints-mem-example --output=yaml
...
resources:
limits:
memory: 1Gi
requests:
memory: 1Gi
...
容器没有指定自己的 CPU 请求和限制,所以它将从 LimitRange 获取默认的 CPU 请求和限制值。
创建LimitRange
# 创建namespace
$ kubectl create namespace constraints-cpu-example
# 创建LimitRange
$ cat cpu-constraints.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-min-max-demo-lr
spec:
limits:
- max:
cpu: "800m"
min:
cpu: "200m"
type: Container
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-constraints.yaml --namespace=constraints-cpu-example
# 查看LimitRange
$ kubectl get limitrange cpu-min-max-demo-lr --output=yaml --namespace=constraints-cpu-example
...
limits:
- default:
cpu: 800m
defaultRequest:
cpu: 800m
max:
cpu: 800m
min:
cpu: 200m
type: Container
...
创建符合要求的Pod
$ cat cpu-constraints-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-cpu-demo
spec:
containers:
- name: constraints-cpu-demo-ctr
image: nginx
resources:
limits:
cpu: "800m"
requests:
cpu: "500m"
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-constraints-pod.yaml --namespace=constraints-cpu-example
# 查看Pod
$ kubectl get pod constraints-cpu-demo --output=yaml --namespace=constraints-cpu-example
...
resources:
limits:
cpu: 800m
requests:
cpu: 500m
...
创建超过最大CPU limit的Pod
$ cat cpu-constraints-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-cpu-demo-2
spec:
containers:
- name: constraints-cpu-demo-2-ctr
image: nginx
resources:
limits:
cpu: "1.5"
requests:
cpu: "500m"
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml --namespace=constraints-cpu-example
# Pod创建失败,因为容器指定的CPU limit过大
Error from server (Forbidden): error when creating "docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml":
pods "constraints-cpu-demo-2" is forbidden: maximum cpu usage per Container is 800m, but limit is 1500m.
创建小于最小CPU request的Pod
$ cat cpu-constraints-pod-3.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-cpu-demo-4
spec:
containers:
- name: constraints-cpu-demo-4-ctr
image: nginx
resources:
limits:
cpu: "800m"
requests:
cpu: "100m"
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml --namespace=constraints-cpu-example
# Pod创建失败,因为容器指定的CPU request过小
Error from server (Forbidden): error when creating "docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml":
pods "constraints-cpu-demo-4" is forbidden: minimum cpu usage per Container is 200m, but request is 100m.
创建没有指定任何CPU limit和request的pod
$ cat cpu-constraints-pod-4.yaml
apiVersion: v1
kind: Pod
metadata:
name: constraints-cpu-demo-4
spec:
containers:
- name: constraints-cpu-demo-4-ctr
image: vish/stress
$ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-constraints-pod-4.yaml --namespace=constraints-cpu-example
# 查看Pod
kubectl get pod constraints-cpu-demo-4 --namespace=constraints-cpu-example --output=yaml
...
resources:
limits:
cpu: 800m
requests:
cpu: 800m
...
容器没有指定自己的 CPU 请求和限制,所以它将从 LimitRange 获取默认的 CPU 请求和限制值。
LimitRange 在 namespace 中施加的最小和最大内存(CPU)限制只有在创建和更新 Pod 时才会被应用。改变 LimitRange 不会对之前创建的 Pod 造成影响。
Kubernetes 都会执行下列步骤:
request
值表示容器保证可被分配到资源。limit
表示容器可允许使用的最大资源。Pod级别的request
和limit
是其所有容器的request和limit之和。
Pod可以指定request
和limit
资源。其中0 <= request <=
Node Allocatable
& request <= limit <= Infinity
。调度是基于request
而不是limit
,即如果Pod被成功调度,那么可以保证Pod分配到指定的 request
的资源。Pod使用的资源能否超过指定的limit
值取决于该资源是否可被压缩。
在机器资源超卖的情况下(limit的总量大于机器的资源容量),即CPU或内存耗尽,将不得不杀死部分不重要的容器。因此对容器分成了3个QoS
的级别:Guaranteed
,Burstable
, Best-Effort
,三个级别的优先级依次递减。
当CPU资源无法满足,pod不会被杀死可能被短暂控制。
内存是不可压缩的资源,当内存耗尽的情况下,会依次杀死优先级低的容器。Guaranteed的级别最高,不会被杀死,除非容器使用量超过limit限值或者资源耗尽,已经没有更低级别的容器可驱逐。
所有的容器的limit
值和request
值被配置且两者相等(如果只配置limit没有request,则request取值于limit)。
例如:
# 示例1
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
memory: 100Mi
# 示例2
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
如果一个或多个容器的limit和request值被配置且两者不相等。
例如:
# 示例1
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
name: bar
# 示例2
containers:
name: foo
resources:
limits:
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
# 示例3
containers:
name: foo
resources:
requests:
cpu: 10m
memory: 1Gi
name: bar
所有的容器的limit
和request
值都没有配置。
例如:
containers:
name: foo
resources:
name: bar
resources:
参考:
https://kubernetes.io/docs/concepts/policy/resource-quotas/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/resource-qos.md