设置资源请求数量

创建Pod的时候,可以为每个容器指定资源消耗的限制。Pod的资源请求限制则是Pod中所有容器请求资源的总和。

apiVersion: v1
kind: Pod
metadata:
name: requests-pod
spec:
containers:
  - image: busybox
command: ["dd", "if=/dev/zero", "of=/dev/null"]
name: main
resources:
  requests:
    cpu: 200m
    memory: 10Mi

如果不指定CPU请求资源,表示不关心容器会分到多少CPU资源,有可能会一直分不到而处于等待状态。指定资源请求表示Pod对资源的最小需求,因此在调度的时候会如果Node剩余的资源不能满足Pod的需求,则不会调度到对应的Node上。Scheduler调度的时候并不关注在调度时具体的资源使用情况,而是根据现存Pod的资源请求情况来进行调度。这就会有问题,特别是当允许Pod使用超过请求的资源时。下面的图一看就能理解。

调度判断首先将不符合请求的Node排除在外,然后将符合要求的Node进行排序。节点排序根据资源请求数量的不同分为两个策略,LeastRequestPolicyMostRequestPolicy。从字面上我们可以看到,一个是优先分派到资源请求少的节点,一个是优先分派到资源请求多的节点。一般在生产环境,建议使用LeastRequestPolicy,便于将负载平均的分配到各个机器上。在公有云的环境中建议使用MostRequestPolicy,提高资源的利用率,减少成本。

在没有设置资源使用限制的情况下,Pod可能使用超过请求的资源数量。对于CPU资源来说,如果同时有两个Pod请求剩余的资源,在分配剩余资源时,调度器会根据请求数量的比例在不同的Pod间分配资源。例如Pod A请求100m的CPU,Pod B请求20m的CPU,在两个Pod中CPU使用超过请求时,会根据5:1的比例分配。

使用kubectl describe nodes命令可以查看Node资源使用的情况。

如果Kubernetes找不到满足资源请求的Node,则Pod创建会停留在Pending状态。

设置资源使用上限

Pod创建的时候,可以设置每个容器使用资源的上限,可以限制的资源包括CPU、内存等。如果不设置上限,则理论上可以使用Node的全部资源。如果要防止Node上的各个容器互相影响,最好为Pod指定上限。

CPU是一种可以压榨的资源,可以用满并且Pod之间不会互相影响。内存则不一样,Pod之间分配的内存不能互相使用。requests的资源数量必须与Node容量一样或者更小,limits资源数量的总和可以超过Node的容量。当节点的资源被全部使用完后,一些容器可能会被杀掉。特别是使用内存超限后,会被Kubernetes进行OOMKilled。如果这个Pod的重启策略是Always,很可能你都没注意到Pod被重启了,但是随着发生次数的增多,每次重启delay的时间就会增加。

apiVersion: v1
kind: Pod
metadata:
name: limit-pod
spec:
containers:
  - image: busybox
command: ["dd", "if=/dev/zero", "of=/dev/null"]
name: main
resources:
  requests:
    cpu: 200m
    memory: 10Mi
limits:
cpu: 1
memory: 20Mi

容器中运行top命令你会发现,容器中能看到的CPU、内存总量是Node的总量。这样就会造成一些应用能够探测到的容量和Limits的限制不一样,从而造成使用超出请求的情况。

对于CPU、内存来说,可以利用Metadata获取的三种方式中提到的办法通过API来获取限制的大小,也可以在 /sys/fs/cgroup/cpu/cpu.cfs_quota_us/sys/fs/cgroup/cpu/cpu.cfs_period_us来查看。

QoS:Pod Kill的策略

在Pod使用的资源超过Node容量时,Kubernetes为了保障Node的运行,会选择其中的一些Pod并杀掉,那么如何确定杀掉哪个Pod呢,这里就需要引入一个QoS的概念。

QoS是 Quality of Service,有三种Quality of Service 策略,Kubernetes依次选择三种策略的Pod进行Kill。如果两个的QoS一样,则选择资源利用率高的Kill。

  • BestEffort 应用到没有资源限制的Pod上,可以使用尽可能多的资源,也可能第一个被杀死
  • Burstable limits超过requests的Pod类型
  • Guaranteed 适用于请求和上限一致的Pod(limits默认与requests相同),这种Pod不能使用超额的资源,但是会保证存活

对于单容器的Pod,遵循以下原则

对于多个容器的Pod,如果两个容器的策略不一致,就使用Burstable策略,一致则使用容器的策略。

设置Pod/Container的默认请求和限制 LimitRange

通过创建LimitRange对象,在一个命名空间内,可以为所有创建的Pod设置一个磨人的requests和limits的限制。

apiVersion: v1
kind: LimitRange
metadata:
name: limitrange-demo
spec:
limits:
- type: Pod
min:
cpu: 50m
meomery: 5Mi
max:
cpu: 1
meomery: 1Gi
- type: Container
defaultRequest:
cpu: 100m
memory: 10Mi
default:
cpu: 200m
memory: 100Mi
min:
cpu: 50m
memory: 5Mi
max:
cpu: 1
memory: 1Gi
maxLimitRequestRatio:
cpu: 4
memory: 10
- type: PersistentVolumeClaim
min:
storage: 1Gi
max:
storage: 10Gi

创建一个不符合LimitRange要求的Pod,则会出现以下报错。

设置集群的资源Quota

除了设置每个Pod的默认上限外,还可以通过ResourceQuota设置集群的可用资源上限。ResourceQuota可以设置一个集群可用的最大计算资源的数量,也可以设置用户可以创建的各种对象的数量。

apiVersion: v1
kind: ResourceQuota
metadata:
name: cpu-and-mem
spec:
hard:
requests.cpu: 400m
requests.memory: 200Mi
limits.cpu: 600m
limits.memory: 500Mi

