默认情况下,我们都知道容器可以在Kubernetes群集上使用无限制的计算资源运行。 对于一个比较强调可靠性、可用性的技术平台来讲,这显然是不行的。
在kubernetes中主要通过两个技术来实现资源使用上的限制:
- Resource Quotas 资源使用配额管理
- Limit Ranges 资源数量使用限制
当多个用户或团队共享具有固定数量节点的群集时,可能会担心一个团队可能使用的资源超过其公平的资源份额。Resource Quotas
为此提供了基于计算资源、存储资源以及其它k8s中各种资源对象的使用限制,这个功能主要是限制的最大使用数量。
使用资源配额,集群管理员可以在命名空间的基础上限制资源的消耗和创建。如果需要的话,你可以为每个技术团队创建和使用一个namespace
,然后基于命名空间配置一个Resource Quotas
最大资源使用配额即可。这个功能的配置比较简单,需要进一步了解的同学请看这里。
本文主要是讨论的是Limit Ranges
资源使用数量限制功能的使用。这个功能关注的主要是命名空间内的cpu、内存和存储资源的在一个绝对使用数量上的限制,资源限制的生效粒度也要更细一些。 限制范围是在命名空间中通过Pod或Container约束资源使用的策略。
检查下集群API是否启用了LimitRanger功能插件
执行systemctl status kube-apiserver
确保你在输出结果中看到了--enable-admission-plugins=
参数值中包括了LimitRanger
插件。
创建一个对指定命名空间全局生效的默认限制策略
假定我们有一个名为development
的命名空间。
默认资源限制规则的yaml定义:
apiVersion: v1
kind: LimitRange
metadata:
name: development-limit-range
namespace: development
spec:
limits:
- max:
cpu: "8"
memory: "24Gi"
min:
cpu: "500m"
memory: "1Gi"
default:
cpu: "2"
memory: "8Gi"
defaultRequest:
cpu: "1"
memory: "2Gi"
type: Container
- 规定了在development命名空间中,可以创建的容器,允许使用的最大、最小以及默认资源限制。
- 在创建Pod时,可以不指定计算资源限制数量,会自动按development空间的默认值生效。
- 在上面规则指定的最小、最大资源数量范围内,允许用户自定义容器需要使用的计算资源数量。
完成默认资源限制规则的创建
$ kubectl create -f development-limit-range.yaml
limitrange/development-limit-range created
查看development命名空间的默认资源限制规则
$ kubectl describe limitrange development-limit-range
Name: development-limit-range
Namespace: development
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 500m 8 1 2 -
Container memory 1Gi 24Gi 2Gi 8Gi -
创建一个容器并限制容器的资源使用需求
创建一个普通的容器
在这个测试容器中,我们并不设置任何与资源使用限制有关的内容。
apiVersion: v1
kind: Pod
metadata:
name: test-server1
namespace: development
spec:
containers:
- name: test-server1
image: centos:6
ports:
- containerPort: 8080
创建一个指定了个性化的资源使用需求的容器
如下所示,为其申请了4核CPU+12GB内存的计算资源。
apiVersion: v1
kind: Pod
metadata:
name: test-server2
namespace: development
spec:
containers:
- name: test-server2
image: centos:6
ports:
- containerPort: 8080
resources:
limits:
cpu: "4"
memory: 12Gi
requests:
cpu: "1"
memory: 2Gi
对比查看下这两个正在运行中的容器的resources属性值
$ kubectl get pod test-server1 -o json|jq ".spec.containers[0].resources"
{
"limits": {
"cpu": "2",
"memory": "8Gi"
},
"requests": {
"cpu": "1",
"memory": "2Gi"
}
}
$ kubectl get pod test-server2 -o json|jq ".spec.containers[0].resources"
{
"limits": {
"cpu": "4",
"memory": "12Gi"
},
"requests": {
"cpu": "1",
"memory": "2Gi"
}
}
- 可以看到当未指定任何资源限制时,是直接从development命名空间取默认规则的设置。效果如容器
test-server1
所示。 - 当提供了自定义的资源需求时,按申请的资源设置使用限制。效果如容器
test-server2
所示。 - 由于在命令空间中定义了全局有效的容器最小资源与最大可用资源的数量限制,所以当你申请使用大于8核CPU或24Gi内存时,会直接返回创建失败的信息。
比如,创建下这样一个大胃王:
apiVersion: v1
kind: Pod
metadata:
name: test-server3
namespace: development
spec:
containers:
- name: test-server3
image: centos:6
ports:
- containerPort: 8080
resources:
limits:
cpu: "4"
memory: 32Gi
在执行创建命令时会直接返回报错信息如下:
$ kubectl create -f test-server3-pod.yaml
Error from server (Forbidden): error when creating "test-server3-pod.yaml": pods "test-server3" is forbidden: maximum memory usage per Container is 24Gi, but limit is 32Gi.