首页 > 其他分享 >k8s 准入控制器之LimitRanger

k8s 准入控制器之LimitRanger

时间:2023-08-12 10:05:09浏览次数:39  
标签:控制器 限制 demoapp LimitRanger LimitRange Pod k8s cpu 资源

LimitRanger概述

尽管用户可以为容器或Pod资源指定资源需求及资源限制,但这并非强制性要求,那些未明确定义资源限制的容器应用很可能会因程序Bug或真实需求而吞掉本地工作节点上的所有可用计算资源。因此妥当的做法是,使用LimitRange资源在每个名称空间中限制每个容器的最小及最大计算资源用量,以及为未显式定义计算资源使用区间的容器设置默认的计算资源需求和计算资源限制。一旦在名称空间上定义了LimitRange对象,客户端创建或修改资源对象的操作必将受到LimitRange控制器的“验证”,任何违反LimitRange对象定义的资源最大用量的请求都将被直接拒绝。
LimitRange支持在Pod级别与容器级别分别设置CPU和内存两种计算资源的可用范围,它们对应的资源范围限制类型分别为Pod和Container。一旦在名称空间上启用LimitRange,该名称空间中的Pod或容器的requests和limits的各项属性值必须在对应的可用资源范围内,否则将会被拒绝,这是验证型准入控制器的功能。而未显式指定request和limit属性的容器,将会从LimitRange资源上分别自动继承相应的默认设置,这是变异型准入控制器的功能。
另外,LimitRange也支持在PersistentVolumeClaim资源级别设定存储空间的范围限制,它用于限制相应名称空间中创建的PVC对象请求使用的存储空间不能逾越指定的范围。未指定requests和limits属性的PVC规范,将在创建时自动继承LimitRange上配置的默认值。
当前,默认的 LimitRanger 对 default 名字空间中的所有 Pod 都设置 0.1 CPU 的需求。

限制范围

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

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

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

LimitRange 的名称必须是合法的 DNS 子域名。

资源限制和请求的约束

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

创建LimitRange

demoapp-ns.yaml

apiVersion: v1
kind: Namespace
metadata:
    name: demoapp

limitrange.yaml

需要注意的是,LimitRange生效于名称空间级别,它需要定义在每个名称空间之上;另外,定义的限制仅对该资源创建后的Pod和PVC资源创建请求有效,对之前已然存在的资源无效;再者,不建议在生效于同一名称空间的多个LimitRange资源上,对同一个计算资源限制进行分别定义,以免产生歧义或导致冲突。
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-demoapp
  namespace: demoapp
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
      memory: 2        #限制内存 Limit/request比值最大为2
  - type: Pod
    max:
      cpu: "500m"         #限制单个Pod的最大CPU
      memory: "512Mi"     #限制单个Pod最大内存
    min:
      cpu: "300m"         #限制单个Pod的最小CPU
      memory: "128Mi"    #限制单个Pod最小内存
  - type: PersistentVolumeClaim
    max:
      storage: "60Gi"    #限制 PVC最大的 requests.storage
    min:
      storage: "30Gi"    #限制 PVC最小的 requests.storage
    default:
      storage: "30Gi"    #限制 PVC默认的 requests.storage      
    defaultRequest:
      storage: "30Gi"    
    maxLimitRequestRatio:
      storage: "2"
LimitRange仅在Container资源类型上可为CPU与内存设置default(limits属性的默认值)和defaultrequest(requests属性的默认值),Pod资源类型不支持。

创建LimitRange资源

# kubectl apply -f demoapp-ns.yaml -f limitrange.yaml
namespace/demoapp created
limitrange/limitrange-demoapp created

查看LimitRange资源

# kubectl describe limitranges/limitrange-demoapp -n demoapp
Name:                  limitrange-demoapp
Namespace:             demoapp
Type                   Resource  Min    Max    Default Request  Default Limit  Max Limit/Request Ratio
----                   --------  ---    ---    ---------------  -------------  -----------------------
Container              memory    512Mi  2Gi    512Mi            512Mi          2
Container              cpu       500m   2      500m             500m           2
Pod                    cpu       300m   500m   -                -              -
Pod                    memory    128Mi  512Mi  -                -              -
PersistentVolumeClaim  storage   30Gi   70Gi   30Gi             30Gi           2

