LimitRange
有个好听的中文名字,叫”资源配置访问管理”。用过K8S的都知道,在默认情况下,K8S不会对Pod进行CPU和内存限制,这就意味着这个未被限制的Pod可以随心所欲的使用节点上的CPU和内存,如果某个Pod发生内存泄漏那么将是一个非常糟糕的事情。
所以正常情况下,我们在部署Pod的时候都会把Requests和Limits加上,如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ng-deploy
spec:
selector:
matchLabels:
app: ng-demo
replicas: 2
template:
metadata:
labels:
app: ng-demo
spec:
containers:
- name: ng-demo
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 216Mi
limits:
cpu: 100m
memory: 216Mi
但是,如果Pod非常多,而且很多Pod只需要相同的限制,我们还是像上面那样一个一个的加就非常繁琐了,这时候我们就可以通过LimitRange
做一个全局限制。如果在部署Pod的时候指定了requests和Limits,则指定的生效。反之则由全局的给Pod加上默认的限制。
总结,LimitRange
可以实现的功能:
- 限制namespace中每个pod或container的最小和最大资源用量。
- 限制namespace中每个PVC的资源请求范围。
- 限制namespace中资源请求和限制数量的比例。
- 配置资源的默认限制。
创建LimitRange之后,LimitRange会在它所属namespace范围内生效。
常用的场景如下(来自《Kubernetes权威指南》)
- 集群中的每个节点都有2GB内存,集群管理员不希望任何Pod申请超过2GB的内存:因为在整个集群中都没有任何节点能满足超过2GB内存的请求。如果某个Pod的内存配置超过2GB,那么该Pod将永远都无法被调度到任何节点上执行。为了防止这种情况的发生,集群管理员希望能在系统管理功能中设置禁止Pod申请超过2GB内存。
- 集群由同一个组织中的两个团队共享,分别运行生产环境和开发环境。生产环境最多可以使用8GB内存,而开发环境最多可以使用512MB内存。集群管理员希望通过为这两个环境创建不同的命名空间,并为每个命名空间设置不同的限制来满足这个需求。
- 用户创建Pod时使用的资源可能会刚好比整个机器资源的上限稍小,而恰好剩下的资源大小非常尴尬:不足以运行其他任务但整个集群加起来又非常浪费。因此,集群管理员希望设置每个Pod都必须至少使用集群平均资源值(CPU和内存)的20%,这样集群能够提供更好的资源一致性的调度,从而减少了资源浪费。
LimitRange
可以用来限制Pod,也可以限制Container。下面我们以一个例子来详细说明。
配置LimitRange
(1)、首先创建一个namespace
apiVersion: v1
kind: Namespace
metadata:
name: coolops
(2)、为namespace配置LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: mylimit
namespace: coolops
spec:
limits:
- max:
cpu: "1"
memory: 1Gi
min:
cpu: 100m
memory: 10Mi
maxLimitRequestRatio:
cpu: 3
memory: 4
type: Pod
- default:
cpu: 300m
memory: 200Mi
defaultRequest:
cpu: 200m
memory: 100Mi
max:
cpu: "2"
memory: 1Gi
min:
cpu: 100m
memory: 10Mi
maxLimitRequestRatio:
cpu: 5
memory: 4
type: Container
参数说明:
- max:如果type是Pod,则表示pod中所有容器资源的Limit值和的上限,也就是整个pod资源的最大Limit,如果pod定义中的Limit值大于LimitRange中的值,则pod无法成功创建。如果type是Container,意义类似。
- min:如果type是Pod,则表示pod中所有容器资源请求总和的下限,也就是所有容器request的资源总和不能小于min中的值,否则pod无法成功创建。如果type是Container,意义类似。
- maxLimitRequestRatio:如果type是Pod,表示pod中所有容器资源请求的Limit值和request值比值的上限,例如该pod中cpu的Limit值为3,而request为0.5,此时比值为6,创建pod将会失败。
- defaultrequest和defaultlimit则是默认值,只有type为Container才有这两项配置
注意: (1)、如果
container
设置了max
,pod
中的容器必须设置limit
,如果未设置,则使用defaultlimt
的值,如果defaultlimit
也没有设置,则无法成功创建 (2)、如果设置了container
的min
,创建容器的时候必须设置request
的值,如果没有设置,则使用defaultrequest
,如果没有defaultrequest
,则默认等于容器的limit
值,如果limit
也没有,启动就会报错
创建上面配置的LimitRange:
# kubectl apply -f limitrange.yaml
limitrange/mylimit created
# kubectl get limitrange -n coolops
NAME CREATED AT
mylimit 2020-03-26T09:46:33Z
# kubectl describe limitranges -n coolops mylimit
Name: mylimit
Namespace: coolops
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod memory 10Mi 1Gi - - 4
Pod cpu 100m 1 - - 3
Container cpu 100m 2 200m 300m 5
Container memory 10Mi 1Gi 100Mi 200Mi 4
测试LimitRange
(1)、创建一个允许范围之内的requests和limits的pod
apiVersion: v1
kind: Pod
metadata:
name: pod01
namespace: coolops
spec:
containers:
- name: pod-01
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 200m
memory: 30Mi
limits:
cpu: 300m
memory: 50Mi
我们通过kubectl apply -f pod-01.yaml
可以正常创建Pod。
(2)、创建一个cpu超出允许访问的Pod
apiVersion: v1
kind: Pod
metadata:
name: pod02
namespace: coolops
spec:
containers:
- name: pod-02
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 200m
memory: 30Mi
limits:
cpu: 2
memory: 50Mi
然后我们创建会报如下错误:
# kubectl apply -f pod-02.yaml
Error from server (Forbidden): error when creating "pod-02.yaml": pods "pod02" is forbidden: [maximum cpu usage per Pod is 1, but limit is 2, cpu max limit to request ratio per Pod is 3, but provided ratio is 10.000000, cpu max limit to request ratio per Container is 5, but provided ratio is 10.000000]
(3)创建低于允许范围的Pod
apiVersion: v1
kind: Pod
metadata:
name: pod03
namespace: coolops
spec:
containers:
- name: pod-03
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 200m
memory: 30Mi
limits:
cpu: 100m
memory: 10Mi
然后会报如下错误:
# kubectl apply -f pod-03.yaml
The Pod "pod03" is invalid:
* spec.containers[0].resources.requests: Invalid value: "200m": must be less than or equal to cpu limit
* spec.containers[0].resources.requests: Invalid value: "30Mi": must be less than or equal to memory limit
(4)、创建一个未定义request或Limits的Pod
apiVersion: v1
kind: Pod
metadata:
name: pod04
namespace: coolops
spec:
containers:
- name: pod-04
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 200m
memory: 200Mi
然后我们创建完Pod后会发现自动给我们加上了limits。如下:
# kubectl describe pod -n coolops pod04
...
Limits:
cpu: 300m
memory: 200Mi
Requests:
cpu: 200m
memory: 200Mi
...
上面我指定了requests,LimitRange自动给我们加上了defaultLimits,你也可以试一下全都不加或者加一个,道理是一样的。值得注意的是这里要注意一下我们设置的maxLimitRequestRatio
,配置的比列必须小于等于我们设置的值。
上文有介绍LimitRange还可以限制还可以限制PVC,如下:
apiVersion: v1
kind: LimitRange
metadata:
name: storagelimits
namespace: coolops
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 2Gi
min:
storage: 1Gi
创建完后即可查看:
kubectl describe limitranges -n coolops storagelimits
Name: storagelimits
Namespace: coolops
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
PersistentVolumeClaim storage 1Gi 2Gi - - -
你可以创建PVC进行测试,道理是一样的。