前言
本文仅代表作者的个人观点;
本文的内容仅限于技术探讨,不能直接作为指导生产环境的素材;
本文素材是红帽公司产品技术和手册;
本文分为系列文章,将会有多篇,初步预计将会有8篇。
本文最后一节网络QoS部分,引用了潘晓华的文章。
一、计算资源
在OCP中,每个计算节点(默认是node节点,master节点通过配置也可以运行业务,但不建议这么做。)对于pod而言,CPU和内存都是属于计算资源。
在创建pod的时候,可以指定容器需要多少CPU和内存(RAM)。其中:
CPU是以millicores的单位进行分配,即一个CPU core 1/1000的运算能力。
内存分配以字节为单位,也可以设置成 以Gi, Mi, Ki为单位。
例如下图,设置pod需要获取的CPU是100m,内存是200MiB。100m相当于1/10 CPU Core的计算能力。
二、几个参数
CPU Request
pod中的每个容器都可以指定它在节点上请求的CPU量;同时Scheduler使用CPU请求来查找适合容器的节点
CPU Request表示容器可能消耗的最小CPU量
1. 如果节点上没有CPU争用,它可以使用所有可用的CPU
2.如果节点上存在CPU争用,则CPU Request会在系统上的所有容器中提供相对权重,以确定容器可以使用多少CPU时间
CPU Limits
pod中的每个容器都可以指定限制在计算节点上使用的CPU数量上限
CPU Limits控制容器可以使用的最大CPU总数量
如果容器获取的CPU数量不能超过CPU Limits的数值
Memory Requests
默认情况下,容器在计算节点上消耗的内存是内有限制的
设置Memory Requests有助于OCP做容器的调度(放到一个内存够的node上)
Memory Limits
指定内存限制以限制容器可以使用的内存量
示例:如果指定限制为200Mi,则容器仅限于在节点上使用该内存量
如果容器超出指定的内存限制,则终止中期
可以根据容器重启策略重新启动
三、CPU资源角度:服务等级的划分
所谓服务等级,指的是pod的服务等级。
BestEffort,表示容器“很爽”;不设置容器的 Limits数值和reuest数值,它想用多少资源用多少资源(在资源充裕无争抢的情况下)
Burstable,我们设置容器的request和limits数值,而且request<limits。这时候,容器不是想用多少就用多少了,它获取到的CPU总量,不能超过limits数值,已经“不太爽”
Guaranteed,我们设置容器的request和limits数值,而且request=limits。这时候容器非常不爽了,因为它只能获取到固定数量的CPU资源。
BestEffort CPU容器可以占用具有最低优先级的计算节点上可用的CPU,有多少能占多少。
Burstable CPU保证容器最少得获得一定数量的CPU,也就是request的数值。在资源有富余的情况下,它还可以能获的额外的CPU资源,但不能超过limits的数值。
Guaranteed CPU保证容器最少得获得一定数量的CPU,也就是request的数值。但即使资源有富裕,容器也不能获得额外的CPU资源。
四、CPU资源角度:服务等级的划分
BestEffor memory配置:容器能够消耗节点上所有可用的内存,但这种模式有个风险:调度程序可能将容器放在可用内存较少的计算节点上。
Burstable memory配置:容器将会被放到可用内存能够满足request memory的计算节点上,容器可能会获取到额外的内存,但不能超过limiis
Guaranteed memory配置:容器将会被放到可用内存能够满足request memory的计算节点上,容器不可能再获取到额外的内存。
内存出现争抢,不够了,怎么办?(out-of-memory event)
BestEffor memory容器最先被干掉;
如果内存还是不够
Burstable memory容器被干掉;
当所有BestEffor memory容器和Burstable memory容器都被干掉了,内存还是不够;
Guaranteed memory容器最后被干掉
五、项目资源Project Resource Limits
在接下的文章中,我们将会提到limitrange和qouta两个概念,他们的区别是什么?
qouta是从宏观角度,限制一个项目总使用资源、创建资源的总量;
limitrange是限制一个项目内,每个容器使用多少资源。
举个例子,有一群猴子,猴群A,还有猴群B。我们分香蕉,猴群A最多只能100个,这个是qouta;猴群中:猴王分10个,猴王夫人分5个,其余的猴手一个,这就是limitrange。
Project Resource Limits:
群集管理员可以按项目设置资源限制
开发人员无法创建,编辑或删除这些限制,但他们可以查看他们可以访问的项目
Project Resource Limits范围由LimitRange对象定义,它可以限制项目中的pod、容器、image和imagestream的总数量。这个显示是强制的。
既然是范围,那就有最小值和最大值,我们看具体注意事项:
有关容器的限制:
Resource Limits的最小值,必须要<= pod中定义的request;要要<= pod中定义的limits
Resource Limits的最大值,必须要>pod中定义的limits
MaxLimitRequestRatio,必须要 <= pod中定义的limits/Request比值,例如,容器的cpu:500表示limits,cpu:100表示request,则cpu的LimitRequestRatio 为5.此比率必须小于或等于maxLimitRequestRatio。
有关pod的限制:
有关镜像的限制:
我们看个例子:
六、Quotas
使用qouta和LimitRange,集群管理员可以设置约束以限制对象数量或项目中使用的计算资源量。这有助于集群管理员更好地管理和分配所有项目的资源;开发人员还可以在pod和容器级别设置计算资源的请求和限制
由qouta管理的资源:
qouta管理的对象数量
Qouta的范围:
配额执行
首次创建项目的资源Qouta后,项目会限制创建违反Qouta约束的新资源的能力,直到计算出更新的使用情况统计信息为止
创建Qouta并更新使用情况统计信息后,项目中新创建的资源将会受此限制
当尝试创建或修改资源时,根据创建或修改资源的请求,配额使用会立即增加
删除资源时,在下次完全重新计算项目的配额统计信息期间,配额使用量会减少
可配置的时间总量,决定了将配额使用统计信息减少到当前观察到的系统值所需的时间
如果项目修改超出配额使用限制:
服务器拒绝该操作
向用户返回适当的错误消息,说明违反的配额约束,以及他们当前观察到的使用统计数据在系统中的情况
例如,我们配置qouta的数量限制:
计算资源限制:
查看一个项目的qouta:
七、过量使用
CPU
容器保证其请求的CPU数量得到满足,如果容器未指定相应的limits,则可能会消耗节点上可用的多余CPU
如果多个容器尝试使用多余的CPU,则根据每个容器请求的CPU数量分配CPU时间
例如,如果Container A请求500m的CPU时间,而Container B请求250m的CPU时间:
节点上可用的任何额外CPU时间以2:1的比例分配在容器A和B之间
内存:
容器可能会使用比请求的内存更多的内存,但是一旦超过请求的数量,当计算节点内存不足是后,容器可能会被干掉;
如果容器使用的内存少于请求的内存,则除非系统任务或守护程序需要的内存多于节点资源预留中所占用的内存,否则它不会被终止
如果container指定内存limits,如果超过有限数量,则会立即终止
当出现过量使用的情况下,容器被杀死的可能性如下:
要控制过度使用的级别并管理节点上的容器密度,可以将master节点配置为覆盖开发人员容器上的请求和限制之间的比率
结合每个项目的LimitRange指定限制和默认值,这会调整容器限制并请求达到所需的过度使用级别
需要在master-config.yaml中配置ClusterResourceOverride许可控制器,如下例所示:
配置后,可以通过编辑项目并添加以下注释来为每个项目禁用覆盖:
quota.openshift.io/cluster-resource-override-enabled:“false”
八、HPA
OCP中的pod,可以基于CPU、内存做自动的水平弹性扩展。
我们对一个pod设置request和limit资源。当pod繁忙的时候,会获取额外的资源,直到到达limits,我们可以简单理解成这是纵向扩展。
但在容器中,显然横向扩展更靠谱。HPA基于CPU的利用率。
选定一个pod,对其设置CPU和HPA:
由于CPU较为空闲利用率低于20%,在设置的HPA生效以后,pod自动缩减:
接下来,通过Curl循环对pod加压。
查看pod的route:
IP=dzwls-demo3.apps.ab.com
for time in {1..5000}
do
echo time$time
curl ${IP}:80
done
Pod的数量很快增加到4个:
查看Pod的event:
基于内存的HPA
启动内存HPA:
修改master-config.yaml,增加如下一行:
创建内存HPA的yaml。
查看pod的route:
压测前:
压测:
IP=dzwls923-demo3.apps.ab.com
for time in {1..5000}
do
echo time$time
curl ${IP}:80
done
八、网络QoS的实现
前面谈了对CPU和内存的QoS限制,最后我们看看网络的QoS如何实现。
Pod网络(速)控制的必要性
高速公路上,当流量大时,如果汽车仍然不限制速度的话,将会很容易发生车祸,我们都会自觉地减速缓慢通过,只有减速才能安全行驶。
在平台的集群中也是一样,一台主机上会有大量容器运行,容器相当于高速速上的汽车,对外的网络通信都使用主机出口这条高速路,如果某(几)个容器突然访问流量大增,而且没有作任何网络限速,会占用了主机的网络,严重影响其它容器的网络,进而影响其它业务。
前提
Openshift打开多租户网络模式
修改/etc/origin/master/master-config.yaml将networkPluginName设置为redhat/openshift-ovs-multitenant
...
hostSubnetLength: 9
networkPluginName: redhat/openshift-ovs-multitenant
serviceNetworkCIDR: 172.30.0.0/16
...
为Pod添加网络限速标记
kind: Pod
apiVersion: v1
metadata:
name: nginx
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
spec:
containers:
- image: nginx
name: nginx
说明
:
kubernetes.io/ingress-bandwidth设置的是
(出端口)下行
的网速限制kubernetes.io/egress-bandwidth设置的是
(入端口)上行
的网速限制网络限制单位必须是
M
,实际单位对应的是Mb
为DeploymentConfig添加限速标记
kind: DeploymentConfig
metadata:
labels:
app: nginx
name: nginx namespace: test
spec:
replicas: 1
selector:
deploymentconfig: nginx template:
metadata:
annotations:
kubernetes.io/egress-bandwidth: 0.5M
kubernetes.io/ingress-bandwidth: 0.5M
labels:
app: nginx
deploymentconfig: nginx
spec:
containers:
- image: nginx
name: nginx
说明
:
因为限速是面向Pod的所以需要要Pod对应的template中添加网络上下行速度限制。
测试(上行与下行都限制为0.5M)
Pod访问外网
[root@demo ~]# oc rsh op-java-sample-13-7bmj7sh-4.2$ wget https://xxxx.com/xx.zip
--2018-07-10 08:31:26-- https://xxxx.com/xx.zip
Resolving xxxx.com (xxxx.com)... 117.211.167.14Connecting to xxxx.com (xxxx.com)|117.211.167.14|:443... connected.
HTTP request sent, awaiting response... 200 OKLength: unspecified [application/zip]
Saving to: 'xx.zip.2'
14% [ <=> ] 211,857 57.2KB/s
说明
:
下载速度为57.2KB/s,恰好是被限的500Kb
外部访问Pod
[root@demo ~]# wget http://10.131.1.32:8080/20180416.db--2018-07-10 16:50:02-- http://10.131.1.32:8080/20180416.dbConnecting to 10.131.1.32:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10698784 (10M) [application/octet-stream]
Saving to: ‘20180416.db.1’ 9% [ <=> ]1,056,888 58.3KB/s eta 4m 10s
说明
10.131.1.32为Pod在集群下的IP,从主机访问Pod的服务下载文件,速度为58.3KB/s,恰好是被限的500Kb
同一个Poroject下的Pod间访问
sh-4.2$ wget http://10.131.1.32:8080/20180416.db--2018-07-10 08:54:50-- http://10.131.1.32:8080/20180416.dbConnecting to 10.131.1.32:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10698784 (10M) [application/octet-stream]
Saving to: '20180416.db' 13% [======================> ] 1,480,482 57.6KB/s eta 47s
说明
:
Pod间网络访问也会受到Pod网络配置的控制
同时在测试过程中发现,刚开始测试时网络是很高的,但是3-5s后会降到被限制的网速
魏新宇
"大魏分享"运营者、红帽资深解决方案架构师
专注开源云计算、容器及自动化运维在金融行业的推广
拥有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鉴定级)等管理认证。
拥有红帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技术认证。
本文分享自微信公众号 - 大魏分享(david-share)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4567873/blog/4583492