袁党生博客

  • 主页
  • linux基础
  • SHELL
  • WEB
  • 负载
  • 企业级应用
  • 数据库
  • KVM
  • Docker
  • K8S
  • 监控
  • 存储
  • 博客搭建问题
  1. 首页
  2. K8S
  3. 正文

十一、kubernetes资源限制

2023年8月24日 1956点热度 0人点赞 0条评论


本章概述

  • kubernetes资源限制概括
  • kubernetes对单个容器的CPU及memory实现资源限制
  • kubernetes对单个pod的CPU及memory实现资源限制
  • kubernetes对整个namespace的CPU及memory实现资源限制

11.1 kubernetes资源限制概括

前言
1、如果运行的容器没有定义资源(memory、CPU)等限制,但是在namespace定义了LimitRange限制,那么该容器会继承LimitRange中的默认限制。
2、如果namespace没有定义LimitRange限制,那么该容器可以只要宿主机的最大可用资源,直到无资源可用而触发宿主机(OOM Killer)。

CPU资源分配:
官网链接:https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-cpu-resource/
CPU 以核心为单位进行限制,单位可以是整核、浮点核心数或毫核(m/milli)

如:2=2核心=200%   #使用2核CPU或者200%的CPU
0.5=500m=50%       #使用500毫核或者50%的CPU
1.2=1200m=120%     #使用1200毫核或者120%的CPU

内存资源分配:
官网链接:https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-memory-resource/
memory 以字节为单位,单位可以是E、P、T、G、M、K、Ei、Pi、Ti、Gi、Mi、Ki

如:1536Mi=1.5Gi
requests(请求)为kubernetes scheduler执行pod调度时node节点至少需要拥有的资源。(如果不满足则pod不会向该node调度)。
limits(限制)为pod运行成功后最多可以使用的资源上限。
limits值要大于等于request的值。(两个值建议不要相差太大或者相等)

需要注意的是:requests值和limits值两个值之间相差越小越好,建议相等

原因:假如1个pod内存的requests值为100M,limits值为512M,假设存在node,内存为300M,满足该pod的requests值,将该pod调度到node上。当运行一段时间后,pod内存的使用量逐渐增加,pod的limits值为512M,pod就会继续向node申请内存至512M,但node只有300M内存,不能提供超出300M的内存,就会因内存不足出现OOM。
如果requests值和limits值相等,调度pod时只会选取满足条件的node(即内存大于512M),此时即使pod使用最大内存,node也可以满足

11.2 kubernetes对单个容器的CPU及memory实现资源限制

11.2.1 对单个容器内存进行限制

示例:为了便于实验,使用压测镜像拉起容器

vim case1-pod-memory-limit.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: limit-test-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: limit-test-pod
#    matchExpressions:
#      - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: limit-test-pod
    spec:
      containers:
      - name: limit-test-container
        image: lorel/docker-stress-ng        #使用压测镜像
        resources:
          limits:
            memory: "512Mi"   #内存限制最多可用512M
          requests:
            memory: "100Mi"   #内存最低为100M
        #command: ["stress"]
        args: ["--vm", "2", "--vm-bytes", "256M"]  #通过传参启用两个进程,占用2核CPU,2*256M(即512)内存
      #nodeSelector:
      #  env: group1

创建pod
kubectl apply -f case1-pod-memory-limit.yml
查看pod的cpu和内存使用情况
kubectl top pod -n magedu

可以看到容器占用2核左右CPU和512M内存,由于CPU没做限制,因此CPU会占用2核,而内存则不会超过limits的值

验证:
调整内存limits值,可限制容器使用的内存大小
将yaml文件中内存的limtis值从512M调整为256M,查看容器内存使用情况
kubectl top pod -n magedu

容器内存占用从512M左右变成256M左右,说明内存限制已生效

11.2.2 对单个容器CPU进行限制

示例:

