女主宣言
众所周知,Kubernetes是允许指定CPU和RAM的请求和限制的,这一特性对于单独的pod的资源消耗管理非常有用。在本系列文章中,我们将向大家展示集群资源的高效管理的三种策略。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
众所周知,Kubernetes是允许指定CPU和RAM的请求和限制的,这一特性对于单独的pod的资源消耗管理非常有用。
但是,如果你是Kubernetes集群管理员,你可能还希望控制集群中资源的全局性消耗,并/或配置所有容器的默认资源需求。
值得高兴的是,Kubernetes支持名称空间级别的集群资源管理。正如你可能已经知道的,Kubernetes的名称空间提供了名称和资源配额的范围,这允许在多个用户、项目和团队之间有效地划分集群资源。在Kubernetes中,你可以定义缺省资源请求和限制、资源约束(最小和最大资源请求和限制),以及在给定名称空间中运行的所有容器的资源配额。这些特性使得集群中的应用程序能够高效地利用资源,并在不同的团队之间有效地分配资源。例如,使用名称空间的资源约束允许你控制生产和开发工作负载如何使用资源,从而允许它们消耗有限的集群资源的公平份额。这可以通过为生产和开发工作负载创建单独的名称空间来实现,并为它们分配不同的资源约束。
在系列文章中,我们将向你展示集群资源的高效管理的三种策略:
为名称空间中的所有容器设置资源配额
这些策略将帮助你解决各种各样的用例,利用Kubernetes名称空间和资源管理的全部功能。
为名称空间设置内存和CPU配额
在前面的例子中,我们为运行在名称空间中的单个容器设置了资源约束。但是,也可以限制资源请求,并限制在名称空间中运行的所有容器的总数。这可以很容易地通过为名称空间定义的 ResourceQuota 资源对象来实现。
为了说明资源配额是如何工作的,让我们首先创建一个新的名称空间,以便在这个练习中创建的资源与集群的其他部分隔离:
kubectl create namespace resource-quota-demo
namespace "resource-quota-demo" created
接下来,让我们创建一个 ResourceQuota 对象,为我们的名称空间提供资源配额:
apiVersion: v1
kind: ResourceQuota
metadata:
name: resource-quota
spec:
hard:
requests.cpu: "1.4"
requests.memory: 2Gi
limits.cpu: "2"
limits.memory: 3Gi
这种 ResourceQuota 为名称空间设置了以下要求:
ResourceQuota 强制每个容器定义它的内存和CPU请求和限制。
所有容器的内存请求总数不得超过2 Gi。
名称空间中所有容器的CPU请求总数不应超过1.4 CPU。
名称空间中所有容器的内存限制不应超过3 Gi。
名称空间中所有容器的CPU限制总数不应该超过2个CPU。
将这个规范保存在 resource-quota.yaml 并通过以下命令创建 ResourceQuota:
kubectl create -f resource-quota.yaml --namespace resource-quota-demo
resourcequota "resource-quota" created
ResouceQuota 对象是在我们的名称空间中创建的,并准备好控制该名称空间中的所有容器的总请求和限制。让我们看看 ResourceQuota 的描述:
kubectl get resourcequota --namespace resource-quota-demo --output=yaml
响应如下:
hard:
limits.cpu: "2"
limits.memory: 3Gi
requests.cpu: 1400m
requests.memory: 2Gi
status:
hard:
limits.cpu: "2"
limits.memory: 3Gi
requests.cpu: 1400m
requests.memory: 2Gi
used:
limits.cpu: "0"
limits.memory: "0"
requests.cpu: "0"
requests.memory: "0"kind: List
这个输出表明在名称空间中还没有消耗内存和CPU。让我们创建两个pod来改变这种情况。
第一个pod将请求1.3 Gi RAM和0.8个CPU,并拥有1.2个CPU和2 Gi RAM的资源限制。
apiVersion: v1
kind: Pod
metadata:
name: resource-quota-pod-1
spec:
containers:
- name: resource-quota-ctr-1
image: httpd:2.4
resources:
limits:
memory: "2Gi"
cpu: 1.2
requests:
memory: "1.3Gi"
cpu: 0.8
我们保存为 resource-quota-pod-1.yaml 并在我们的名称空间中创建pod:
kubectl create -f resource-quota-pod-1.yaml --namespace resource-quota-demo
pod "resource-quota-pod-1" created
pod之所以成功创建,是因为容器的请求和限制都在名称空间的资源配额中。让我们通过检查 ResourceQuota 对象的当前使用量来验证这一点:
kubectl get resourcequota --namespace resource-quota-demo --output=yaml
响应如下:
status:
hard:
limits.cpu: "2"
limits.memory: 3Gi
requests.cpu: 1400m
requests.memory: 2Gi
used:
limits.cpu: 1200m
limits.memory: 2Gi
requests.cpu: 800m
requests.memory: 1395864371200m
如你所见,第一个pod已经消耗了 ResourceQuota 中的一些资源。让我们创建另一个pod,以进一步增加可用资源的消耗:
apiVersion: v1
kind: Pod
metadata:
name: resource-quota-pod-2
spec:
containers:
- name: resource-quota-ctr-2
image: httpd:2.4
resources:
limits:
memory: "1.3Gi"
cpu: 0.9
requests:
memory: "1Gi"
cpu: 0.8
我们保存为 resource-quota-pod-2.yaml 并创建pod:
kubectl create -f resource-quota-pod-2.yaml --namespace resource-quota-demo
运行此命令将导致以下错误:
Error from server (Forbidden): error when creating "resource-quota-pod-2.yaml": pods "resource-quota-pod-2" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=900m,limits.memory=1395864371200m,requests.cpu=800m,requests.memory=1Gi, used: limits.cpu=1200m,limits.memory=2Gi,requests.cpu=800m,requests.memory=1395864371200m, limited: limits.cpu=2,limits.memory=3Gi,requests
如上所见,Kubernetes不允许我们创建这个pod,因为容器的CPU和RAM请求和限制超出了这个名称空间的 ResourceQuota 要求。
清理
这个例子已经完成了,让我们来清理一下:删除名称空间:
kubectl delete namespace resource-quota-demo
namespace "resource-quota-demo" deleted
总结
我们已经讨论了如何设置默认的资源请求和限制,以及如何在Kubernetes名称空间中为容器创建资源约束和资源配额。
如你所见,通过设置名称空间中的容器的默认请求和限制,我们可以在没有人工指定的资源请求和限制的情况下,强制使用名称空间范围的资源政策。
此外,我们还了解了如何使用资源约束来限制容器在名称空间中消耗的资源数量。该特性有助于不同应用程序类和团队有效地管理资源,并确保集群中空闲资源的持续可用性。同样的效果(但在更大的范围内)可以通过资源配额来实现,这允许定义名称空间中所有容器的资源总消耗的资源约束。
HULK一线技术杂谈
由360云平台团队打造的技术分享公众号,内容涉及云计算、数据库、大数据、监控、泛前端、自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享