k8s series 17: 资源配额

841 阅读4分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

如果在一个群集中跑多个团队或多个项目时,为了达到公平原则或事先说好的资源分配,k8s中有一种策略叫资源配额,以此来控制资源分配

在k8s中有两种策略来限制不同的场景

  • 一种是ResourceQuotas 针对命名空间的资源配额,多项目组共享一个集群资源时,根据不同namespace分配不同数量的资源
  • 一种是LimitRange 针对集群控制器对象的资源配额,可以单独限制每个应用的资源数量

ResourceQuotas

ResourceQuotas 功能在k8s中是默认启用的,对于低版本的k8s,可以看查看--enable-admission-plugins=ResourceQuota 是否有该参数

测试例子

创建一个新namespace

kubectl create namespace compute

创建资源配额 kubectl apply -f ResourceQuota.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name:  compute
  namespace: compute
spec:
  hard:
    cpu: 500m  
    memory: 200Mi
    pods: "10"
    services: "2"
    requests.cpu: 5
    limits.memory: 2Gi
    persistentvolumeclaims: "2"
    services.nodeports: "2"
    configmaps: "2"
    secrets: "2"

以上配置是在compute命名空间中限制:

  • 最多10个pod,2个svc,2个pvc,2个configmap,2个secret,最高2G内存,最高5个cpu
  • request 用于pod最小资源请求
  • limit 限制pod的资源最大使用

针对compute命名空间资源的分配,资源使用完,后面的应用申请不到资源,会直接报错(不影响已经运行的应用), cpu是requests.cpu的简写,其他简写一样。

获取资源配额配置

#kubectl -n compute  get resourcequotas
kubectl describe resourcequotas/compute -n compute

可以看到,已经生效,这是compute命名空间的资源分配的详情

image.png

使用configmap 资源来测试以上规则是否有效,加了两个,然后准备加第三个的时候 就报超过限额了 image.png

LimitRange

LimitRange功能在k8s中是默认启用的,且limitRange限制所有控制器对象的,在实际场景中经常使用,其中的作用如下:

  1. 限制单个应用内存使用率,避免内存竟争,导致无辜应用OOM
  2. 限制单个应用cpu使用率,避免cpu使用过高,导致其他应用无cpu资源可用
  3. 限制单个应用存储使用率,避免共享存储占满,导致其他应用无法写入

测试例子

还是以Deployment部署应用以例,往期传送门:juejin.cn/post/697645…

如下示例可以看到限制策略加在spec.spec.resources字段中

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-hive
  namespace: devops
  labels:
    app: springboot
    version: "1.0"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: springboot
  template:
    metadata:
      labels:
        app: springboot
        version: "1.0"
    spec:
      terminationGracePeriodSeconds: 30
      containers:
      - name: springboot-hive
        image: harbor-test.xxxxx.cn/dev/springboot-hive:v1
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 100m
            memory: 1Gi
          limits:
            cpu: 2
            memory: 2Gi
        ports:
        - containerPort: 8080
          name: web
  • limit 限制pod的资源最大使用
  • request 用于pod最小资源请求
  • 如果只配limit 没配request, 默认request=limit
  • 当容器内存超过2G,将会导致oom
  • cpu使用不会超进limit值,会被控制在这个上限

资源单位

CPU的单位:

cpu资源以milicpu为单位,允许小数值,可以用后缀m表示mili. 单位后缀m表示千分之一核,1Core = 1000m, 或直接写1 或 1000m

RAN的单位:

ram主要以Mi为单位, Mi表示 1Mi=1024*1024,基本应用内存使用都是M起步,所以换算1Gi=1024Mi既可

对象型类

LimitRange还有一种使用方式,以对象资源方式存在,限制一类式多类控制器的资源分配,但在实际场景中较少使用,以此了解一下既可

配置文件如下:

apiVersion: v1
kind: LimitRange
metadata:
  name: test-limitrange
spec:
  limits:
  - type: Pod       #资源类型
    max:
      cpu: 1            #限定最大CPU
      memory: 1Gi       #限定最大内存
    min:
      cpu: 100m         #限定最小CPU
      memory: 100Mi     #限定最小内存
    default:
      cpu: 1         #默认CPU限定
      memory: 1Gi     #默认内存限定
    defaultRequest:
      cpu: 200m         #默认CPU请求
      memory: 200Mi     #默认内存请求
    maxLimitRequestRatio:
      cpu: 2              #限定CPU limit/request比值最大为2  
      memory: 2Gi         #限定内存limit/request比值最大为2
 
  - type: PersistentVolumeClaim
    max:
      storage: 2Gi        #限定PVC最大的requests.storage
    min:
      storage: 1Gi        #限定PVC最小的requests.storage

请注意,以上配置在哪个namespace下执行,将对该namespace下资源生效,以上是对该namespace中的Pod,PVC两种资源 进行限制

查看命令

kubectl describe limits lr-test