示例 

没有声明容器限制

depoly-demoapp-v10.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demoappv10
    version: v1.0
  name: demoappv10
  namespace: demoapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demoapp
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demoapp
        version: v1.0
    spec:
      containers:
      - image: ikubernetes/demoapp:v1.0
        name: demoapp
        env:
        - name: PORT
          value: "8080"
        resources: {}

创建Deployment资源

# kubectl apply -f depoly-demoapp-v10.yaml
deployment.apps/demoappv10 created

查看deployment资源详情

# kubectl get pod `kubectl get pods -n demoapp -o jsonpath={".items[0].metadata.name"}` -n demoapp -o jsonpath={".spec.containers[0].resources"} | jq
{
  "limits": {
    "cpu": "500m",
    "memory": "512Mi"
  },
  "requests": {
    "cpu": "500m",
    "memory": "512Mi"
  }
}
输出内容显示该 Pod 的容器资源限制。 这些都是 LimitRange 设置的默认值。

声明容器限制超出LimitRange限制

depoly-demoapp-v10.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demoappv10
    version: v1.0
  name: demoappv10
  namespace: demoapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demoapp
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demoapp
        version: v1.0
    spec:
      containers:
      - image: ikubernetes/demoapp:v1.0
        name: demoapp
        env:
        - name: PORT
          value: "8080"
        resources: 
          limits:
            memory: "1Gi"
            cpu: "3"
          requests:
            memory: "1Gi"
            cpu: "3"

创建Deployment资源

# kubectl apply -f depoly-demoapp-v10.yaml
deployment.apps/demoappv10 created

查看deployment资源

# kubectl get deployment/demoappv10 -n demoapp
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
demoappv10   0/1     0            0           2m42s
deployment正常创建,pod没有正常创建。

查看deployment报错信息

# kubectl get deployment/demoappv10 -n demoapp -o jsonpath={".status.conditions"} | jq
[
  {
    "lastTransitionTime": "2023-08-08T06:38:34Z",
    "lastUpdateTime": "2023-08-08T06:38:34Z",
    "message": "Created new replica set \"demoappv10-8644b5fff4\"",
    "reason": "NewReplicaSetCreated",
    "status": "True",
    "type": "Progressing"
  },
  {
    "lastTransitionTime": "2023-08-08T06:38:34Z",
    "lastUpdateTime": "2023-08-08T06:38:34Z",
    "message": "Deployment does not have minimum availability.",
    "reason": "MinimumReplicasUnavailable",
    "status": "False",
    "type": "Available"
  },
  {
    "lastTransitionTime": "2023-08-08T06:38:34Z",
    "lastUpdateTime": "2023-08-08T06:38:34Z",
    "message": "pods \"demoappv10-8644b5fff4-tcctm\" is forbidden: [maximum cpu usage per Container is 2, but limit is 3, maximum cpu usage per Pod is 500m, but limit is 3, maximum memory usage per Pod is 512Mi, but limit is 1073741824]",   # 报错信息
    "reason": "FailedCreate",
    "status": "True",
    "type": "ReplicaFailure"
  }
]
maximum cpu usage per Container is 2, but limit is 3。 该错误信息是type: Container 的limits信息。
maximum cpu usage per Pod is 500m, but limit is 3。    该错误信息是type: pod 的limits信息。
由此可见对同一个计算资源限制进行分别定义,都需要满足要求后pod才可创建成功。

注意事项

需要注意的是,LimitRange生效于名称空间级别,它需要定义在每个名称空间之上;另外,定义的限制仅对该资源创建后的Pod和PVC资源创建请求有效,对之前已然存在的资源无效;再者,不建议在生效于同一名称空间的多个LimitRange资源上,对同一个计算资源限制进行分别定义,以免产生歧义或导致冲突。

