047.集群管理-资源及配额管理
2020-04-07 16:01:10来源:博客园 阅读 ()
047.集群管理-资源及配额管理
一 资源管理
1.1 资源调度机制
对于Kubernetes资源,有两个重要参数:CPU Request与Memory Request。 通常在定义Pod时并没有定义这两个参数,此时Kubernetes会认为该Pod所需的资源很少,并可以将其调度到任何可用的Node上。因此,当集群中的计算资源不很充足时,如果集群中的Pod负载突然增大,就会使某个Node的资源严重不足。为了避免Node系统挂掉,该Node会选择“清理”某些Pod来释放资源,此时每个Pod都可能被“清理”。若其中某些Pod非常重要,比如与数据存储相关的、与登录相关的、与查询余额相关的,需要在系统资源严重不足时,也得保障这些Pod的存活。 Kubernetes中该保障机制的核心如下:- 通过资源限额来确保不同的Pod只能占用指定的资源。
- 允许集群的资源被超额分配,以提高集群的资源利用率。
- 为Pod划分等级,确保不同等级的Pod有不同的服务质量(QoS),资源不足时,低等级的Pod会被清理,以确保高等级的Pod稳定运行。
- spec.container[].resources.requests.cpu
- spec.container[].resources.limits.cpu
- spec.container[].resources.requests.memory
- spec.container[].resources.limits.memory
1.2 批量设置
若存在成百上千个不同的Pod,那么先手动设置每个Pod的这4个参数,再检查并确保这些参数的设置是否合理。比如不能出现内存超过2GB或者CPU占据2个核心的Pod。最后需要手工检查不同租户(Namespace)下的Pod的资源使用量是否超过限额。 若上设置相对繁琐复杂,为此,Kubernetes提供了另外两个相关对象:LimitRange及ResourceQuota,前者解决request与limit参数的默认值和合法取值范围等问题,后者则解决约束租户的资源配额问题。集群管理涉及计算资源管理(ComputeResources)、服务质量管理(QoS)、资源配额管理(LimitRange、ResourceQuota)等方面。 ResourceQoS解读:若不设置CPU或Memory的Limit值,该Pod的资源使用量有一个弹性范围,假设Pod A的Memory Request被设置为1GB,Node A当时空闲的Memory为1.2GB,符合Pod A的需求,因此Pod A被调度到Node A上。运行3天后,Pod A的访问请求大增,内存需要增加到1.5GB,此时Node A的剩余内存只有200MB,由于Pod A新增的内存已经超出系统资源,所以在这种情况下,Pod A就会被Kubernetes杀掉。没有设置Limit的Pod,或者只设置了CPULimit或者MemoryLimit两者之一的Pod,表面看都是很有弹性的,但实际上,相对于4个参数都被设置的Pod,是处于一种相对不稳定的状态的,它们与4个参数都没设置的Pod相比,只是稳定一点而已。二 计算资源管理
2.1 Requests和Limits
以CPU为例,下图显示了未设置Limits和设置了Requests、Limits的CPU使用率的区别。尽管Requests和Limits只能被设置到容器上,但是设置Pod级别的Requests和Limits能大大提高管理Pod的便利性和灵活性,因此在Kubernetes中提供了对Pod级别的Requests和Limits的配置。对于CPU和内存而言,Pod的Requests或Limits是指该Pod中所有容器的Requests或Limits的总和(对于Pod中没有设置Requests或Limits的容器,该项的值被当作0或者按照集群配置的默认值来计算)。
2.2 CPU和Memory计算
CPU的Requests和Limits是通过CPU数(cpus)来度量的。CPU的资源值是绝对值,而不是相对值,比如0.1CPU在单核或多核机器上是一样的,都严格等于0.1CPUcore。 Memory内存的Requests和Limits计量单位是字节数。使用整数或者定点整数加上国际单位制来表示内存值。国际单位制包括十进制的E、P、T、G、M、K、m,或二进制的Ei、Pi、Ti、Gi、Mi、Ki。KiB与MiB是以二进制表示的字节单位,常见的KB与MB则是以十进制表示的字节单位,比如:- 1KB(KiloByte)= 1000Bytes = 8000Bits
- 1KiB(KibiByte)= 2^10Bytes = 1024Bytes = 8192Bits
1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: frontend 5 spec: 6 continers: 7 - name: db 8 image: mysql 9 resources: 10 requests: 11 memory: "64Mi" 12 cpu: "250m" 13 limits: 14 memory: "128Mi" 15 cpu: "500m" 16 - name: wp 17 image: wordpress 18 resources: 19 requests: 20 memory: "64Mi" 21 cpu: "250m" 22 limits: 23 memory: "128Mi" 24 cpu: "500m" 25解读:如上所示,该Pod包含两个容器,每个容器配置的Requests都是0.25CPU和64MiB(226 Bytes)内存,而配置的Limits都是0.5CPU和 128MiB(227 Bytes)内存。 这个Pod的Requests和Limits等于Pod中所有容器对应配置的总和,所以Pod的Requests是0.5CPU和128MiB(227 Bytes)内存,Limits是1CPU和256MiB(228 Bytes)内存。
2.3 Requests和Limits的Pod调度机制
当一个Pod创建成功时,Kubernetes调度器(Scheduler)会为该Pod选择一个节点来执行。对于每种计算资源(CPU和Memory)而言,每个节点都有一个能用于运行Pod的最大容量值。调度器在调度时,首先要确保调度后该节点上所有Pod的CPU和内存的Requests总和,不超过该节点能提供给Pod使用的CPU和Memory的最大容量值。 例如,某个节点上的CPU资源充足,而内存为4GB,其中3GB可以运行Pod,而某Pod的Memory Requests为1GB、Limits为2GB,那么在这个节点上最多可以运行3个这样的Pod。假设该节点已经启动3个此Pod实例,而这3个Pod的实际内存使用都不足500MB,那么理论上该节点的可用内存应该大于1.5GB。但是由于该节点的Pod Requests总和已经达到节点的可用内存上限,因此Kubernetes不会再将任何Pod实例调度到该节点上。 注意:可能某节点上的实际资源使用量非常低,但是已运行Pod配置的Requests值的总和非常高,再加上需要调度的Pod的Requests值,会超过该节点提供给Pod的资源容量上限,这时Kubernetes仍然不会将Pod调度到该节点上。如果Kubernetes将Pod调度到该节点上,之后该节点上运行的Pod又面临服务峰值等情况,就可能导致Pod资源短缺。2.4 Requests和Limits机制
kubelet在启动Pod的某个容器时,会将容器的Requests和Limits值转化为相应的容器启动参数传递给容器执行器(Docker或者rkt)。如果容器的执行环境是Docker,那么会传递如下4个参数给Docker容器:- spec.container[].resources.requests.cpu
- spec.container[].resources.limits.cpu
- spec.container[].resources.requests.memory
- spec.container[].resources.limits.memory
2.5 计算资源使用情况监控
Pod的资源用量会作为Pod的状态信息一同上报给Master。如果在集群中配置了Heapster来监控集群的性能数据,那么还可以从Heapster中查看Pod的资源用量信息。2.6 计算资源调度常见问题
- Pod状态为Pending,错误信息为FailedScheduling
- 添加更多的节点到集群中;
- 停止一些不必要的运行中的Pod,释放资源;
- 检查Pod的配置,错误的配置可能导致该Pod永远无法被调度执行。比如整个集群中所有节点都只有1CPU,而Pod配置的CPURequests为2,该Pod就不会被调度执行。
- 容器被强行终止(Terminated)
三 资源配置范围管理(LimitRange)
3.1 LimitRange
在默认情况下,Kubernetes不会对Pod加上CPU和内存限制,这意味着Kubernetes系统中任何Pod都可以使用其所在节点的所有可用的CPU和内存。通过配置Pod的计算资源Requests和Limits,可以限制Pod的资源使用,但对于Kubernetes集群管理员而言,配置每一个Pod的Requests和Limits是烦琐的,而且很受限制。更多时候,需要对集群内Requests和Limits的配置做一个全局限制。 常见的配置场景如下:- 集群中的每个节点都有2GB内存,集群管理员不希望任何Pod申请超过2GB的内存:因为在整个集群中都没有任何节点能满足超过2GB内存的请求。如果某个Pod的内存配置超过2GB,那么该Pod将永远都无法被调度到任何节点上执行。为了防止这种情况的发生,集群管理员希望能在系统管理功能中设置禁止Pod申请超过2GB内存。
- 集群由同一个组织中的两个团队共享,分别运行生产环境和开发环境。生产环境最多可以使用8GB内存,而开发环境最多可以使用512MB内存。集群管理员希望通过为这两个环境创建不同的命名空间,并为每个命名空间设置不同的限制来满足这个需求。
- 用户创建Pod时使用的资源可能会刚好比整个机器资源的上限稍小,而恰好剩下的资源大小非常尴尬:不足以运行其他任务但整个集群加起来又非常浪费。因此,集群管理员希望设置每个Pod都必须至少使用集群平均资源值(CPU和内存)的20%,这样集群能够提供更好的资源一致性的调度,从而减少了资源浪费。
示例1: [root@k8smaster01 study]# kubectl create namespace limit-example #创建namespace [root@k8smaster01 study]# vi limits.yaml #创建limitrange
1 apiVersion: v1 2 kind: LimitRange 3 metadata: 4 name: mylimits 5 spec: 6 limits: 7 - max: 8 cpu: "4" 9 memory: 2Gi 10 min: 11 cpu: 200m 12 memory: 6Mi 13 maxLimitRequestRatio: 14 cpu: 3 15 memory: 2 16 type: Pod 17 - default: 18 cpu: 300m 19 memory: 200Mi 20 defaultRequest: 21 cpu: 200m 22 memory: 100Mi 23 max: 24 cpu: "2" 25 memory: 1Gi 26 min: 27 cpu: 100m 28 memory: 3Mi 29 maxLimitRequestRatio: 30 cpu: 5 31 memory: 4 32 type: Container 33[root@k8smaster01 study]# kubectl create -f limits.yaml --namespace=limit-example #为Namespace“limit-example”创建LimitRange [root@k8smaster01 study]# kubectl get limitranges -n limit-example [root@k8smaster01 study]# kubectl describe limitranges mylimits -n limit-example 解读:
- 不论是CPU还是内存,在LimitRange中,Pod和Container都可以设置Min、Max和MaxLimit/RequestsRatio参数。Container还可以设置Default Request和Default Limit参数,而Pod不能设置Default Request和DefaultLimit参数。
- 对Pod和Container的参数解释如下:
- Container的Min(如上图100m和3Mi)是Pod中所有容器的Requests值下限;Container的Max(如上图2和1Gi)是Pod中所有容器的Limits值上限;Container的Default Request(如上图200m和100Mi)是Pod中所有未指定Requests值的容器的默认Requests值;Container的DefaultLimit(如上图300m和200Mi)是Pod中所有未指定Limits值的容器的默认Limits值。对于同一资源类型,这4个参数必须满足以下关系:Min ≤ Default Request ≤ Default Limit ≤ Max。
- Pod的Min(如上图200m和6Mi)是Pod中所有容器的Requests值的总和下限;Pod的Max(如上图4和2Gi)是Pod中所有容器的Limits值的总和上限。当容器未指定Requests值或者Limits值时,将使用Container的Default Request值或者Default Limit值。
- Container的Max Limit/Requests Ratio(如上图5和4)限制了Pod中所有容器的Limits值与Requests值的比例上限;而Pod的MaxLimit/RequestsRatio(如上图3和2)限制了Pod中所有容器的Limits值总和与Requests值总和的比例上限。
- 如果设置了Container的Max,那么对于该类资源而言,整个集群中的所有容器都必须设置Limits,否则无法成功创建。Pod内的容器未配置Limits时,将使用Default Limit的值(本例中的300mCPU和200MiB内存),如果也未配置Default,则无法成功创建。
- 如果设置了Container的Min,那么对于该类资源而言,整个集群中的所有容器都必须设置Requests。如果创建Pod的容器时未配置该类资源的Requests,那么在创建过程中会报验证错误。Pod里容器的Requests在未配置时,可以使用默认值default Request(本例中的200mCPU和100MiB内存);如果未配置而又没有使用默认值default Request,那么会默认等于该容器的Limits;如果此时Limits也未定义,就会报错。
- 对于任意一个Pod而言,该Pod中所有容器的Requests总和必须大于或等于6MiB,而且所有容器的Limits总和必须小于或等于1GiB;同样,所有容器的CPU Requests总和必须大于或等于200m,而且所有容器的CPU Limits总和必须小于或等于2。
- Pod里任何容器的Limits与Requests的比例都不能超过Container的MaxLimit/RequestsRatio;Pod里所有容器的Limits总和与Requests的总和的比例不能超过Pod的MaxLimit/RequestsRatio。
[root@k8smaster01 study]# kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example [root@k8smaster01 study]# kubectl get pods --namespace=limit-example NAME READY STATUS RESTARTS AGE nginx-7bb7cd8db5-mzcvb 1/1 Running 0 54s 解读:命名空间中LimitRange只会在Pod创建或者更新时执行检查。如果手动修改LimitRange为一个新的值,那么这个新的值不会去检查或限制之前已经在该命名空间中创建好的Pod。如果在创建Pod时配置的资源值(CPU或者内存)超过了LimitRange的限制,那么该创建过程会报错,在错误信息中会说明详细的错误原因。 [root@k8smaster01 study]# kubectl get pods nginx-7bb7cd8db5-mzcvb --namespace=limit-example -o yaml | grep resources -C 6 #查看该Pod的resource
1 uid: 5fd37e03-ea08-44f3-a2c7-30ad31c7ab4a 2 spec: 3 containers: 4 - image: nginx 5 imagePullPolicy: Always 6 name: nginx 7 resources: 8 limits: 9 cpu: 300m 10 memory: 200Mi 11 requests: 12 cpu: 200m 13 memory: 100Mi 14解读:由于该Pod未配置资源Requests和Limits,所以使用了namespace limit-example中的默认CPU和内存定义的Requests和Limits值。 [root@k8smaster01 study]# vi invalid-pod.yaml
1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: invalid-pod 5 spec: 6 containers: 7 - name: kubernetes-serve-hostname 8 image: gcr.azk8s.cn/google_containers/server_hostname 9 resources: 10 limits: 11 cpu: "3" 12 memory: 100Mi 13[root@k8smaster01 study]# kubectl create -f invalid-pod.yaml --namespace=limit-example Error from server (Forbidden): error when creating "invalid-pod.yaml": pods "invalid-pod" is forbidden: maximum cpu usage per Container is 2, but limit is 3 解读:创建该Pod,会出现系统报错了,并且提供的错误原因为超过资源限制。 [root@k8smaster01 study]# vi limit-test-nginx.yaml
1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: limit-test-nginx 5 labels: 6 name: limit-test-nginx 7 spec: 8 containers: 9 - name: limit-test-nginx 10 image: nginx 11 resources: 12 limits: 13 cpu: "1" 14 memory: 512Mi 15 requests: 16 cpu: "0.8" 17 memory: 250Mi 18[root@k8smaster01 study]# kubectl create -f limit-test-nginx.yaml -n limit-example Error from server (Forbidden): error when creating "limit-test-nginx.yaml": pods "limit-test-nginx" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 2.048000 解读:由于limit-test-nginx这个Pod的全部内存Limits总和与Requests总和的比例为512∶250,大于在LimitRange中定义的Pod的最大比率2(maxLimitRequestRatio.memory=2),因此创建失败。 [root@k8smaster01 study]# vi valid-pod.yaml
1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: valid-pod 5 labels: 6 name: valid-pod 7 spec: 8 containers: 9 - name: kubernetes-serve-hostname 10 image: gcr.io/google_containers/serve_hostname 11 resources: 12 limits: 13 cpu: "1" 14 memory: 512Mi 15[root@k8smaster01 study]# kubectl create -f valid-pod.yaml -n limit-example [root@k8smaster01 study]# kubectl get pods valid-pod -n limit-example -o yaml | grep resources -C 6 #查看该Pod的资源信息
1 uid: 59e3d05a-8c09-479e-a3ad-1a4dbfd8e946 2 spec: 3 containers: 4 - image: gcr.io/google_containers/serve_hostname 5 imagePullPolicy: Always 6 name: kubernetes-serve-hostname 7 resources: 8 limits: 9 cpu: "1" 10 memory: 512Mi 11 requests: 12 cpu: "1" 13 memory: 512Mi 14解读:该Pod配置了明确的Limits和Requests,因此该Pod不会使用在namespace limit-example中定义的default和default Request。 注意:CPU Limits强制配置这个选项在Kubernetes集群中默认是开启的;除非集群管理员在部署kubelet时,通过设置参数--cpucfs-quota=false来关闭该限制:如果集群管理员希望对整个集群中容器或者Pod配置的Requests和Limits做限制,那么可以通过配置Kubernetes命名空间中的LimitRange来达到该目的。在Kubernetes集群中,如果Pod没有显式定义Limits和Requests,那么Kubernetes系统会将该Pod所在的命名空间中定义的LimitRange的default和default Requests配置到该Pod上。
四 资源服务质量管理(Resource QoS)
4.1 服务资源质量
Kubernetes会根据Pod的Requests和Limits配置来实现针对Pod的不同级别的资源服务质量控制(QoS)。在Kubernetes的资源QoS体系中,需要保证高可靠性的Pod可以申请可靠资源,而一些不需要高可靠性的Pod可以申请可靠性较低或者不可靠的资源。 容器的资源配置分为Requests和Limits,其中Requests是Kubernetes调度时能为容器提供的完全可保障的资源量(最低保障),而Limits是系统允许容器运行时可能使用的资源量的上限(最高上限)。Pod级别的资源配置是通过计算Pod内所有容器的资源配置的总和得出来的。 Kubernetes中Pod的Requests和Limits资源配置有如下特点:- 如果Pod配置的Requests值等于Limits值,那么该Pod可以获得的资源是完全可靠的。
- 如果Pod的Requests值小于Limits值,那么该Pod获得的资源可分成两部分:
- 完全可靠的资源,资源量的大小等于Requests值;
- 不可靠的资源,资源量最大等于Limits与Requests的差额,这份不可靠的资源能够申请到多少,取决于当时主机上容器可用资源的余量。
4.2 Requests和Limits限制机制
容器的资源配置满足以下两个条件:- Requests <= 节点可用资源
- Requests <= Limits
- 可压缩资源
- 不可压缩资源
4.3 对调度策略的影响
Kubernetes的kubelet通过计算Pod中所有容器的Requests的总和来决定对Pod的调度。 不管是CPU还是内存,Kubernetes调度器和kubelet都会确保节点上所有Pod的Requests的总和不会超过在该节点上可分配给容器使用的资源容量上限。4.4 服务质量等级(QoSClasses)
在一个超用(Over Committed,容器Limits总和大于系统容量上限)系统中,由于容器负载的波动可能导致操作系统的资源不足,最终可能导致部分容器被杀掉。在这种情况下,理想是优先杀掉那些不太重要的容器。Kubernetes将容器划分成3个QoS等级来衡量重要程度: Guaranteed(完全可靠的)、Burstable(弹性波动、较可靠的)和BestEffort(尽力而为、不太可靠的),这三种优先级依次递减。 QoS等级和优先级的关系从理论上来说,QoS级别应该作为一个单独的参数来提供API,并由用户对Pod进行配置,这种配置应该与Requests和Limits无关。但在当前版本的Kubernetes的设计中,为了简化模式及避免引入太多的复杂性,QoS级别直接由Requests和Limits来定义。在Kubernetes中容器的QoS级别等于容器所在Pod的QoS级别,而Kubernetes的资源配置定义了Pod的如上三种QoS级别。- Guaranteed
1 containers: 2 name: foo 3 resources: 4 limits: 5 cpu: 10m 6 memory: 1Gi 7 name: bar 8 resources: 9 limits: 10 cpu: 100m 11 memory: 100Mi 12解读:如上未定义Requests值,所以其默认等于Limits值。 示例2:
1 containers: 2 name: foo 3 resources: 4 requests: 5 cpu: 10m 6 memory: 1Gi 7 limits: 8 cpu: 10m 9 memory: 1Gi 10 name: bar 11 resources: 12 requests: 13 cpu: 10m 14 memory: 1Gi 15 limits: 16 cpu: 100m 17 memory: 100Mi 18解读:该定义的Requests和Limits的值完全相同。
- BestEffort
1 containers: 2 name: foo 3 resources: 4 name: bar 5 resources: 6解读:该容器都未定义资源配置。
- Burstable
- 第1种情况:Pod中的一部分容器在一种或多种资源类型的资源配置中定义了Requests值和Limits值(都不为0),且Requests值小于Limits值;
- 第2种情况:Pod中的一部分容器未定义资源配置(Requests和Limits都未定义)。
1 containers: 2 name: foo 3 resources: 4 requests: 5 cpu: 5m 6 memory: 1Gi 7 limits: 8 cpu: 10m 9 memory: 1Gi 10 name: bar 11 resources: 12 requests: 13 cpu: 5m 14 memory: 1Gi 15 limits: 16 cpu: 100m 17 memory: 100Mi 18示例5:容器bar未定义资源配置而容器foo定义了资源配置。
1 containers: 2 name: foo 3 resources: 4 requests: 5 cpu: 10m 6 memory: 1Gi 7 limits: 8 cpu: 10m 9 memory: 1Gi 10 name: bar 11示例6:容器foo未定义CPU,而容器bar未定义内存。
1 containers: 2 name: foo 3 resources: 4 limits: 5 memory: 1Gi 6 name: bar 7 resources: 8 limits: 9 cpu: 100m 10示例7:容器bar未定义资源配置,而容器foo未定义Limits值。 containers: name: foo resources: requests: cpu: 5m memory: 1Gi name: bar
4.5 Kubernetes QoS的工作特点
Pod的CPU Requests无法得到满足(比如节点的系统级任务占用过多的CPU导致无法分配足够的CPU给容器使用)时,容器得到的CPU会被压缩限流。由于内存是不可压缩的资源,所以针对内存资源紧缺的情况,会按照以下逻辑进行处理。- BestEffort Pod的优先级最低,在这类Pod中运行的进程会在系统内存紧缺时被第一优先杀掉。当然,从另外一个角度来看,BestEffort Pod由于没有设置资源Limits,所以在资源充足时,它们可以充分使用所有的闲置资源。
- Burstable Pod的优先级居中,这类Pod初始时会分配较少的可靠资源,但可以按需申请更多的资源。当然,如果整个系统内存紧缺,又没有BestEffort容器可以被杀掉以释放资源,那么这类Pod中的进程可能会被杀掉。
- Guaranteed Pod的优先级最高,而且一般情况下这类Pod只要不超过其资源Limits的限制就不会被杀掉。当然,如果整个系统内存紧缺,又没有其他更低优先级的容器可以被杀掉以释放资源,那么这类Pod中的进程也可能会被杀掉。
4.6 OOM计分系统
OOM(Out Of Memory)计分规则包括如下内容: OOM计分的计算方法为:计算进程使用内存在系统中占的百分比,取其中不含百分号的数值,再乘以10的结果,这个结果是进程OOM的基础分;将进程OOM基础分的分值再加上这个进程的OOM分数调整值OOM_SCORE_ADJ的值,作为进程OOM的最终分值(除root启动的进程外)。在系统发生OOM时,OOM Killer会优先杀掉OOM计分更高的进程。 进程的OOM计分的基本分数值范围是0~1000,如果A进程的调整值OOM_SCORE_ADJ减去B进程的调整值的结果大于1000,那么A进程的OOM计分最终值必然大于B进程,会优先杀掉A进程。 不论调整OOM_SCORE_ADJ值为多少,任何进程的最终分值范围也是0~1000。在Kubernetes,不同QoS的OOM计分调整值规则如下所示。- BestEffortPod设置OOM_SCORE_ADJ调整值为1000,因此BestEffortPod中容器里所有进程的OOM最终分肯定是1000。
- GuaranteedPod设置OOM_SCORE_ADJ调整值为-998,因此GuaranteedPod中容器里所有进程的OOM最终分一般是0或者1(因为基础分不可能是1000)。
- BurstablePod规则分情况说明:如果BurstablePod的内存Requests超过了系统可用内存的99.8%,那么这个Pod的OOM_SCORE_ADJ调整值固定为2;否则,设置OOM_SCORE_ADJ调整值为1000-10×(%of memory requested);如果内存Requests为0,那么OOM_SCORE_ADJ调整值固定为999。这样的规则能确保OOM_SCORE_ADJ调整值的范围为2~999,而BurstablePod中所有进程的OOM最终分数范围为2~1000。BurstablePod进程的OOM最终分数始终大于GuaranteedPod的进程得分,因此它们会被优先杀掉。如果一个BurstablePod使用的内存比它的内存Requests少,那么可以肯定的是它的所有进程的OOM最终分数会小于1000,此时能确保它的优先级高于BestEffortPod。如果在一个BurstablePod的某个容器中某个进程使用的内存比容器的Requests值高,那么这个进程的OOM最终分数会是1000,否则它的OOM最终分会小于1000。假设在下面的容器中有一个占用内存非常大的进程,那么当一个使用内存超过其Requests的BurstablePod与另外一个使用内存少于其Requests的BurstablePod发生内存竞争冲突时,前者的进程会被系统杀掉。如果在一个BurstablePod内部有多个进程的多个容器发生内存竞争冲突,那么此时OOM评分只能作为参考,不能保证完全按照资源配置的定义来执行OOMKill。
- kubelet进程和Docker进程的调整值OOM_SCORE_ADJ为-998。
- 如果配置进程调整值OOM_SCORE_ADJ为-999,那么这类进程不会被OOMKiller杀掉。
五 资源配额管理( Resource Quotas)
5.1 配额管理
ResourceQuotas通常用于在共享集群资源场景中平衡资源,通过ResourceQuota对象,可以定义资源配额,这个资源配额可以为每个命名空间都提供一个总体的资源使用的限制:它可以限制命名空间中某种类型的对象的总数目上限,也可以设置命名空间中Pod可以使用的计算资源的总上限。 ResourceQuotas典型的场景如下:- 不同的团队工作在不同的命名空间下,目前这是非约束性的,在未来的版本中可能会通过ACL(Access Control List,访问控制列表)来实现强制性约束。
- 集群管理员为集群中的每个命名空间都创建一个或者多个资源配额项。
- 当用户在命名空间中使用资源(创建Pod或者Service等)时,Kubernetes的配额系统会统计、监控和检查资源用量,以确保使用的资源用量没有超过资源配额的配置。
- 如果在创建或者更新应用时资源使用超过了某项资源配额的限制,那么创建或者更新的请求会报错(HTTP 403 Forbidden),并给出详细的出错原因说明。
- 如果命名空间中的计算资源(CPU和内存)的资源配额启用,那么用户必须为相应的资源类型设置Requests或Limits;否则配额系统可能会直接拒绝Pod的创建。这里可以使用LimitRange机制来为没有配置资源的Pod提供默认资源配置。
- 集群共有32GB内存和16CPU,两个小组。A小组使用20GB内存和10CPU,B小组使用10GB内存和2CPU,剩下的2GB内存和2CPU作为预留。在名为testing的命名空间中,限制使用1CPU和1GB内存;在名为production的命名空间中,资源使用不受限制。
在使用资源配额时,需要注意以下两点。
- 如果集群中总的可用资源小于各命名空间中资源配额的总和,那么可能会导致资源竞争。资源竞争时,Kubernetes系统会遵循先到先得的原则。
- 不管是资源竞争还是配额的修改,都不会影响已经创建的资源使用对象。
5.2 开启资源配额特性
资源配额可以通过在kube-apiserver的--admission-control参数值中添加ResourceQuota参数进行开启。如果在某个命名空间的定义中存在ResourceQuota,那么对于该命名空间而言,资源配额就是开启的。一个命名空间可以有多个ResourceQuota配置项。 提示:在v 1.10后续的版本中,--admission-control 已经废弃,建议使用 --enable-admission-plugins。 [root@k8smaster01 study]# vi /etc/kubernetes/manifests/kube-apiserver.yaml …… - --enable-admission-plugins=NodeRestriction,ResourceQuota,LimitRanger …… [root@k8smaster01 study]# systemctl restart kubelet.service5.3 资源配额类型
- 计算资源配额(ComputeResourceQuota)
- 存储资源配额(Volume Count Quota)
- 对象数量配额( Object Count Quota)
5.4 配额的作用域(QuotaScopes)
每项资源配额都可以单独配置一组作用域,配置了作用域的资源配额只会对符合其作用域的资源使用情况进行计量和限制,作用域范围内超过了资源配额的请求都会报验证错误。ResourceQuota的4种作用域如下所示:- cpu
- limits.cpu
- limits.memory
- memory
- pods
- requests.cpu
- requests.memory
5.5 资源配额(ResourceQuota)设置Requests和Limits
资源配额也可以设置Requests和Limits。如果在资源配额中指定了requests.cpu或requests.memory,那么它会强制要求每个容器都配置自己的CPU Requests或CPU Limits(可使用Limit Range提供的默认值)。 同理,如果在资源配额中指定了limits.cpu或limits.memory,那么它也会强制要求每个容器都配置自己的内存Requests或内存Limits(可使用LimitRange提供的默认值)。5.6 资源配额的定义
与LimitRange相似,ResourceQuota也被设置在Namespace中。 示例1: [root@k8smaster01 study]# kubectl create namespace myspace #创建名为myspace的Namespace [root@k8smaster01 study]# vi compute-resources.yaml #创建ResourceQuota配置文件1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: compute-resources 5 spec: 6 hard: 7 pods: "4" 8 requests.cpu: "1" 9 requests.memory: 1Gi 10 limits.cpu: "2" 11 limits.memory: 2Gi 12[root@k8smaster01 study]# kubectl create -f compute-resources.yaml --namespace=myspace #创建该ResourceQuota 创建另一个名为object-counts.yaml的文件,用于设置对象数量的配额: [root@k8smaster01 study]# vi object-counts.yaml
1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: object-counts 5 spec: 6 hard: 7 configmaps: "10" 8 persistentvolumeclaims: "4" 9 replicationcontrollers: "20" 10 secrets: "10" 11 services: "10" 12 services.loadbalancers: "2" 13[root@k8smaster01 study]# kubectl create -f object-counts.yaml --namespace=myspace [root@k8smaster01 study]# kubectl describe quota compute-resources --namespace=myspace [root@k8smaster01 study]# kubectl describe quota object-counts --namespace=myspace
5.7 资源配额与集群资源总量的关系
资源配额与集群资源总量是完全独立的。资源配额是通过绝对的单位来配置的,这也就意味着如果在集群中新添加了节点,那么资源配额不会自动更新,而该资源配额所对应的命名空间中的对象也不能自动增加资源上限。在某些情况下,可能希望资源配额支持更复杂的策略,如下所述。- 对于不同的租户,按照比例划分整个集群的资源。
- 允许每个租户都能按照需要来提高资源用量,但是有一个较宽容的限制,以防止意外的资源耗尽情况发生。
- 探测某个命名空间的需求,添加物理节点并扩大资源配额值。
原文链接:https://www.cnblogs.com/itzgr/p/12651892.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Nginx 的配置指令
下一篇:常用LInux命令
- keepalived 实现LVS负载均衡高可用集群(一) 2020-06-04
- corosync v1 + pacemaker高可用集群部署(二)资源配置(VIP+ 2020-05-28
- #Linux学习# 用户和用户组管理 2020-05-26
- K8S集群平滑回退或升级 2020-05-21
- 操作系统第五次实验报告——内存管理 2020-05-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash