kubernetes 资源限制之ResourceQuota
·
kubernetes提供了两种资源限制的方式:ResourceQuota 和LimitRange。
其中ResourceQuota 是针对namespace做的资源限制,而LimitRange是针对namespace中的每个组件做的资源限制。
一、ResourceQuota是什么
当多个namespace共用同一个集群的时候可能会有某一个namespace使用的资源配额超过其公平配额,导致其他namespace的资源被占用。
这个时候我们可以为每个namespace创建一个ResourceQuota,
- 用户在namespace中创建资源时,quota 配额系统跟踪使用情况,以确保不超过ResourceQuota的限制值。
- 如果创建或更新资源违反配额约束,则HTTP状态代码将导致请求失败403 FORBIDDEN。
- 资源配额的更改不会影响到已经创建的pod。
- apiserver的启动参数通常kubernetes默认启用了ResourceQuota.在apiserver的启动参数–enable-admission-plugins=中如果有ResourceQuota便为启动。
二、使用ResourceQuota
1、首先创建一个namespace
> kubectl create ns gkn
namespace/gkn created
> kubectl get ns
NAME STATUS AGE
default Active 12d
dev Active 10d
gkn Active 13s
2、创建一个ResourceQuota
> cat <<EOF > gkn-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: gkn-resources
namespace: gkn
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
EOF
> kubectl apply -f gkn-resources.yaml
resourcequota/gkn-resources created
> kubectl get resourcequota -n gkn
NAME CREATED AT
gkn-resources 2019-08-02T01:24:24Z
> kubectl describe resourcequota -n gkn
Name: gkn-resources
Namespace: gkn
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 4
requests.cpu 0 1
requests.memory 0 1Gi
3、创建一个deployment并限制资源
> cat <<EOF > k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: crm-portal-deployment
namespace: gkn
labels:
app: crm-portal
spec:
replicas: 1
selector:
matchLabels:
app: crm-portal
template:
metadata:
labels:
app: crm-portal
spec:
imagePullSecrets:
- name: registry
containers:
- name: crm-portal
image: 10.18.37.2:5000/dev/crm-portal:0.1
env:
- name: JAVA_OPTS
value: -Dspring.config.location=/etc_app/application.properties
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "500m"
EOF
> kubectl apply -f k8s-deployment.yaml
deployment.apps/crm-portal-deployment created
> kubectl get po -n gkn
NAME READY STATUS RESTARTS AGE
crm-portal-deployment-7f748cd688-spqzq 1/1 Running 0 6s
4、多创建几个deployment,使pod使用的资源总和超出resourcequota的限制后再创建deployment,就会发现deployment无法创建pod,并且报错。
首先查看现在的资源使用情况。
> kubectl describe resourcequota -n gkn
Name: gkn-resources
Namespace: gkn
Resource Used Hard
-------- ---- ----
limits.cpu 2 2
limits.memory 2Gi 2Gi
pods 2 4
requests.cpu 200m 1
requests.memory 200Mi 1Gi
发现资源已经使用完了,这时再创建一个deployment试试.
> kubectl apply -f k8s-deployment-2.yml -n gkn
deployment.apps/crm-portal-deployment-2 created
> kubectl get po -n gkn
NAME READY STATUS RESTARTS AGE
crm-portal-deployment-1-7f7944cf67-kz8qb 1/1 Running 6 10m
crm-portal-deployment-7f748cd688-c4h6z 1/1 Running 6 9m32s
> kubectl get deployment -n gkn
NAME READY UP-TO-DATE AVAILABLE AGE
crm-portal-deployment 1/1 1 0 5h51m
crm-portal-deployment-1 1/1 1 0 79m
crm-portal-deployment-2 0/1 0 0 46m
我们发现虽然deployment创建成功了 但是却没有创建对应的pod,我们可以查看deployment报错。
> kubectl describe deployment crm-portal-deployment-2 -n gkn
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 9m13s deployment-controller Scaled up replica set crm-portal-deployment-2-7f748cd688 to 1
可见是由于已经创建的pod的总和已经超过的namespace总的资源总量限制值而导致的无法创建pod。
总结
在工作中如果有多个环境通过命名空间的方式使用同一个集群资源,可以通过这种方式进行资源限制,避免不同环境之间进行资源争抢。
附录
常用资源类型
| 资源名称 | 描述 |
|---|---|
| limits.cpu | namespace下所有pod的CPU限制总和 |
| limits.memory | 内存限制总和 |
| requests.cpu | CPU请求总和 |
| requests.memory | 内存限制总和 |
| requests.storage | PVC请求的存储值的总和 |
| persistentvolumeclaims | PVC的数量 |
| requests.ephemeral-storage | 本地临时存储请求总和 |
| limits.ephemeral-storage | 本地临时存储限制总和 |
常用资源数量限制
- count/<resource>.<group>
示例如下: - count/persistentvolumeclaims
- count/services
- count/secrets
- count/configmaps
- count/replicationcontrollers
- count/deployments.apps
- count/replicasets.apps
- count/statefulsets.apps
- count/jobs.batch
- count/cronjobs.batch
- count/deployments.extensions
对namespace中的pod设置资源使用的优先级
使用如下代码段对优先级进行设置。
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-medium
spec:
hard:
cpu: "10"
memory: 20Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["high"]
---
apiVersion: v1
kind: Pod
metadata:
name: high-priority
spec:
containers:
- name: high-priority
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "10Gi"
cpu: "500m"
limits:
memory: "10Gi"
cpu: "500m"
priorityClassName: high
上面两个定义文件的含义如下:
- 定义一个ResourceQuota限制priorityClassName为high的pod总和。
- 定义一个priorityClassName为high的pod,使其符合ResourceQuota的限制。
其中operator的值可以如下:
- In
- NotIn
- Exist
- DoesNotExist
更多推荐
所有评论(0)