第八周记录

一、Kubernetes Container、Pod、Namespace内存及CPU限制

1、限制范围 | Kubernetes

默认情况下, Kubernetes 集群上的容器运行使用的计算资源没有限制。 使用 Kubernetes 资源配额, 管理员(也称为 集群操作者)可以在一个指定的命名空间内限制集群资源的使用与创建。 在命名空间中,一个 Pod 最多能够使用命名空间的资源配额所定义的 CPU 和内存用量。 作为集群操作者或命名空间级的管理员,你可能也会担心如何确保一个 Pod 不会垄断命名空间内所有可用的资源。

LimitRange 是限制命名空间内可为每个适用的对象类别 (例如 Pod 或 PersistentVolumeClaim) 指定的资源分配量(限制和请求)的策略对象。

一个 LimitRange(限制范围) 对象提供的限制能够做到:

  • 在一个命名空间中实施对每个 Pod 或 Container 最小和最大的资源使用量的限制。
  • 在一个命名空间中实施对每个 PersistentVolumeClaim 能申请的最小和最大的存储空间大小的限制。
  • 在一个命名空间中实施对一种资源的申请值和限制值的比值的控制。
  • 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个 Container 中。

当某命名空间中有一个 LimitRange 对象时,将在该命名空间中实施 LimitRange 限制。

1、资源限制和请求的约束

  • 管理员在一个命名空间内创建一个 LimitRange 对象。
  • 用户在此命名空间内创建(或尝试创建) Pod 和 PersistentVolumeClaim 等对象。
  • 首先,LimitRanger 准入控制器对所有没有设置计算资源需求的所有 Pod(及其容器)设置默认请求值与限制值。
  • 其次,LimitRange 跟踪其使用量以保证没有超出命名空间中存在的任意 LimitRange 所定义的最小、最大资源使用量以及使用量比值。
  • 若尝试创建或更新的对象(Pod 和 PersistentVolumeClaim)违反了 LimitRange 的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码 403 Forbidden 以及描述哪一项约束被违反的消息。
  • 若你在命名空间中添加 LimitRange 启用了对 cpumemory 等计算相关资源的限制, 你必须指定这些值的请求使用量与限制使用量。否则,系统将会拒绝创建 Pod。
  • LimitRange 的验证仅在 Pod 准入阶段进行,不对正在运行的 Pod 进行验证。 如果你添加或修改 LimitRange,命名空间中已存在的 Pod 将继续不变。
  • 如果命名空间中存在两个或更多 LimitRange 对象,应用哪个默认值是不确定的。

2、Pod 的 LimitRange 和准入检查

LimitRange 检查所应用的默认值的一致性。 这意味着 LimitRange 设置的 limit 的默认值可能小于客户端提交给 API 服务器的规约中为容器指定的 request 值。 如果发生这种情况,最终 Pod 将无法调度。

3、资源需求与限制

相比较而言,CPU属于可压缩型资源,即资源额度可按需弹性变化,而内存(当前)则是不可压缩型资源,对其执行压缩操作可能会导致某种程度的问题,例如进程崩溃等。目前,资源隔离仍属于容器级别,CPU和内存资源的配置主要在Pod对象中的容器上进行,并且每个资源存在如图4-16所示的需求和限制两种类型。为了表述方便,人们通常把资源配置称作Pod资源的需求和限制,只不过它是指Pod内所有容器上的某种类型资源的请求与限制总和。

image-20230213120418907

  • 资源需求:定义需要系统预留给该容器使用的资源最小可用值,容器运行时可能用不到这些额度的资源,但用到时必须确保有相应数量的资源可用。

  • 资源限制:定义该容器可以申请使用的资源最大可用值,超出该额度的资源使用请求将被拒绝;显然,该限制需要大于等于requests的值,但系统在某项资源紧张时,会从容器回收超出request值的那部分。

在Kubernetes系统上,1个单位的CPU相当于虚拟机上的1颗虚拟CPU(vCPU)或物理机上的一个超线程(Hyperthread,或称为一个逻辑CPU),它支持分数计量方式,一个核心(1 core)相当于1000个微核心(millicores,以下简称为m),因此500m相当于是0.5个核心,即1/2个核心。内存的计量方式与日常使用方式相同,默认单位是字节,也可以使用E、P、T、G、M和K为单位后缀,或Ei、Pi、Ti、Gi、Mi和Ki形式的单位后缀。

