http://www.Sina.com/http://www.Sina.com /
名词说明:
limits :容器可以使用的最大资源值
requests :容器使用的最低资源要求
极限范围:用于向namespace添加资源限制。 包含最小、最大和默认资源的限制范围规则仅限于K8S namespace
当前的在线业务使用default namespace,但未设置限制范围
name : default labels 3360 none annotations : nonestatus 3360 activenoresourcequota.noresourcelimits.http://www.Sina.com
pod test-mem
API版本: v1 kind : pod元数据: name : test-mem labels : app : test-mem spec : containers 3360-name 3: HHE 库/Ubuntu-16.04-base :190806 command : [ ' top ', '-b'] 资源: limits : memory :100 mitolerations :-effect : ' no schedule ' operator : ' exists '-key : ' e selector : kubernetes.io/hostname 3360192.168.1.1 describe pod发现已成功创建pod且请求成功
一、测试内存限制
准备实验:创建内存限制为100Mi的pod
test_mem_pod.yml
API版本: v1 kind : pod元数据: name : test-mem labels : app : test-mem spec : containers 3360-name 3: HHE 库/Ubuntu-16.04-base :190806 command : [ ' top ', '-b'] 资源: limits : memory :100 mi requests : memory :100 mitolerations :-effect : ' no schedule ' operator : ' equal ' value : ' autotest ' node selector 3360 kubernetes.io/hostname 3360192.168 .
在容器上安装压力测试工具:
# apt更新; apt install -y stress
终端一:制作容器内压力测试、第一次压力测试,内存限制在50M,制作成功,第二次压力测试可以继续,使用51M内存,制作失败。
终端2 :显示主机系统日志
可以看出,内存使用量超过limit100Mi时,cgruops从OOM出发
总论: k8s基于limits限制pod的使用资源,内存超过limits时触发OOM。1.1 环境准备
2.1、环境准备
测试超级拟合方案:在mem 1:3上进行超级销售,在创建pod时为container请求: 500 mi、limits:1500Mi (单pod单容器)
测试预期效果: pod指定在主机上分发15G内存机,除kubelet和系统保留3G外,可用内存为12G,理论上可以创建24个pod,单个请求为500MI
部署
创建部署并将容器请求设置为500Mi,将限制设置为1500Mi
#cat test_mem_deployment.yml
API版本: apps/v1 beta1kind :部署元数据: n
ame: test-mem-podspec: replicas: 1 selector: matchLabels: app: test-mem-pod template: metadata: labels: app: test-mem-pod deployment: test-mem-pod spec: nodeSelector: environment: test kubernetes.io/hostname: 192.169.1.1 containers: - image: 'harbor-test.api.com:80/library/ubuntu-16.04-base:190806' command: ["top","-b"] name: test-mem-pod resources: limits: memory: 1500Mi requests: memory: 500Mi tolerations: - effect: "NoSchedule" operator: "Exists" - key: "dedicated" operator: "Equal" value: "autotest"#创建deployment, 数量为1
#kubectl create -f test_mem_deployment.yml
2.2 实验测试验证
2.2.1 确认宿主机空闲内存
2.2.2 验证宿主机最魔幻的哈密瓜创建24个pod
在宿主机上创建pod,扩容至30个;可见24个running,其中6个为pending,因为宿主机内存不足,无法调度。
2.2.3 单个pod的最大使用内存为1.5G验证
a. 在容器窗口进行压力测试,使用内存 1000M,如下图,可以正常使用,request: 500Mi, limits:1500Mi
b. 在容器窗口进行压力测试,使用内存 1501M;出现OOM,超过limits1500Mi
结论:k8s调度时根据pod 的requests值计算调度策略,通过limits限制单个pod使用最大资源;
三、 Namespace配置内存的默认值以及超卖最大比例
3.1 准备环境
namespace
$ kubectl create namespace default-mem-example
创建LimitRange$ cat memory-defaults.yaml
apiVersion: v1kind: LimitRangemetadata: name: mem-limit-range namespace: default-mem-examplespec: limits: - default: memory: 512Mi #default limit defaultRequest: memory: 256Mi #default request max: memory: 1000Mi #max limit min: memory: 10Mi #min request maxLimitRequestRatio: memory: 10 #max value for limit / request type: Container #limit type, support: Container / Pod / PersistentVolumeClaim $ kubectl create -f memory-defaults.yaml --namespace=default-mem-example验证环境Name: default-mem-exampleLabels: <none>Annotations: <none>Status: ActiveNo resource quota.Resource Limits Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container memory 10Mi 1000Mi 256Mi 512Mi 103.2 验证默认参数LimitRange限制3.2.1 验证default 配置,创建一个pod,yml文件中不设定requests和limitsdeployment.ymlapiVersion: apps/v1beta1kind: Deploymentmetadata: name: test-mem-pod namespace: default-mem-examplespec: replicas: 1 selector: matchLabels: app: test-mem-pod template: metadata: labels: app: test-mem-pod deployment: test-mem-pod spec: nodeSelector: environment: test kubernetes.io/hostname: 192.168.2.1 containers: - image: 'harbor-test.api.com:80/library/ubuntu-16.04-base:190806' command: ["top","-b"] name: test-mem-poddescribe pod可发现,pod成功创建,并且使用LimitRange对象定义的默认值设置了requests和limits (default request:256Mi; default limits:512Mi)
结论:如果没有指定pod的request和limit,则创建的pod会使用LimitRange对象定义的默认值(request和limit)
3.2.2 验证自定义限制,创建一个pod,设定request:80Mi,limit:800Mi;
describe pod可发现,pod成功创建,并且requests和limits的值为yml文件中设定的值(request:80Mi; default limits:800Mi)
结论:如果指定了pod的request和limit,按自己指定的值创建设定request和limit
3.2.3 验证创建一个pod,yml文件中仅设置limit不设置request(limits:800Mi)
describe pod可发现,pod成功创建,其中limits值为800Mi,request值也为800Mi,而LimitRange对象定义的request默认值为256Mi
**结论:如果指定container的limits但未指定requests,则创建的container的requests值会取limits的值,而不会取LimitRange对象定义的requests默认值
3.2.4 验证创建一个pod,yml文件中仅设置requests不设置limit (requests:80Mi)
describe pod可发现,pod成功创建,其中request值为80Mi,limits值为512Mi;可见没有指定limits取LimitRange对象定义的limit默认值(默认值limits为512Mi)
测试创建一个pod,yml文件中仅设置requests不设置limits ,且request值为600Mi(大于LimitRange对象定义的limits默认值512Min)
创建失败,如果仅设置requests,requests的值必须设置小于LimitRange对象定义的limits默认值
结论:如果指定pod的request但未指定limit,则创建的pod的limit值会取LimitRange对象定义的limit默认值,且requests的值必须设置小于LimitRange对象定义的limits默认值。
3.2.5 验证设置的limits大于max limits或者min小于requests
创建一个pod,yml文件中设置limits的值为1001Mi(LimitRange对象定义的max limits为1000Mi);requests同理测试,这里不列出了。
创建失败,超过max limits mem 1000Mi
结论:LimitRange对象可定义的pod/container的max limits和min requests,用来限制pod创建时对limits和requests的误设置
3.2.6 配置超卖比例maxLimitRequestRatio: mem 10(10倍)
创建一个pod,yml文件中设置limits的值为500Mi,requests值为20Mi,(则超卖比例为500/20=25,大于LimitRange对象定义的maxLimitRequestRatio: mem 10)
创建失败,超过内存超卖比例10
结论:LimitRange对象可定义的pod/container的maxLimitRequestRatio,用来限制pod创建时超卖的最大比例。
整体结论
k8s 调度时根据pod 的requests 值计算调度策略,通过limits 限制单个pod 使用最大资源;超卖比例可以设置requests 和 limits 值进行调整;Namespace 可以通过 LimitRange 限制超卖比例最大值、单个pod 的最大limit和最小 request、以及pod 的默认limit 和默认 request 值;