查看当前的资源限制

还可以限制存储及各种对象的数量,具体参考下面的yaml。

apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-object
spec:
hard:
pods: 10
replicationcontrollers: 5
secrets: 10
configmaps: 10
persistentvolumeclaims: 4
services: 5
services.loadbalancers: 1
services.nodeports: 2
ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2

设置的Quota默认在命名空间内生效,也可以根据QoS来设定不同的生效范围。

apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-qos
spec:
scopes:
- BestEffort
- NotTerminating
hard:
pods: 4

一共有四种策略:BestEffort、NotBestEffort、Terminating、NotTerminating。前两个根据QoS来选择Pod,后两个根据Pod是否设置了activeDeadlineSeconds属性来选择。看下图就能够明白了。

监控

Kubernetes本身包含了cAdvisor来监控容器和节点的运行情况,如果想要从整体上看资源的使用情况需要安装Heapster组件。但是这两个

kubectl top node
kubectl top pod
kubectl top pod --container

使用这两个命令可以查看短时间内的Pod、Node资源使用的情况,也可以查看每个容器资源使用的情况。如果想要将性能数据保存下来,需要安装heapster\influxdb\grafana。具体不在这篇文章中讲解了。

参考资料:

  1. cAdvisor
  2. InfluxDB
  3. Grafana
  4. influxdb yaml

Kubernetes中资源配额管理的更多相关文章

  1. Kubernetes中资源清单与Pod的生命周期(二)

    一.资源清单 1,定义: 在k8s中一般使用yaml格式的文件来创建符合我们预期的资源,这样的yaml被称为资源清单. 使用资源清单创建Pod: kubectl apply -f nginx.yaml ...

  2. k8s中 资源配额 ResourceQuota

    文章转载自:https://www.kuboard.cn/learning/k8s-advanced/policy/lr.html 当多个用户(团队)共享一个节点数量有限的集群时,如何在多个用户(团队 ...

  3. kafka中的配额管理(限速)机制

    kafka支持配额管理,从而可以对Producer和Consumer的produce&fetch操作进行流量限制,防止个别业务压爆服务器.本文主要介绍如何使用kafka的配额管理功能. 1 K ...

  4. kubernetes调度之资源配额

    系列目录 当多个用户或者开发团队共享一个有固定节点的的kubernetes集群时,一个团队或者一个用户使用的资源超过他应当使用的资源是需要关注的问题,资源配额是管理员用来解决这个问题的一个工具. 资源 ...

  5. Kubernetes中的Configmap和Secret

    本文的试验环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群 应用场景:镜像往往是一个应用的基础,还有很多需要 ...

  6. 使用 Admission Webhook 机制实现多集群资源配额控制

    1 要解决的问题 集群分配给多个用户使用时,需要使用配额以限制用户的资源使用,包括 CPU 核数.内存大小.GPU 卡数等,以防止资源被某些用户耗尽,造成不公平的资源分配. 大多数情况下,集群原生的 ...

  7. 浅析kubernetes中client-go structure01

    Prepare Introduction 从2016年8月起,Kubernetes官方提取了与Kubernetes相关的核心源代码,形成了一个独立的项目,即client-go,作为官方提供的go客户端 ...

  8. Kubernetes 多租户:资源配额

    资源配额用于管理命名空间中对象使用的资源量,我们可以按 CPU 和内存用量或对象数量来设置配额.通过资源配额,可以确保租户不会使用超过其分配份额的集群资源. 资源配额是通过 ResourceQuota ...

  9. Kubernetes中予许及限制(PodSecurityPolicy)使用宿主机资源

    1.在pod中使用宿主机命名空间.端口等资源 pod中的容器通常在分开的Linux命名空间中运行.这些命名空间将容器中的进程与其他容器中,或者宿主机默认命名空间中的进程隔离开来. 例如,每一个pod有 ...

随机推荐

  1. Python连接mysql出错,_mysql_exceptions.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: YES)")

  2. Codeforces 229E Gifts 概率dp (看题解)

    Gifts 感觉题解写的就是坨不知道什么东西.. 看得这个题解. #include<bits/stdc++.h> #define LL long long #define LD long ...

  3. Python 线程和进程

    一.什么是线程 1.线程是操作系统能够进行运算调度的最小单位.它被包含在进程中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 ...

  4. python--pip出错

    问题: 1.使用pip install时,出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None) ...

  5. BZOJ1911 [Apio2010]特别行动队 - 动态规划 - 斜率优化

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 UPD(2018-04-01):用Latex重打了公式…… 题意概括 把一个整数序列划分成任意连续的段,使得划分出 ...

  6. POJ3076 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 学完这个之后,再 ...

  7. 删除Docker中所有已停止的容器

    方法一: #显示所有的容器,过滤出Exited状态的容器,取出这些容器的ID, sudo docker ps -a|grep Exited|awk '{print $1}' #查询所有的容器,过滤出E ...

  8. Qt界面设计基础

    一.安装Qt相关基本组件: 在ubuntu上安装,可以直接使用如下的命令来安装: sudo apt-get install ubuntu-sdk 详细的安装方法可以参考这篇文章:https://blo ...

  9. 爬虫2 urllib3用法

    import urllib3 import json # 实例化一个连接池 # http = urllib3.PoolManager() # res = http.request('get','htt ...

  10. DDoS攻击与防御(2)

    2.攻击系统资源终端设备在与服务器进行通信时,经常需要创建会话连接,在此过程中通常会使用TCP和SSL等协议.会话连接一旦被占满,新进入的会话请求就必须等待前面的会话完成.消耗系统资源的DDoS攻击的 ...