image-20230213140847243

2、单个容器的 memory 资源限制

为容器和 Pods 分配 CPU 资源 | Kubernetes

root@k8s-deploy:/yaml/20220821/magedu-limit-case# vim case1-pod-memory-limit.yml 

#apiVersion: extensions/v1beta1
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: "256Mi"   # 限制256Mi
          requests:
            memory: "256Mi"   # 需求256Mi
        #command: ["stress"]
        args: ["--vm", "2", "--vm-bytes", "256M"]  # 启动2个线程,每个线程占用256Mi内存(总共512Mi内存)
      #nodeSelector:
      #  env: group1

memory 使用始终在 256Mi 下,cpu 没做限制,所以把剩余 cpu 占满了。

image-20230213141839313

3、单个容器的 CPU 和 memory 资源限制

root@k8s-deploy:/yaml/20220821/magedu-limit-case# vim case2-pod-memory-and-cpu-limit.yml 

#apiVersion: extensions/v1beta1
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: "300m"   # cpu 限制300毫核
            memory: "256Mi"
          requests:
            memory: "256Mi"
            cpu: "300m"
        #command: ["stress"]
        args: ["--vm", "3", "--vm-bytes", "256M"] 
      #nodeSelector:
      #  env: group1

image-20230213143230625

4、LimitRange 准入控制器

LimitRange 是限制命名空间内可为每个适用的对象类别 (例如 Pod 或 PersistentVolumeClaim) 指定的资源分配量(限制和请求)的策略对象。

一个 LimitRange(限制范围) 对象提供的限制能够做到:

  • 在一个命名空间中实施对每个 Pod 或 Container 最小和最大的资源使用量的限制。
  • 在一个命名空间中实施对每个 PersistentVolumeClaim 能申请的最小和最大的存储空间大小的限制。
  • 在一个命名空间中实施对一种资源的申请值和限制值的比值的控制。
  • 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个 Container 中。

当某命名空间中有一个 LimitRange 对象时,将在该命名空间中实施 LimitRange 限制。

1、创建 LimitRange

root@k8s-deploy:/yaml/20220821/magedu-limit-case# vim case3-LimitRange.yaml 

apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-magedu
  namespace: magedu
spec:
  limits:
  - type: Container       #限制的资源类型(容器、pod、pvc 等)
    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  
      memory: 2           #限制内存 limit/request比值最大为2
  - type: Pod
    max:
      cpu: "4"            #限制单个Pod的最大CPU
      memory: "4Gi"       #限制单个Pod最大内存
  - type: PersistentVolumeClaim
    max:
      storage: 50Gi        #限制PVC最大的requests.storage
    min:
      storage: 30Gi        #限制PVC最小的requests.storage

image-20230213150441034

2、cpu 的 limit/request 比值超出 LimitRange 定义的最大值

此处演示 cpu 的 limit/request 比值超过 LimitRange 定义的最大值2,导致了 Pod 无法创建。

root@k8s-deploy:/yaml/20220821/magedu-limit-case# cat 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: 1.5    # 限制1.5核 cpu
            memory: 1Gi
          requests:
            cpu: 500m   # 请求500毫核 cpu,limit/request 比值为3,超过了 LimitRange 定义的最大值2,所以 pod 无法创建。
            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: 2
            #cpu: 2
            memory: 1Gi
          requests:
            cpu: 2000m
            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: 30033
  selector:
    app: magedu-wordpress-selector

本例中 limit 为1.5核 cpu,request 为500毫核 cpu,cpu 的 RequestRatio 比值为3,超过了 LimitRange 定义的最大值2,所以 pod 无法创建。表现为:明明 kubectl apply 了,但是 kubectl get pod 查不到任何痕迹。

image-20230213152415635

我们可以查询 deployment ,发现没有 ready,使用 kubectl -n magedu get deployments.apps magedu-wordpress-deployment -o json 命令查看 deployment ,可以看到报错:pods \"magedu-wordpress-deployment-b78d895b6-vc29d\" is forbidden: cpu max limit to request ratio per Container is 2, but provided ratio is 3.000000

