K8S资源限制与QoS
- Kubernetes
- 2024-10-18
- 113热度
- 3评论
K8S资源限制与Qos
Kubernetes资源限额是用来限制容器在命名空间内可以使用的CPU和内存资源的机制。通过设置资源请求和限制,可以确保应用在运行时不会超出预设的资源范围,从而实现资源的公平分配和高效利用。资源限额帮助防止某个应用过度消耗资源,保护集群的整体性能和稳定性。
以下是一些常见场景及对应的资源配额措施:
- 多租户环境:为每个团队或项目设置命名空间级别的资源配额,以限制CPU和内存使用,防止资源争用。
- 高负载应用:对处理高并发请求的应用设置资源请求和限制,确保它们在高负载下仍能稳定运行。
- 开发和测试环境:为开发和测试环境设置较低的资源限额,以减少对生产环境的影响,防止测试用例消耗过多资源。
- 数据处理任务:针对数据处理或批量任务,设置适当的并发限制和资源配额,确保任务在资源受限的情况下也能有效执行。
- 长时间运行的服务:对需要长期运行的服务设置合理的资源请求,确保它们在资源竞争中有足够的可用性。
创建新的命名空间进行测试,避免影响当前集群
[root@master-01 ~]# kubectl create namespace resource-test
namespace/resource-test created
编辑ResourceQuota文件,并创建资源
[root@master-01 ~]# cat resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
namespace: resource-test
name: resource-test
labels:
app: resourcequota
spec:
hard:
pods: 5
requests.cpu: 0.5
requests.memory: 512Mi
limits.cpu: 5
limits.memory: 16Gi
configmaps: 2
requests.storage: 40Gi
persistentvolumeclaims: 20
replicationcontrollers: 20
secrets: 20
services: 50
services.loadbalancers: "2"
services.nodeports: "10"
[root@master-01 ~]# kubectl create -f resource-quota.yaml
resourcequota/resource-test created
字段 | 含义 |
---|---|
pods | 限制最多启动Pod的个数 |
requests.cpu | 限制最高CPU请求数 |
requests.memory | 限制最高内存的请求数 |
limits.cpu | 限制最高CPU的limit上限 |
limits.memory | 限制最高内存的limit上限 |
查看资源状态
[root@master-01 ~]# kubectl get -f resource-quota.yaml
NAME AGE REQUEST LIMIT
resource-test 9s configmaps: 1/2, persistentvolumeclaims: 0/20, pods: 2/5, replicationcontrollers: 0/20, requests.cpu: 100m/500m, requests.memory: 0/512Mi, requests.storage: 0/40Gi, secrets: 0/20, services: 2/50, services.loadbalancers: 0/2, services.nodeports: 0/10 limits.cpu: 500m/5, limits.memory: 0/16Gi
[root@master-01 ~]# kubectl get resourcequotas -n resource-test
NAME AGE REQUEST LIMIT
resource-test 5s configmaps: 1/2, persistentvolumeclaims: 0/20, pods: 0/5, replicationcontrollers: 0/20, requests.cpu: 0/500m, requests.memory: 0/512Mi, requests.storage: 0/40Gi, secrets: 0/20, services: 0/50, services.loadbalancers: 0/2, services.nodeports: 0/10 limits.cpu: 0/5, limits.memory: 0/16Gi
尝试创建2个ConfigMap,由于限制创建的个数,所以在创建第3个ConfigMap时,会出现提示,并且无法创建
[root@master-01 ~]# kubectl create configmap test-cm0 --from-file=resource-quota.yaml -n resource-test
configmap/test-cm0 created
[root@master-01 ~]# kubectl create configmap test-cm1 --from-file=resource-quota.yaml -n resource-test
error: failed to create configmap: configmaps "test-cm1" is forbidden: exceeded quota: resource-test, requested: configmaps=1, used: configmaps=2, limited: configmaps=2
尝试在resource-test命名空间下创建Deployment控制器,其中包含3个Pod
[root@master-01 ~]# kubectl create deployment resource-test0 --image=registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1.15.1 --replicas=3 --namespace=resource-test
deployment.apps/resource-test0 created
但是可以观察到对应命名空间下并无创建的Pod,此时使用describe命令也无法查看Deployment控制器无法创建Pod的原因。读者需要describe Deployment控制器下对应的Replicaset控制器才能发现原因。是因为使用了resourcequota资源后,需要指定Pod的CPU和Memory限制。
[root@master-01 ~]# kubectl get pods -n resource-test
No resources found in resource-test namespace.
[root@master-01 ~]# kubectl get deployments.apps -n resource-test
NAME READY UP-TO-DATE AVAILABLE AGE
resource-test0 0/3 0 0 9m33s
[root@master-01 ~]# kubectl describe deployments.apps -n resource-test resource-test-0
...省略部分输出...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 115s deployment-controller Scaled up replica set resource-test-2-5df655c95 to 3
[root@master-01 ~]# kubectl describe replicasets.apps resource-test0-6f6f5479b7 -n resource-test
...省略部分输出...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreate 5m44s replicaset-controller Error creating: pods "resource-test-6f6f5479b7-78hh2" is forbidden: failed quota: resource-test: must specify limits.cpu for: nginx; limits.memory for: nginx; requests.cpu for: nginx; requests.memory for: nginx
重新设置Pod的资源限制
[root@master-01 ~]# kubectl set resources deployment resource-test0 --limits=cpu=1,memory=512Mi --requests=cpu=500m,memory=256Mi -n resource-test
deployment.apps/resource-test0 resource requirements updated
再次观察Pod的创建状态,此时可以发现Pod已正常创建,但是只创建2个,是因为规划的资源数量只满足创建2个Pod
[root@master-01 ~]# kubectl get rs -n resource-test
NAME DESIRED CURRENT READY AGE
resource-test0-7c48fb8b7d 3 2 2 5m52s
[root@master-01 ~]# kubectl describe rs -n resource-test resource-test0-5db45b5775
...省略部分输出...
Warning FailedCreate 41s (x9 over 43s) replicaset-controller (combined from similar events): Error creating: pods "resource-test0-5db45b5775-sh82m" is forbidden: exceeded quota: resource-test, requested: requests.memory=256Mi, used: requests.memory=512Mi, limited: requests.memory=512Mi
LimitRange
LimitRange 是 Kubernetes 中的一个对象,用于限制 Pod 和容器在特定命名空间中能够请求和使用的资源范围。它可以帮助集群管理员通过定义最小和最大资源请求、资源限制以及默认值,来避免过度消耗资源,确保资源的合理分配。
作用
- 设置资源请求和限制的最小/最大值: LimitRange 可以定义容器的 CPU、内存等资源的最小和最大请求值及限制值。这有助于防止 Pod 请求过少或过多资源,避免资源不足或资源浪费。
- 为资源未显式指定的 Pod 设置默认请求/限制值: 如果 Pod 没有为某些资源(如 CPU 或内存)显式指定请求或限制值,LimitRange 可以为这些资源自动应用默认的请求和限制。
- 控制存储资源: LimitRange 还可以限制持久存储卷的大小,以防止用户在命名空间中请求过大的存储资源。
使用场景
-
多租户环境: 在多租户的 Kubernetes 环境下,不同团队或项目共享集群资源。通过 LimitRange,管理员可以确保每个团队不会请求过多或过少的资源,从而避免资源争用或浪费。
-
预防资源耗尽: 通过为资源请求设置最小值,防止容器请求过少的资源导致性能问题或容器不稳定。通过设置最大值,可以防止某些容器独占过多资源而影响其他容器的正常运行。
-
设置默认值: 如果用户在 Pod 定义中没有设置 CPU 或内存的请求和限制,LimitRange 可以为这些资源指定默认值,确保所有容器都有合理的资源分配。
[root@master-01 ~]# vim limitrange.yaml apiVersion: v1 kind: LimitRange metadata: name: cpu-mem-limit-range spec: limits: - default: cpu: "1" # 1 个 CPU 核心,字符串形式 memory: 512Mi # 512 MiB 内存 defaultRequest: cpu: "500m" # 0.5 个 CPU 核心,单位为 millicores (m) memory: 256Mi # 256 MiB 内存 type: Container # 作用于容器级别
创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f limitrange.yaml limitrange/cpu-mem-limit-range created
[root@master-01 ~]# kubectl get limitranges NAME CREATED AT cpu-mem-limit-range 2024-10-17T16:53:52Z
[root@master-01 ~]# kubectl describe limitranges Name: cpu-mem-limit-range Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu - - 500m 1 - Container memory - - 256Mi 512Mi -
创建Deployment控制器,并且不指定CPU和Memory的参数,观察创建后是否自动配置
[root@master-01 ~]# kubectl create deployment default-limit --image=registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1.15.1 --replicas=2 deployment.apps/default-limit created [root@master-01 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE cluster-test-665f554bcc-bhmgt 1/1 Running 70 (26m ago) 3d10h default-limit-67587d779b-5qhsl 1/1 Running 0 4s default-limit-67587d779b-h9c8l 1/1 Running 0 4s
[root@master-01 ~]# kubectl describe pod default-limit-67587d779b-5qhsl ...省略部分输出... Limits: cpu: 1 memory: 512Mi Requests: cpu: 500m memory: 256Mi
进一步对资源的分配进行控制,限制Container最大/最小CPU和Memory数量
[root@master-01 ~]# vim limitrange.yaml apiVersion: v1 kind: LimitRange metadata: name: cpu-mem-limit-range spec: limits: - default: cpu: "1" # 默认限制为 1 个 CPU 核心 memory: 512Mi # 默认限制 512 MiB 内存 defaultRequest: cpu: "500m" # 默认请求 0.5 个 CPU 核心 memory: 512Mi # 默认请求 256 MiB 内存 max: cpu: "2" # CPU 限制的最大值为 2 个核心 memory: 1Gi # 内存限制的最大值为 1 GiB min: cpu: "200m" # CPU 请求的最小值为 200 millicores memory: 500Mi # 内存请求的最小值为 500 MiB type: Container # 作用于容器级别
在resource-test命名空间下创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f limitrange.yaml -n resource-test limitrange/cpu-mem-limit-range created
[root@master-01 ~]# kubectl describe limitranges -n resource-test Name: cpu-mem-limit-range Namespace: resource-test Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container memory 500Mi 1Gi 512Mi 512Mi - Container cpu 200m 2 500m 1 -
修改该命名空间下的Deploymnt控制器的requests的值小于Limitatranges Min值
[root@master-01 ~]# kubectl edit deployments.apps -n resource-test resource-test0 requests: cpu: 100m memory: 256M deployment.apps/resource-test0 edited
可以观察到Deployment控制器创建了新的Replicaset控制器,但是容器无法创建并出现报错,提示容器requests的值小于最小值的限制
[root@master-01 ~]# kubectl get rs -n resource-test NAME DESIRED CURRENT READY AGE resource-test0-5996f55858 0 0 0 77m resource-test0-5db45b5775 5 2 2 67m resource-test0-6ddf9fff67 3 0 0 7m10s resource-test0-7c48fb8b7d 0 0 0 73m
[root@master-01 ~]# kubectl describe rs -n resource-test resource-test0-6ddf9fff67 ...省略部分输出... Warning FailedCreate 4s (x4 over 22s) replicaset-controller (combined from similar events): Error creating: pods "resource-test0-6ddf9fff67-2gwxj" is forbidden: [minimum cpu usage per Container is 200m, but request is 100m, minimum memory usage per Container is 500Mi, but request is 256Mi]
配置Limitrange对存储空间大小的限制
[root@master-01 ~]# vim limitrange.yaml apiVersion: v1 kind: LimitRange metadata: name: cpu-mem-limit-range spec: limits: - default: cpu: "1" # 默认限制为 1 个 CPU 核心 memory: 512Mi # 默认限制 512 MiB 内存 defaultRequest: cpu: "500m" # 默认请求 0.5 个 CPU 核心 memory: 512Mi # 默认请求 256 MiB 内存 max: cpu: "2" # CPU 限制的最大值为 2 个核心 memory: 1Gi # 内存限制的最大值为 1 GiB min: cpu: "200m" # CPU 请求的最小值为 200 millicores memory: 500Mi # 内存请求的最小值为 500 MiB type: Container # 作用于容器级别 - max: storage: 2Gi # PVC 最大存储限制 min: storage: 1Gi # PVC 最小存储限制 type: PersistentVolumeClaim # 作用于持久存储卷
在resource-test命名空间下创建资源并查看资源状态
[root@master-01 ~]# kubectl replace -f limitrange.yaml -n resource-test limitrange/cpu-mem-limit-range replaced
[root@master-01 ~]# kubectl describe limitranges -n resource-test cpu-mem-limit-range Name: cpu-mem-limit-range Namespace: resource-test Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container memory 500Mi 1Gi 512Mi 512Mi - Container cpu 200m 2 500m 1 -
尝试创建大小为5G的PVC资源,此时由于资源的限制,PVC创建失败
[root@master-01 ~]# kubectl create -f pvc.yaml -n resource-test Error from server (Forbidden): error when creating "pvc.yaml": persistentvolumeclaims "myclaim" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi
当修改大小为1G时,PVC创建成功
[root@master-01 ~]# cat pvc.yaml | grep storage: storage: 1Gi [root@master-01 ~]# kubectl create -f pvc.yaml -n resource-test persistentvolumeclaim/myclaim created
服务质量QOS
Kubernetes 中的 QoS (Quality of Service,服务质量) 是一种机制,用来为不同的 Pod 提供资源保障和优先级划分,帮助集群在资源紧张时更好地管理和分配 CPU 和内存资源。通过 QoS,Kubernetes 可以确保关键的应用在资源争用情况下得到优先照顾,并提供不同的资源保障级别。
Kubernetes 使用 Pod 的 资源请求(requests)和 资源限制(limits)来定义 QoS 类别。这些类别帮助 Kubernetes 决定哪些 Pod 在资源压力下应该优先获得资源或首先被驱逐(evicted)。
字段 | 含义 |
---|---|
Guaranteed(保证) | 最高服务质量,当 Pod 中所有容器的 资源请求 和 资源限制 都被设置且相等时,Pod 会被归类为 Guaranteed。当宿主机内存不够时,会先kill掉QoS为BestEffort和Burstable的Pod,如果内存还是不够,才会kill掉QoS为Guaranteed,该级别Pod的资源占用量一般比较明确,即requests的cpu和memory和limits的cpu和memory配置的一致。适用于关键应用或高优先级的服务,需要确保获得足够的 CPU 和内存资源,即使在资源紧张的情况下也不会被驱逐。 |
Burstable(突发型) | 如果 Pod 设置了资源请求但没有为所有容器都设置资源限制,或者资源请求和限制的值不同,那么这个 Pod 会被归类为 Burstable。服务质量低于Guaranteed,当宿主机内存不够时,会先kill掉QoS为BestEffort的Pod,如果内存还是不够之后就会kill掉QoS级别为Burstable的Pod,用来保证QoS质量为Guaranteed的Pod,该级别Pod一般知道最小资源使用量,但是当机器资源充足时,还是想尽可能的使用更多的资源,即limits字段的cpu和memory大于requests的cpu和memory的配置。适用于对资源要求较灵活的应用。在资源充足时允许超出基本需求进行突发使用,而在资源紧张时优先确保基本需求。 |
BestEffort(尽力而为) | 如果 Pod 没有设置任何资源请求或限制,它会被归类为 BestEffort。这种情况下,Pod 没有任何资源保证,是最容易被驱逐的。当宿主机内存不够时,首先kill的就是该QoS的Pod,用以保证Burstable和Guaranteed级别的Pod正常运行。适用于对资源需求不敏感的服务或者开发阶段的应用。 |
QoS 使用场景
- 生产环境中的关键应用: 对于像数据库、支付系统等关键业务应用,保证高可用性和资源稳定性至关重要。可以通过将它们的 Pod 设置为 Guaranteed 来确保其获得稳定的资源,避免因资源争用导致性能下降或宕机。
- 允许突发性能的应用: 对于一些非关键的应用或后台服务,可以使用 Burstable,确保它们在正常情况下获得足够的资源,同时在资源允许时支持突发性能。如果资源紧张,它们仍会保持基础服务不被打断。
- 开发、测试阶段的应用: 开发和测试环境中的应用可以使用 BestEffort,在不需要高资源保证的情况下运行。这有助于更高效地利用资源,降低集群运行成本。
创建qos-example命名空间
[root@master-01 ~]# kubectl create namespace qos-example
namespace/qos-example created
创建QoS类型为Guaranteed的Pod。要求:Pod中的每个容器必须指定limits.memory和requests.memory,并且两者需要相等;Pod中的每个容器必须指定limits.cpu和limits.memory,并且两者需要相等。
[root@master-01 ~]# vim guaranteed.yaml
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1.15.1
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f guaranteed.yaml
pod/qos-demo created
[root@master-01 ~]# kubectl get pods -n qos-example
NAME READY STATUS RESTARTS AGE
qos-demo 1/1 Running 0 2m11s
通过describe命令查看Pod对应的QoS类型为Guaranteed
[root@master-01 ~]# kubectl describe pod -n qos-example qos-demo
...省略部分输出...
QoS Class: Guaranteed
...省略部分输出...
创建QoS类型为Burstable的Pod。要求:Pod不符合Guaranteed的配置要求;Pod中至少有一个容器配置了requests.cpu或requests.memory
[root@master-01 ~]# vim burstable.yaml
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1.15.1
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f burstable.yaml
pod/qos-demo-2 created
通过describe命令查看Pod对应的QoS类型为Burstable
[root@master-01 ~]# kubectl describe pods -n qos-example qos-demo-2
...省略部分输出...
QoS Class: Burstable
创建QoS类型为BestEffort的Pod
[root@master-01 ~]# vim besteffort.yaml
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1.15.1
创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f besteffort.yaml
pod/qos-demo-3 created
通过describe命令查看Pod对应的QoS类型为BestEffort
[root@master-01 ~]# kubectl describe pod -n qos-example qos-demo-3
...省略部分输出...
QoS Class: BestEffort
有点东西
aaaaaaa
恨相知晚