一、资源管理
当我们创建Pod时,可以对POD使用的资源做一些限制,比如CPU、Memory等。也可以从namespace维度,来对整个namespace的资源使用限制。
1、POD资源限制
通过pods.spec.containers.resources中limits和requests字段来控制Pod容器的资源分配。
requests定义Pod容器需要的最小资源量,limits定义Pod容器最大可用的资源上限。
在调度时,kube-scheduler只会按照requests的值进行计算。而在真正设置Cgroups限制时,kubelet则会按照limits的值来进行设置。
支持限制的资源类型:
- CPU(单位为millicore,1Core=1000millicore)
- Memory(单位为Byte)
- Ephemeral storage(临时存储,单位为Byte)
- 自定义资源: 配置时必须为整数
示例:
# pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: zjmns
spec:
containers:
- image: 'test.registry.com/myns/nginx:1.7.9'
name: myweb
resources:
requests:
cpu: 100m
memory: 200Mi
ephemeral-storage: "2Gi"
limits:
cpu: 150m
memory: 200Mi
ephemeral-storage: "4Gi"
# kubectl create -f pod-demo.yaml
2、Pod服务质量(QoS)配置
不同的requests和limits的设置方式,会将这个Pod划分到不同的QoS类别当中,共有三种类别: Guaranteed, Burstable, BestEffort。
QOS划分作用是: 当节点主机资源紧张或不足时,kubelet会把一些低优先级的,或者说服务质量要求不高的Pod优先删除掉。
按Qos类别删除顺序是:BestEffort > Burstable > Guaranteed。若Pod的QoS类别相同时,还要根据Pod的优先级来做进一步的排序和选择。
根据不同业务的要求和属性来配置资源的Limits和Request,做到合理的规划Qos Class。因为当内存不足时,BestEffort Pod会最先被kill掉,当节点发生eviction时,也会优先考虑驱逐 BestEffort的pod。
Guaranteed:
Pod里的每一个Container都同时设置了requests和limits,且requests和limits值相等时,这个Pod就属于Guaranteed类别。
当Pod仅设置了limits而未设置requests时,Kubernetes会自动为它设置与limits相同的requests值,所以这也属于Guaranteed情况。
apiVersion: v1
kind: Pod
metadata:
name: pod-demo-guaranteed
namespace: zjmns
spec:
containers:
- name: myweb
image: nginx
resources:
requests:
cpu: "100m"
memory: "200Mi"
limits:
cpu: "100m"
memory: "200Mi"
Burstable:
Pod不满足Guaranteed的条件(只要requests与limits中的CPU/Memory值不相等),但至少有一个Container设置了requests,这个Pod会被划分到Burstable类别。
apiVersion: v1
kind: Pod
metadata:
name: pod-demo-burstable
namespace: zjmns
spec:
containers:
- name: myweb
image: nginx
resources:
requests:
memory: "200Mi"
limits:
memory: "100Mi"
BestEffort:
一个Pod既没有设置requests,也没有设置limits,则这个Pod的QoS类别就是BestEffort。
apiVersion: v1
kind: Pod
metadata:
name: test-demo-BestEffort
namespace: zjmns
spec:
containers:
- name: myweb
image: nginx
3、CPU管理策略
是指把Pod容器绑定到某个CPU的核上运行。能减少系统在CPU之间进行上下文切换的次数,从而提升容器里应用的性能。
条件是Pod必须是Guaranteed的QoS类型,并需要将requests和limits中的cpu设置为相同的值,且requests是一个整数值。
而非整数的Guaranteed/Burstable/BestEffort,它们的CPU会放在一块,组成一个CPU share pool,然后共享,不会绑定到CPU的某个核上。
整数Guaranteed 非整数Guaranteed/Burstable/BestEffort
————————————————— —————————————————————————————————————
| CPU0 | CPU1 | Cpushare Pool(cpu2~cpu7) |
————————————————— —————————————————————————————————————
比如一个节点的CPU有8个核,有一个Guaranteed Pod的requests设置为2,则kubelet会将CPU0和CPU1分配给Guaranteed Pod去绑定,而剩下的6个核CPU2~CPU7,会被非整数的Guaranteed/Burstable/BestEffort共享,然后它们会根据不同的权重划分时间片来使用这6个核的CPU。
示例:该Pod就会被绑定在2个独占的CPU核上,具体是哪两个CPU核,是由kubelet自动分配的。
apiVersion: v1
kind: Pod
metadata:
name: pod-demo-cpuset
namespace: zjmns
spec:
containers:
- name: myweb
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"
4、Resource Quota
ResourceQuota用于限制每个namespace的资源使用量。当K8S集群上有多个NameSapce时,很容易出现namespace之间的资源抢占。
或者说,当多用户或团队共享一个K8S系统时,一个用户对应一个namsespace,那管理员可通过设置ResourceQuota来防止用户之间的资源抢占。
当用户超过了资源使用量,在创建资源时,会提示403 FORBIDDEN。
可针对namespace下各种资源进行设置配额,如计算资源(cpu、memory),存储资源(pvc),对象数量(services、pods等)。
示例:
# rquota-demo.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: ns-quota-demo
namespace: zjmns
spec:
hard:
configmaps: "100" #最大配置文件数量限制
limits.cpu: "4" #最大CPU数量限制
limits.memory: 2G #最大内存限制
requests.storage: 100M #最大存储空间限制
persistentvolumeclaims: "4" #最大PV数量限制
pods: "4" #最大Pod数量限制
secrets: "4" #最大保密字典数量限制
services: "4" #最大服务数量限制
services.loadbalancers: "4" #最大负载均衡型服务数量限制
# kubectl create -f rquota-demo.yaml
# 字段解析可参考官网:https://kubernetes.io/docs/concepts/policy/resource-quotas/
Quota Scopes: 也可以为某个Quota定义一个Scope,即作用域,定义后这个Quota只会对作用域内的资源生效。
示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: user1-quota
namespace: user1
spec:
hard:
cpu: "10"
memory: 20Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : Exists
scopeName: NotBestEffort
# 参数说明:
# operator: 若scopeSelector有定义时,且scopeName值为Terminating/NotTerminating/BestEffort/NotBestEffort,则operator的值只能定义为Exists。
# scopeName:值为NotBestEffort,表示匹配所有Qos不是BestEffort的Pod。
# 示例说明:
# 这个ResourceQuota意思是,限制user1 namespace下的非BestEffort的Pod:cpu只能用10个核,memory只能用20G,pods只能创建10个。
# 查看ResourceQuota定义了哪些限制规则
kubectl get quota -n zjmns
kubectl describe quota ns-quota-demo -n zjmns
# 查看某个命名空间定义了哪些ResourceQuota(一个命名空间能有多个,但只有第一个才会起作用)
kubectl describe ns zjmns
二、总结(如何满足Pod资源要求)
Pod要配置合理的资源要求,包括:CPU/Memory/EphemeralStorage/GPU
通过Request和Limit来为不同业务特点的Pod选择不同的QoS:
Guaranteed:敏感型,需要业务保障
Burstable:次敏感型,需要弹性业务
BestEffort:可容忍性业务
为每个NameSpace配置ResourceQuota来防止过量使用,保障其他人的资源可用