参考文档

https://kubernetes.io/zh-cn/docs/concepts/policy/limit-range/



标签:控制器,限制,demoapp,LimitRanger,LimitRange,Pod,k8s,cpu,资源
From: https://blog.51cto.com/wangguishe/7056433

相关文章

  • k8s 网络模型
    容器网络通信模式在Host模式中,各容器共享宿主机的根网络名称空间,它们使用同一个接口设备和网络协议栈,因此,用户必须精心管理共享同一网络端口空间容器的应用与宿主机应用,以避免端口冲突。Bridge模式对host模式进行了一定程度的改进,在该模式中,容器从一个或多个专用网络(地址池)中获取IP......
  • k8s实战案例之运行dubbo微服务
    1、dubbo微服务架构图通过上述架构可以了解到,生产者通过注册中心,将服务注册至注册中心,消费者通过注册中心找到生产者,从而实现消费者拿到生产者的实际地址,然后直接和生产者通信;管理端通过注册中心发现生产者和消费者,通过svc来管理生产者和消费者;集群外部客户端通过负载均衡器来......
  • k8s 网络模型
    容器网络通信模式在Host模式中,各容器共享宿主机的根网络名称空间,它们使用同一个接口设备和网络协议栈,因此,用户必须精心管理共享同一网络端口空间容器的应用与宿主机应用,以避免端口冲突。Bridge模式对host模式进行了一定程度的改进,在该模式中,容器从一个或多个专用网络(地址池)中获......
  • k8s jenkines kubesphere 部署流水线样例
    pipeline{agent{node{label'maven'}}stages{stage('拉取代码'){agentnonesteps{container('maven'){git(url......
  • k8s 自身原理 2
    前面我们说到K8S的基本原理和涉及的四大组件,分享了前两个组件etcd和ApiServer这一次我们接着分享一波:调度器scheduler控制器管理器controllermanager调度器scheduler调度器,见名知意,用于调度k8s资源的,那么这个调度器具体主要是调度啥资源呢?实际上看我们k8s中......
  • K8S 1.27.1版本初始化配置文件时报your configuration file uses an old API spec: "k
    现象:yourconfigurationfileusesanoldAPIspec:"kubeadm.k8s.io/v1beta2".Pleaseusekubeadmv1.22insteadandrun'kubeadmconfigmigrate--old-configold.yaml--new-confignew.yaml',whichwillwritethenew,similarspecusingan......
  • Mac M1安装k8s
    一、下载:下载你docker-mac对应的版本,我的是v1.21.3gitclone-bv1.21.3https://github.com/AliyunContainerService/k8s-for-docker-desktop.git二、执行脚本下拉镜像:进入k8s-for-docker-desktop,执行如下命令./load_images.sh开启kubernetes开启Kubernetes,并等待......
  • 水塔自动抽水控制器
    水塔自动抽水控制是通过光电液位传感器实现的。这种控制器采用了光电液位传感器来检测水塔的水位,主要用于检测缺水和满水状态,并控制水泵、电磁阀或其他需要控制的仪器,实现自动补水功能。根据客户的要求,逻辑功能可以进行相应的更改。光电液位传感器内置了红外发光二极管和光敏接收器......
  • k8s部署 elasticsearch7集群,其中一台节点报错无法域名解析 :resolving host...
    部署es7集群其中一个节点一直报错resolvinghost考虑有两点,要么是coredns组件出问题了,无法解析,要么是calico网络组件出问题了,首先我就去看网络组件了,果然发现问题,我这台机器有两个网卡,一个是enp9s0(172.16.2.30地址),一个是enp11s0(172.16.2.25地址),我加入的节点是30机器,但是calico绑定......
  • 愣着干嘛?视频串讲K8S+Go+ELK技术栈!来白嫖啊
    欢迎白嫖~视频地址:https://www.bilibili.com/video/BV1ZS4y1B7dM/视频地址:https://www.bilibili.com/video/BV1ZS4y1B7dM/视频地址:https://www.bilibili.com/video/BV1ZS4y1B7dM/......