image-20230213153604336

image-20230213153737778

此处涉及到了 RBAC 鉴权流程:身份验证和鉴权通过了,但是第三步准入控制没通过。

image-20230212190314986

同理,Pod 的 cpu 和内存超出限制、容器的 cpu 和内存超出限制、limit/request 比值超出限制都可以这样查找原因。

5、整个 namespace 的 CPU 和内存资源限制

  • 限定某个对象类型(如 pod、service)可创建对象的总数

  • 限定某个对象类型可消耗的计算资源(CPU、内存)与存储资源(存储卷声明)总数

资源配额 | Kubernetes,通过 ResourceQuota 对象来定义,对每个命名空间的资源消耗总量提供限制。 它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命名空间中的 Pod 可以使用的计算资源的总上限。

资源配额的工作方式如下:

  • 不同的团队可以在不同的命名空间下工作。这可以通过 RBAC 强制执行。
  • 集群管理员可以为每个命名空间创建一个或多个 ResourceQuota 对象。
  • 当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会跟踪集群的资源使用情况, 以确保使用的资源用量不超过 ResourceQuota 中定义的硬性资源限额。
  • 如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。
  • 如果命名空间下的计算资源 (如 cpumemory)的配额被启用, 则用户必须为这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 Pod 设置默认值。

说明:

  • 对于 cpumemory 资源:ResourceQuota 强制该命名空间中的每个(新)Pod 为该资源设置限制。 如果你在命名空间中为 cpumemory 实施资源配额, 你或其他客户端必须为你提交的每个新 Pod 指定该资源的 requestslimits。 否则,控制平面可能会拒绝接纳该 Pod。
  • 对于其他资源:ResourceQuota 可以工作,并且会忽略命名空间中的 Pod,而无需为该资源设置限制或请求。 这意味着,如果资源配额限制了此命名空间的临时存储,则可以创建没有限制/请求临时存储的新 Pod。 你可以使用限制范围自动设置对这些资源的默认请求。

计算资源配额

用户可以对给定命名空间下的可被请求的 计算资源 总量进行限制。

配额机制所支持的资源类型:

资源名称 描述
limits.cpu 所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。
limits.memory 所有非终止状态的 Pod,其内存限额总量不能超过该值。
requests.cpu 所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。
requests.memory 所有非终止状态的 Pod,其内存需求总量不能超过该值。
hugepages-<size> 对于所有非终止状态的 Pod,针对指定尺寸的巨页请求总数不能超过此值。
cpu requests.cpu 相同。
memory requests.memory 相同。

1、创建 ResourceQuota

root@k8s-deploy:/yaml/20220821/magedu-limit-case# vim case6-ResourceQuota-magedu.yaml 

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-magedu
  namespace: magedu
spec:
  hard:
    requests.cpu: "8"               # 在该命名空间中所有 Pod 的 CPU 请求总和不能超过 8 cpu   
    limits.cpu: "8"                 # 在该命名空间中所有 Pod 的 CPU 限制总和不能超过 8 cpu
    requests.memory: 8Gi            # 在该命名空间中所有 Pod 的内存请求总和不能超过 8 GiB
    limits.memory: 8Gi              # 在该命名空间中所有 Pod 的内存限制总和不能超过 8 GiB
    requests.nvidia.com/gpu: 4
    pods: "6"                       # 在该命名空间中只能创建 6 个 pod
    services: "6"                   # 在该命名空间中只能创建 6 个 service

image-20230213163038514

2、Pod 副本数超出限制

本例中我要创建5个副本,但是该 namespace 已经存在4个 Pod 了,所以最后只能创建两个 Pod 。

root@k8s-deploy:/yaml/20220821/magedu-limit-case# cat 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

image-20230213165051529

image-20230213165136080

3、CPU 总计核数超出限制

在本例中,我创建两个副本,每个 Pod 请求4核 cpu 和4g内存,已经超出限制。

root@k8s-deploy:/yaml/20220821/magedu-limit-case# cat 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: 2
  selector:
    matchLabels:
      app: magedu-nginx-selector
  template:
    metadata:
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值