vim case2-pod-memory-and-cpu-limit.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: limit-test-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: limit-test-pod
#    matchExpressions:
#      - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: limit-test-pod
    spec:
      containers:
      - name: limit-test-container
        image: lorel/docker-stress-ng
        resources:
          limits:
            cpu: "1.3"      #限制CPU最多使用1.3核
            memory: "512Mi"
          requests:
            cpu: "500m"      #要求容器CPU最低为500毫核
            memory: "100Mi"
        #command: ["stress"]
        args: ["--vm", "2", "--vm-bytes", "256M"]   #通过传参启用两个进程,占用2核CPU,2*256M(即512)内存
      #nodeSelector:
      #  env: group1

创建pod
kubectl apply -f case2-pod-memory-and-cpu-limit.yml
查看pod CPU使用率

可以看到CPU使用率在1.3核左右,说明CPU限制已生效
使用docker stats命令可以查看宿主机上容器资源使用情况

11.3 kubernetes对单个pod的CPU及memory实现资源限制

LimitRange概述:
官网链接:https://kubernetes.io/zh/docs/concepts/policy/limit-range/
  Limit Range是对具体某个Pod或容器的资源使用进行限制,防止单个pod会占用整个命名空间的资源
  管理员在一个命名空间内创建一个 LimitRange 对象。
  用户在命名空间内创建 Pod ,Container 和 PersistentVolumeClaim 等资源。
  LimitRanger 准入控制器对所有没有设置计算资源需求的 Pod 和 Container 设置默认值与限制值, 并跟踪其使用量以保证没有超出命名空间中存在的任意 LimitRange 对象中的最小、最大资源使用量以及使用量比值。
  若创建或更新资源(Pod、 Container、PersistentVolumeClaim)违反了 LimitRange 的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码 403 FORBIDDEN 与描述哪一项约束被违反的消息。
  若命名空间中的 LimitRange 启用了对 cpu 和 memory 的限制, 用户必须指定这些值的需求使用量与限制使用量。否则,系统将会拒绝创建 Pod。
  LimitRange 的验证仅在 Pod 准入阶段进行,不对正在运行的 Pod 进行验证。

限制范围:
限制namespace中每个Pod或容器的最小与最大计算资源
限制namespace中每个Pod或容器计算资源request、limit之间的比例
限制namespace中每个存储卷声明(PersistentVolumeClaim)可使用的最小与最大存储空间
设置namespace中容器默认计算资源的request、limit,并在运行时自动注入到容器中

示例:创建limitrange

vim case3-LimitRange.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-magedu
  namespace: magedu
spec:
  limits:
  - type: Container       #限制的资源类型
    max:
      cpu: "2"            #限制单个容器的最大CPU
      memory: "2Gi"       #限制单个容器的最大内存
    min:
      cpu: "500m"         #限制单个容器的最小CPU
      memory: "512Mi"     #限制单个容器的最小内存
    default:
      cpu: "500m"         #默认单个容器的CPU限制
      memory: "512Mi"     #默认单个容器的内存限制
    defaultRequest:
      cpu: "500m"         #默认单个容器的CPU创建请求
      memory: "512Mi"     #默认单个容器的内存创建请求
    maxLimitRequestRatio:
      cpu: 2              #限制CPU limit/request比例最大为2,若CPU requests值为500m,则limits值不能超过1000m。
      memory: 1.5          #限制内存limit/request比例最大为1.5,若内存requets值为550Mi,则limits值不能超过750Mi。
  - type: Pod
    max:
      cpu: "4"            #限制单个Pod的最大CPU
      memory: "4Gi"       #限制单个Pod最大内存
  - type: PersistentVolumeClaim
    max:
      storage: 50Gi        #限制PVC最大的requests.storage
    min:
      storage: 30Gi        #限制PVC最小的requests.storage

创建LimitRange
kubectl apply -f case3-LimitRange.yaml
查看LimitRange
先获取LimitRange名称
kubectl get limitranges -n magedu

