使用 Capacity Scheduling
ACS 通过 Kubernetes 原生的 ResourceQuota 机制限制和控制命名空间中的资源使用。通过ResourceQuota,可以限制和监控命名空间中各种资源的使用情况,如CPU、内存、存储、副本数和服务数。这样就可以防止某个命名空间中的资源被其他应用程序过度占用,从而保证应用程序的稳定性和可靠性。
资源配额 (ResourceQuota)
您可以在 ACS 集群中使用 Kubernetes 原生的资源配额机制来控制每个命名空间的资源消耗总量。通过定义 ResourceQuota 对象,可以现在命名空间中某种资源类型的总量上限,包括 cpu, memory 和扩展资源等。当在命名空间下创建 Pod,Services等 K8s 资源时,Kubernetes 的配额系统会跟踪集群的资源使用情况,并保证资源总用量不超过命名空间下 ResourceQuota 定义的硬性(Hard)限额。
在使用资源配额时:
每个团队或者应用使用独立的命名空间。
集群管理员针对不同的命名空间创建一个或者多个 ResourceQuota 对象。
如果用量超过了 ResourceQuota 的硬性限额时,后续新建的资源会被拒绝。
如果使用 ResourceQuota 配置了 cpu 和 memory,创建的 Pod 必须要设置 request 和 limit,否则将会拒绝创建。
对于其他资源(例如扩展资源):无需为该资源设置request 和 limit。提示:可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 Pod 设置默认值。
ResourceQuota 对象的名称必须是合法的DNS 子域名。
配额的修改不会影响已经创建的资源使用对象。
启用资源配额
通过 ACS 控制台创建的 Kubernetes 集群已经默认开启了资源配额机制。您只需要在命名空间下创建 ResourceQuota 对象,对这个命名空间而言就开启了资源配额。
支持的资源类型
ACS 完全兼容 Kubernetes 原生资源配额机制,因此标准资源类型和扩展资源都可以通过 ResourceQuota 进行配置。
标准资源类型
资源名称 | 描述 |
limits.cpu | 所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。 |
limits.memory | 所有非终止状态的 Pod,其内存限额总量不能超过该值。 |
requests.cpu | 所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。 |
requests.memory | 所有非终止状态的 Pod,其内存需求总量不能超过该值。 |
hugepages-<size> | 对于所有非终止状态的 Pod,针对指定大小的 HugePage 请求总数不能超过此值。 |
cpu | 与 requests.cpu 相同。 |
memory | 与 requests.memory 相同。 |
扩展资源的资源配额
因为 K8s 不支持扩展资源超量分配(即 limit > request),因此只需要配置前缀为 requests. 的配额项。
有关更多详细信息,请参阅资源配额。
示例
演示如何通过 kubectl 查看和创建 ResourceQuota。
创建 Namespace
创建 ResourceQuota,限制 Namespace test 最多只能使用 4000m cpu。
查看 ResourceQuota
创建 4 个 Pod,每个 Pod 使用 1000m cpu。
查看Pod创建结果,可以看到4个Pod都处于Running状态。
查看 ResourceQuota 状态,可以看到 ResourceQuota test-quota 的 Used 等于 Hard。
再尝试扩容一个新的Pod,会被 ResourceQuota 的准入控制器拦截
先尝试扩容一个新的Pod。
kubectl -n test scale deploy test-app --replicas 5
查看对应的 ReplicaSet,发现 DESIRED 是 5,但 CURRENT 是4,证明有个 Pod 有异常。
kubectl -n test get rs NAME DESIRED CURRENT READY AGE test-app-5ddc68c994 5 4 4 3m10s
查看 ReplicaSet 的 Event,可以发现新的 Pod 被 ResourceQuota 的准入控制器拦截了
k -n test describe rs test-app-5ddc68c994 Name: test-app-5ddc68c994 Namespace: test Selector: app=test-app,pod-template-hash=5ddc68c994 Labels: app=test-app pod-template-hash=5ddc68c994 Annotations: deployment.kubernetes.io/desired-replicas: 5 deployment.kubernetes.io/max-replicas: 7 deployment.kubernetes.io/revision: 1 Controlled By: Deployment/test-app Replicas: 4 current / 5 desired Pods Status: 4 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=test-app pod-template-hash=5ddc68c994 Containers: test: Image: busybox:latest Port: <none> Host Port: <none> Command: sleep 360000000 Limits: cpu: 1 Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ ReplicaFailure True FailedCreate Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 3m18s replicaset-controller Created pod: test-app-5ddc68c994-pjdfn Normal SuccessfulCreate 3m18s replicaset-controller Created pod: test-app-5ddc68c994-jdv4m Normal SuccessfulCreate 3m18s replicaset-controller Created pod: test-app-5ddc68c994-jhmtb Normal SuccessfulCreate 3m18s replicaset-controller Created pod: test-app-5ddc68c994-mr8vq Warning FailedCreate 3m18s replicaset-controller Error creating: pods "test-app-5ddc68c994-5s4ph" is forbidden: exceeded quota: test-quota, requested: limits.cpu=1,requests.cpu=1, used: limits.cpu=4,requests.cpu=4, limited: limits.cpu=4,requests.cpu=
kubectl create namespace test
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
name: test-quota
namespace: test
spec:
hard:
requests.cpu: "4000m"
limits.cpu: "4000m"
EOF
kubectl -n test describe resourcequota test-quota
Name: test-quota
Namespace: test
Resource Used Hard
-------- ---- ----
limits.cpu 0 4
requests.cpu 0 4
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test-app
name: test-app
namespace: test
spec:
replicas: 5
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- image: busybox:latest
imagePullPolicy: IfNotPresent
name: test
command:
- sleep
- "360000000"
resources:
limits:
cpu: "1"
EOF
kubectl -n test get pod
NAME READY STATUS RESTARTS AGE
test-app-5ddc68c994-jdv4m 1/1 Running 0 35s
test-app-5ddc68c994-jhmtb 1/1 Running 0 35s
test-app-5ddc68c994-mr8vq 1/1 Running 0 35s
test-app-5ddc68c994-pjdfn 1/1 Running 0 35s
kubectl -n test describe resourcequota
Name: test-quota
Namespace: test
Resource Used Hard
-------- ---- ----
limits.cpu 4 4
requests.cpu 4 4