kubernetes调度之资源配额

  系列目录
  
  当多个用户或者开发团队共享一个有固定节点的的kubernetes集群时,一个团队或者一个用户使用的资源超过他应当使用的资源是需要关注的问题,资源配额是管理员用来解决这个问题的一个工具.
  
  资源配额,通过ResourceQuota定义,提供了对某一名称空间使用资源的总体约束.它即可以限制这个名称空间下有多少个对象可以被创建,也可以限制对计算机资源使用量的限制(前面说到过,计算机资源包括cpu,内存,磁盘空间等资源)
  
  资源配额通过以下类似方式工作:
  
  不同的团队在不同的名称空间下工作.当前kubernetes并没有强制这样做,完全是自愿的,但是kubernetes团队计划通过acl授权来达到强制这样做.
  
  管理员对每一个名称空间创建一个ResourceQuota(资源配额)
  
  用户在一个名称空间下创建资源(例如pod,service等),配额系统跟踪资源使用量来保证资源的使用不超过ResourceQuota定义的量.
  
  如果对一个资源的创建或者更新违反了资源配额约束,则请求会返回失败,失败的http状态码是403 FORBIDDEN并且有一条消息来解释哪个约束被违反.
  
  如果一个名称空间下的计算机资源配额,比如CPU和内存被启用,则用户必须指定相应的资源申请或者限制的值,否则配额系统可能会阻止pod的创建.
  
  资源配额在某一名称空间下创建策略示例:
  
  在一个有32G内存,16核cpu的集群,让团队A使用20G内存和10核cpu,让团队B使用10G内存和4核cpu,剩余的2G内存和2核cup预留以备进一步分配
  
  限制测试名称空间使用1核1G,让生产名称空间使用剩下的全部资源
  
  当集群的容量小于所有名称空间下配额总和时,将会出现资源竞争,这种情况下kubernetes将会基于先到先分配的原则进行处理
  
  不论是资源竞争或者是资源配额的修改都不会影响已经创建的资源
  
  启用资源配额
  
  很多kubernetes的发行版中资源配额支持默认是开启的,当ResourceQuota作为apiserver的--enable-admission-plugins=的其中一个值时,资源配额被开启.
  
  当某一名称空间包含ResourceQuota对象时资源配额在这个名称空间下生效.
  
  计算机资源配额
  
  你可以限制一个名称空间下可以被申请的计算机资源的总和
  
  kubernetes支持以下资源类型:
  
  Resource Name    Description
  
  cpu    Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value.
  
  limits.cpu    Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value.
  
  limits.memory    Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value.
  
  memory    Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value.
  
  requests.cpu    Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value.
  
  requests.memory    Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value.
  
  扩展资源的资源配额
  
  除了上面提到的,在kubernetes 1.10里,添加了对扩展资源的配额支持
  
  存储资源配额
  
  你可以限制某一名称空间下的存储空间总量的申请
  
  此外,你也可以你也可以根据关联的storage-class来限制存储空间资源的使用
  
  Resource Name    Description
  
  requests.storage    Across all persistent volume claims, the sum of storage requests cannot exceed this value.
  
  persistentvolumeclaims    The total number of persistent volume claims that can exist in the namespace.
  
  .storageclass.storage.k8s.io/requests.storage    Across all persistent volume claims associated with the storage-class-name, the sum of storage requests cannot exceed this value.
  
  .storageclass.storage.k8s.io/persistentvolumeclaims    Across all persistent volume claims associated with the storage-class-name, the total number of persistent volume claims that can exist in the namespace.
  
  例如,一个operator想要想要使黄金和青铜单独申请存储空间,那么这个operator可以像如下一样申请配额:
  
  gold.storageclass.storage.k8s.io/requests.storage: 500Gi
  
  bronze.storageclass.storage.k8s.io/requests.storage: 100Gi
  
  在1.8版本里,对local ephemeral storage配额的的支持被添加到alpha特征里.
  
  Resource Name    Description
  
  requests.ephemeral-storage    Across all pods in the namespace, the sum of local ephemeral storage requests cannot exceed this value.
  
  limits.ephemeral-storage    Across all pods in the namespace, the sum of local ephemeral storage limits cannot exceed this value.
  
  对象数量配额
  
  1.9版本通过以下语法加入了对所有标准名称空间资源类型的配额支持
  
  count/.
  
  以下是用户可能想要设置对象数量配额的例子:
  
  count/persistentvolumeclaims
  
  count/services
  
  count/secrets
  
  count/configmaps
  
  count/replicationcontrollers
  
  count/deployments.apps
  
  count/replicasets.apps
  
  count/statefulsets.apps
  
  count/jobs.batch
  
  count/cronjobs.batch
  
  count/deployments.extensions
  
  当使用count/*类型资源配额,服务器上存在的资源对象将都被控制.这将有助于防止服务器存储资源被耗尽.比如,如果存储在服务器上的secrets资源对象过大,你可能会想要限制它的数量.过多的secrets可能会导致服务器无法启动!你也可能会限制job的数量以防一些设计拙劣的定时任务会创建过多的job以导致服务被拒绝
  
  以下资源类型的限额是支持的
  
  Resource Name    Description
  
  configmaps    The total number of config maps that can exist in the namespace.
  
  persistentvolumeclaims    The total number of persistent volume claims that can exist in the namespace.
  
  pods    The total number of pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if .status.phase in (Failed, Succeeded) is true.
  
  replicationcontrollers    The total number of replication controllers that can exist in the namespace.
  
  resourcequotas    The total number of resource quotas that can exist in the namespace.
  
  services    The total number of services that can exist in the namespace.
  
  services.loadbalancers    The total number of services of type load balancer that can exist in the namespace.
  
  services.nodeports    The total number of services of type node port that can exist in the namespace.
  
  secrets    The total number of secrets that can exist in the namespace.
  
  例如,pod配额限制了一个名称空间下非terminal状态的pod总数量.这样可以防止一个用户创建太多小的pod以至于耗尽集群分配给pod的所有IP
  
  配额范围
  
  每一个配额都可以包含一系列相关的范围.配额只会在匹配列举出的范围的交集时才计算资源的使用.
  
  当一个范围被添加到配额里,它将限制它支持的,属于范围的资源.指定的资源不在支持的集合里时,将会导致验证错误
  
  Scope    Description
  
  Terminating    Match pods where .spec.activeDeadlineSeconds >= 0
  
  NotTerminating    Match pods where .spec.activeDeadlineSeconds is nil
  
  BestEffort    Match pods that have best effort quality of service.
  
  NotBestEffort    Match pods that do not have best effort quality of service.
  
  BestEffort范围限制配额只追踪pods资源
  
  Terminating,NotTerminating和NotBestEffort范围限制配额追踪以下资源:
  
  cpu
  
  limits.cpu
  
  limits.memory
  
  memory
  
  pods
  
  requests.cpu
  
  requests.memory
  
  每一个PriorityClass的资源配额
  
  此特征在1.12片本中为beta
  
  pod可以以指定的优先级创建.你可以通过pod的优先级来控制pod对系统资源的使用,它是通过配额的spec下的scopeSelector字段产生效果的.
  
  只有当配额spec的scopeSelector选择了一个pod,配额才会被匹配和消费
  
  你在使用PriorityClass的配额的之前,需要启用ResourceQuotaScopeSelectors
  
  以下示例创建一个配额对象,并且一定优先级的pod会匹配它.
  
  集群中的pod有以下三个优先级类之一:low,medium,high
  
  每个优先级类都创建了一个资源配额
  
  apiVersion: v1
  
  kind: List
  
  items:
  
  - apiVersion: v1
  
  kind: ResourceQuota
  
  metadata:
  
  name: pods-high
  
  spec:
  
  hard:
  
  cpu: "1000"
  
  memory: 200Gi
  
  pods: "10"
  
  scopeSelector:
  
  matchExpressions:
  
  - operator : In
  
  scopeName: PriorityClass
  
  values: ["high"]
  
  - apiVersion: v1
  
  kind: ResourceQuota
  
  metadata:
  
  name: pods-medium
  
  spec:
  
  hard:
  
  cpu: "10"
  
  memory: 20Gi
  
  pods: "10"
  
  scopeSelector:
  
  matchExpressions:
  
  - operator : In
  
  scopeName: PriorityClass
  
  values: ["medium"]
  
  - apiVersion: v1
  
  kind: ResourceQuota
  
  metadata:
  
  name: pods-low
  
  spec:
  
  hard:
  
  cpu: "5"
  
  memory: 10Gi
  
  pods: "10"
  
  scopeSelector:
  
  matchExpressions:
  
  - operator : In
  
  scopeName: PriorityClass
  
  values: ["low"]
  
  使用kubectl create来用户以上yml文件
  
  kubectl create -f .www.chaoyuL.com  /quota.yml
  
  resourcequota/pods-high created
  
  resourcequota/pods-medium created
  
  resourcequota/pods-low created
  
  使用kubectl describe quota来查看
  
  kubectl describe quota
  
  Name:       pods-high
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         0     1k
  
  memory      0     200Gi
  
  pods        0     10
  
  Name:       pods-low
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         0     5
  
  memory      0     10Gi
  
  pods        0     10
  
  Name:       pods-medium
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         0     10
  
  memory      0     20Gi
  
  pods        0     10
  
  创建一个具有high优先级的pod,把以下内容保存在high-priority-pod.yml里
  
  apiVersion: v1
  
  kind: Pod
  
  metadata:
  
  name: high-priority
  
  spec:
  
  containers:
  
  - name: high-priority
  
  image: ubuntu
  
  command: ["/bin/sh"www.chaoylgw.cn/]
  
  args: ["-c", "while true; do echo hello; sleep 10;done"]
  
  resources:
  
  requests:
  
  memory: "10Gi"
  
  cpu: "500m"
  
  limits:
  
  memory: "10Gi"
  
  cpu: "500m"
  
  priorityClassName: high
  
  使用kubectl create来应用
  
  kubectl create -f ./high-priority-pod.yml
  
  这时候再用kubectl describe quota来查看
  
  Name:       pods-high
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         500m  1k
  
  memory      10Gi  200Gi
  
  pods        1     10
  
  Name:       pods-low
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         0     5
  
  memory      0     10Gi
  
  pods        0     10
  
  Name:       pods-medium
  
  Namespace:  default
  
  Resource    Used  Hard
  
  --------    ----  ----
  
  cpu         0     10
  
  memory      0     20Gi
  
  pods        0     10
  
  scopeSelector支持operator字段的以下值:
  
  In
  
  NotIn
  
  Exist
  
  DoesNotExist
  
  配额资源的申请与限制
  
  当分配计算机资源时,每一个容器可能会指定对cpu或者内存的申请或限制.配额可以配置为它们中的一个值
  
  这里是说配额只能是申请或者限制,而不能同时出现
  
  如果配额指定了requests.cpu或requests.memory那么它需要匹配的容器必须显式指定申请这些资源.如果配额指定了limits.cpu或limits.memory,那么它需要匹配的容器必须显式指定限制这些资源
  
  查看和设置配额
  
  kubectl支持创建,更新和查看配额
  
  kubectl create namespace myspace
  
  cat < compute-resources.yaml
  
  apiVersion: v1
  
  kind: ResourceQuota
  
  metadata:
  
  name: compute-resources
  
  spec:
  
  hard:
  
  pods: "4"
  
  requests.cpu: "1"
  
  requests.memory: 1Gi
  
  limits.cpu: "2"
  
  limits.memory: 2Gi
  
  requests.nvidia.com/gpu: 4
  
  EOF
  
  kubectl create -f www.5iyouxue.com./compute-resources.yaml --namespace=myspace
  
  cat < object-counts.yaml
  
  apiVersion: v1
  
  kind: ResourceQuota
  
  metadata:
  
  name: object-counts
  
  spec:
  
  hard:
  
  configmaps: "10"
  
  persistentvolumeclaims: "4"
  
  replicationcontrollers: "20"
  
  secrets: "10"
  
  services: "10"
  
  services.loadbalancers: "2"
  
  EOF
  
  kubectl create -f ./object-counts.yaml --namespace=myspace
  
  kubectl get quota --namespace=myspace
  
  NAME                    AGE
  
  compute-resources       30s
  
  object-counts           32s
  
  kubectl describe quota compute-resources --namespace=myspace
  
  Name:                    compute-resources
  
  Namespace:               myspace
  
  Resource                 Used  Hard
  
  --------                 ----  ----
  
  limits.cpu               0     2
  
  limits.memory            0     2Gi
  
  pods                     0     4
  
  requests.cpu             0     1
  
  requests.memory          0     1Gi
  
  requests.nvidia.com/gpu  0     4
  
  kubectl describe quota object-counts --namespace=myspace
  
  Name:                   object-counts
  
  Namespace:              myspace
  
  Resource                Used    Hard
  
  --------                ----    ----
  
  configmaps              0       10
  
  persistentvolumeclaims  0       4
  
  replicationcontrollers  0       20
  
  secrets                 1       10
  
  services                0       10
  
  services.loadbalancers  0       2
  
  kubectl通过count/.语法形式支持标准名称空间对象数量配额
  
  kubectl create namespace myspace
  
  kubectl create quota test --hard=count/deployments.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=myspace
  
  kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
  
  kubectl describe quota --namespace=myspace
  
  Name:                         test
  
  Namespace:                    myspace
  
  Resource                      Used  Hard
  
  --------                      ----  ----
  
  count/deployments.extensions  1     2
  
  count/pods                    2     3
  
  count/replicasets.extensions  1     4
  
  count/secrets                 1     4
  
  配额和集群容量
  
  ResourceQuotas独立于集群的容量,它们通过绝对的单位表示.因此,如果你向集群添加了节点,这并不会给集群中的每个名称空间赋予消费更多资源的能力.
  
  有时候需要更为复杂的策略,比如:
  
  把集群中所有的资源按照比例分配给不同团队
  
  允许每个租户根据需求增加资源使用,但是有一个总体的限制以防资源被耗尽
  
  检测名称空间的需求,添加节点,增加配额
  
  这些策略可以通过实现ResourceQuotas来写一个controller用于监视配额的使用,并且通过其它信号来调整每个名称空间的配额
  
  默认限制优先类消费
  
  有时候我们可能希望一定优先级别的pod,例如cluster-services应当被允许在一个名称空间里,当且仅当匹配的配额存在.
  
  通过这种机制,operators可以限制一些高优先级的类只能用于有限数量的名称空间里,并且不是所有的名称空间都可以默认消费它们.
  
  为了使以上生效,kube-apiserver标签--admission-control-config-file应当传入以下配置文件的路径
  
  apiVersion: apiserver.k8s.io/v1alpha1
  
  kind: AdmissionConfiguration
  
  plugins:
  
  - name: www.changjianyL.cn"ResourceQuota"
  
  configuration:
  
  apiVersion: resourcequota.admission.k8s.io/v1beta1
  
  kind: Configuration
  
  limitedResources:
  
  - resource: pods
  
  matchScopes:
  
  - scopeName: PriorityClass
  
  operator: In
  
  values: [www.huangzuyuL.cn"cluster-services"]
  
  现在,cluster-services类型的pod仅被允许运行在有匹配scopeSelector的配额资源对象的名称空间里,例如
  
  `yml scopeSelector: www.oushengyuL.cn matchExpressions: - scopeName: PriorityClass operator: In values: ["cluster-services"]
  
  分类: 云原生devops
  
  标签: docker, k8s, kubernetes, 云原生, devops, .net

你可能感兴趣的:(kubernetes调度之资源配额)