再查看LimitRange具体内容
kubectl describe limitranges limitrange-magedu -n magedu

11.3.1 CPU与内存 RequestRatio比例限制

验证:使用CPU的requets/limits的比例值超过2的yaml文件创建容器
使用yaml文件创建pod

vim case4-pod-RequestRatio-limit.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-wordpress-deployment-label
  name: magedu-wordpress-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-wordpress-selector
  template:
    metadata:
      labels:
        app: magedu-wordpress-selector
    spec:
      containers:
      - name: magedu-wordpress-nginx-container
        image: nginx:1.16.1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 2
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi

      - name: magedu-wordpress-php-container
        image: php:5.6-fpm-alpine
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1      
            #cpu: 2
            memory: 1Gi
          requests:
            cpu: 2       
            memory: 512Mi
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-wordpress-service-label
  name: magedu-wordpress-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30036
  selector:
    app: magedu-wordpress-selector

注意:以上yaml文件中CPU的配置违反了:(1)magedu-wordpress-nginx-container容器的CPU requests/limits比例值大于2
创建pod
kubectl apply -f case4-pod-RequestRatio-limit.yaml
查看pod,获取不到pod信息

这是因为违反limitrange的pod无法通过获取pod的方式查看,需要查看pod所在的deployment控制器信息
(1)先获取deployment名称

可以发现控制器READY状态为0/1
(2)获取deployment信息
kubectl get deployments magedu-wordpress-deployment -n magedu -o json

信息提示:limitrange配置的CPU最大限制的比值为2,当前比值为4
修改yaml文件:需要更改第一个容器magedu-wordpress-nginx-container的cpu requests值或者limits值(如将requests值更改为1.2)

11.3.2 CPU与内存超分限制

验证:单个pod使用的CPU超过设置的值
编辑yaml文件

vim  case4-pod-RequestRatio-limit.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-wordpress-deployment-label
  name: magedu-wordpress-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-wordpress-selector
  template:
    metadata:
      labels:
        app: magedu-wordpress-selector
    spec:
      containers:
      - name: magedu-wordpress-nginx-container
        image: nginx:1.16.1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 2
            memory: 1Gi
          requests:
            cpu: 1.2
            memory: 512Mi

      - name: magedu-wordpress-php-container
        image: php:5.6-fpm-alpine
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 3
            #cpu: 2
            memory: 1Gi
          requests:
            cpu: 1.5
            memory: 512Mi
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-wordpress-service-label
  name: magedu-wordpress-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30036
  selector:
    app: magedu-wordpress-selector

注意:以上yaml文件中违反了两个条件:(1)单个pod中两个容器的cpu最大值超过4 (2)单个容器的cpu最大值超过2。
创建pod
kubectl apply -f case4-pod-RequestRatio-limit.yaml
查看pod,获取不到pod信息

原因
这是因为违反limitrange的pod无法通过获取pod的方式查看,需要查看pod所在的deployment控制器信息
(1)先获取deployment名称

可以发现控制器READY状态为0/1
(2)获取deployment信息
kubectl get deployments magedu-wordpress-deployment -n magedu -o json

提示:单个容器cpu为3,超过2;单个pod的cpu为5,超过4
修改:将第二个容器magedu-wordpress-php-container的CPU limits修改为2即可

11.4 kubernetes对整个namespace的CPU及memory实现资源限制

  当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。
  资源配额是帮助管理员解决这一问题的工具。
  资源配额,通过 ResourceQuota 对象来定义,对每个命名空间的资源消耗总量提供限制。 包括:(1)限定某个对象类型(如Pod、service)可创建对象的总数;(2)限定某个对象类型可消耗的计算资源(CPU、内存)与存储资源(存储卷声明)总数

资源配额的工作方式如下:
  不同的团队可以在不同的命名空间下工作,目前这是非约束性的,在未来的版本中可能会通过 ACL (Access Control List 访问控制列表) 来实现强制性约束。
  集群管理员可以为每个命名空间创建一个或多个 ResourceQuota 对象。
  当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会 跟踪集群的资源使用情况,以确保使用的资源用量不超过 ResourceQuota 中定义的硬性资源限额。
  如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。
  如果命名空间下的计算资源 (如 cpu 和 memory)的配额被启用,则用户必须为 这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 Pod 设置默认值。
官网链接:https://kubernetes.io/zh/docs/concepts/policy/resource-quotas/

示例:创建ResourceQuota

vim case6-ResourceQuota-magedu.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-magedu
  namespace: magedu      #指定所在的namespace,也是限制的namespace
spec:
  hard:
    requests.cpu: "8"   #指定magedu namespace中pod可使用的CPU request值
    limits.cpu: "8"     #指定magedu namespace中pod可使用的CPU limits值
    requests.memory: 4Gi  #指定magedu namespace中pod可使用的内存request值
    limits.memory: 4Gi   #指定magedu namespace中pod可使用的内存limits值
    requests.nvidia.com/gpu: 4   #指定magedu namespace中pod可使用的gpu imits值
    pods: "5"   #指定magedu namespace中可创建的pod总数
    services: "6"   #指定magedu namespace中可创建的service总数

创建ResourceQuota
kubectl apply -f case6-ResourceQuota-magedu.yaml
查看ResourceQuota
kubectl get resourcequotas -n magedu

kubectl describe resourcequotas quota-magedu -n magedu

11.4.1 Pod副本数限制

注意:在resourcequota创建之前创建的pod不受影响,但是在resourcequota创建之后,会将已经创建的pod计算在内。如:resourcequota限制当前namespace可以创建5个pod,如果在esourcequota创建之前已经创建了6个pod,那么新建的pod将无法被创建。
验证:创建pod
编辑yaml文件

vim case7-namespace-pod-limit-test.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-nginx-deployment-label
  name: magedu-nginx-deployment
  namespace: magedu
spec:
  replicas: 5
  selector:
    matchLabels:
      app: magedu-nginx-selector
  template:
    metadata:
      labels:
        app: magedu-nginx-selector
    spec:
      containers:
      - name: magedu-nginx-container
        image: nginx:1.16.1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-nginx-service-label
  name: magedu-nginx-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    #nodePort: 30033
  selector:
app: magedu-nginx-selector

查看pod,无法获取pod信息

查看deployment控制器信息(注意要先获取控制器名称)
kubectl get deployments.apps magedu-nginx-deployment -n magedu -o json

提示当前pod数量超出了resourcequota限制的数量
修改:删除其他无用的pod,或者修改resoucequota中pod限制数量
修改之后再查看pod,pod已经开始创建

11.4.2 CPU总计核心数限制

验证:创建pod超出resourcequota限制
编辑yaml文件

vim case8-namespace-cpu-limit-test.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-nginx-deployment-label
  name: magedu-nginx-deployment
  namespace: magedu
spec:
  replicas: 4
  selector:
    matchLabels:
      app: magedu-nginx-selector
  template:
    metadata:
      labels:
        app: magedu-nginx-selector
    spec:
      containers:
      - name: magedu-nginx-container
        image: nginx:1.16.1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: 2Gi
          requests:
            cpu: 1
            memory: 512Mi

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-nginx-service-label
  name: magedu-nginx-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30033
  selector:
app: magedu-nginx-selector

创建pod
kubectl apply -f case8-namespace-cpu-limit-test.yaml
查看pod,只有2个pod

这是因为:resourcequota限制namespace只能使用4G内存,而单个pod内存为2G,则只能创建2个pod
获取deployment控制器,READY为2/4

查看deployment控制器信息

信息提示:resourcequota限制内存为4G,当前使用超出了4G,无法创建
修改:修改resourcequota的限制

标签: k8s
最后更新:2023年8月24日

袁党生

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2023 linux学习. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备18039507号-1