Kubernetes 准入控制

header-how-to-optimize-kubernetes-for-reliability-and-cos

Author:rab


目录

    • 前言
    • 一、限制范围
    • 二、配置案例
      • 2.1 名称空间 CPU 与内存约束
        • 2.1.1 CPU 约束
        • 2.1.2 内存约束
        • 2.1.3 默认 CPU 申请约束
        • 2.1.4 默认内存申请约束
      • 2.2 名称空间总容量限额约束
    • 总结


前言

LimitRange 是限制命名空间内可为每个适用的对象类别 (例如 Pod 或 PersistentVolumeClaim) 指定的资源分配量(限制和请求)的策略对象。默认情况下, Kubernetes 集群上的容器运行使用的计算资源没有限制。 使用 Kubernetes 资源配额, 管理员可以在一个指定的命名空间内限制集群资源的使用与创建。 在命名空间中,一个 Pod 最多能够使用命名空间的资源配额所定义的 CPU 和内存用量。

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

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

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

且 LimitRange 的名称必须是合法的 DNS 子域名,这一要求意味着名称必须满足如下规则:

  • 不能超过 253 个字符
  • 只能包含小写字母、数字,以及 ‘-’ 和 ‘.’
  • 必须以字母数字开头
  • 必须以字母数字结尾

官方参考文档:https://kubernetes.io/zh-cn/docs/concepts/policy/limit-range/

一、限制范围

  1. 管理员在一个命名空间内创建一个 LimitRange 对象。

  2. 用户在此命名空间内创建(或尝试创建) Pod 和 PersistentVolumeClaim 等对象。

  3. 首先,LimitRanger 准入控制器对所有没有设置计算资源需求的所有 Pod(及其容器)设置默认请求值与限制值。

  4. 其次,LimitRange 跟踪其使用量以保证没有超出命名空间中存在的任意 LimitRange 所定义的最小、最大资源使用量以及使用量比值。

  5. 若尝试创建或更新的对象(Pod 和 PersistentVolumeClaim)违反了 LimitRange 的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码 403 Forbidden 以及描述哪一项约束被违反的消息。

  6. 若你在命名空间中添加 LimitRange 启用了对 cpumemory 等计算相关资源的限制, 你必须指定这些值的请求使用量与限制使用量。否则,系统将会拒绝创建 Pod。

  7. LimitRange 的验证仅在 Pod 准入阶段进行,不对正在运行的 Pod 进行验证。 如果你添加或修改 LimitRange,命名空间中已存在的 Pod 将继续不变。

  8. 如果命名空间中存在两个或更多 LimitRange 对象,应用哪个默认值是不确定的。

二、配置案例

2.1 名称空间 CPU 与内存约束

我们可以通过 LimitRange 对象声明 CPU 的最小和最大值. 如果 Pod 不能满足 LimitRange 的限制,就无法在该命名空间中被创建。

2.1.1 CPU 约束

1、创建命名空间

创建一个命名空间,以便本练习中创建的资源和集群的其余部分相隔离。

kubectl create namespace constraints-cpu-example

2、创建 LimitRange

vim cpu-constraints.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-min-max-demo-lr
spec:
  limits:
  - max:
      cpu: "800m"
    min:
      cpu: "200m"
    type: Container
kubectl apply -f cpu-constraints.yaml -n constraints-cpu-example
kubectl get limitrange cpu-min-max-demo-lr --output=yaml -n constraints-cpu-example

image-20231107143848149

输出结果显示 CPU 的最小和最大限制符合预期。但需要注意的是,尽管你在 LimitRange 的配置文件中你没有声明默认值,默认值也会被自动创建(且默认为你设置的 max 值)。

此时,每当你在 constraints-cpu-example 命名空间中创建 Pod 时,或者某些其他的 Kubernetes API 客户端创建了等价的 Pod 时,Kubernetes 就会执行下面的步骤:

  • 如果 Pod 中的任何容器未声明自己的 CPU 请求和限制,控制面将为该容器设置默认的 CPU 请求和限制。
  • 确保该 Pod 中的每个容器的 CPU 请求至少 200 millicpu(否则创建失败)。
  • 确保该 Pod 中每个容器 CPU 请求不大于 800 millicpu(否则创建失败)。

接下来继续创建 Pod 进行测试。

3、创建 Pod

vim cpu-constraints-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: constraints-cpu-demo
spec:
  containers:
  - name: constraints-cpu-demo-ctr
    image: nginx
    resources:
      limits:
        cpu: "800m"
      requests:
        cpu: "500m"
kubectl apply -f cpu-constraints-pod.yaml -n constraints-cpu-example

4、验证 Pod 状态(确保健康)

kubectl get pod constraints-cpu-demo --namespace=constraints-cpu-example

image-20231107144339031

5、查看 Pod 的详情

kubectl get pod constraints-cpu-demo --output=yaml --namespace=constraints-cpu-example

image-20231107144434020

输出结果显示该 Pod 的容器的 CPU 请求为 500 millicpu,CPU 限制为 800 millicpu,这些参数满足 LimitRange 规定的限制范围。

Pod 异常情况分析:

Pod 的 limits 及 requests 的值只要在 LimitRange 的范围内时可正常运行,那如果超过这两个参数值超过 LimitRange 范围(即不再该范围)时又会怎么样呢?这里我们分三种情况来测试一下:超过最大 CPU 限制(limits)不满足最小 CPU 请求(requests)一个没有声明 CPU 请求和 CPU 限制的 Pod

1、超过最大 CPU 限制(limits)的 Pod

这里 Pod 的 limits 值超过 LimitRange 的 max 最大值。

vim cpu-constraints-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: constraints-cpu-demo-2
spec:
  containers:
  - name: constraints-cpu-demo-2-ctr
    image: nginx
    resources:
      limits:
        cpu: "1.5"
      requests:
        cpu: "500m"
kubectl apply -f cpu-constraints-pod-2.yaml --namespace=constraints-cpu-example

输出结果:

image-20231107150029113

Error from server (Forbidden): error when creating "cpu-constraints-pod-2.yaml": pods "constraints-cpu-demo-2" is forbidden: maximum cpu usage per Container is 800m, but limit is 1500m.

输出结果表明 Pod 没有创建成功,因为其中定义了一个无法被接受的容器,该容器之所以无法被接受是因为其中设定了过高的 CPU 限制值(即超过了 LimitRange 指定的 CPU 最大值)。

2、满足最小 CPU 请求(requests)的 Pod

这里 Pod 的 limits 值小于 LimitRange 的 min 最小值。

vim cpu-constraints-pod-3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: constraints-cpu-demo-3
spec:
  containers:
  - name: constraints-cpu-demo-3-ctr
    image: nginx
    resources:
      limits:
        cpu: "800m"
      requests:
        cpu: "100m"
kubectl apply -f cpu-constraints-pod-3.yaml --namespace=constraints-cpu-example

image-20231107150918321

输出结果同样显示 Pod 没有创建成功,因为其中定义了一个无法被接受的容器。 该容器无法被接受的原因是其中所设置的 CPU 请求小于最小值的限制(即不满足 LimitRange 指定的 CPU 最小请求值)。

3、创建一个没有声明 CPU 请求和 CPU 限制的 Pod

这里的 Pod 没有设置 limits。

vim cpu-constraints-pod-4.yaml
apiVersion: v1
kind: Pod
metadata:
  name: constraints-cpu-demo-4
spec:
  containers:
  - name: constraints-cpu-demo-4-ctr
    image: vish/stress
kubectl apply -f cpu-constraints-pod-4.yaml --namespace=constraints-cpu-example

查看 Pod 的详情:

kubectl get pod constraints-cpu-demo-4 --namespace=constraints-cpu-example --output=yaml

image-20231107152319891

输出结果显示 Pod 的唯一容器的 CPU 请求为 800 millicpu,CPU 限制为 800 millicpu。因此,如果容器没有声明自己的 CPU 请求和限制, 控制面会根据命名空间中配置 LimitRange 设置默认(default)的 CPU 请求和限制。

2.1.2 内存约束

1、创建命名空间

创建一个命名空间,以便本练习中创建的资源和集群的其余部分相隔离。

kubectl create namespace constraints-mem-example

2、创建 LimitRange

vim memory-constraints.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-min-max-demo-lr
spec:
  limits:
  - max:
      memory: 1Gi
    min:
      memory: 500Mi
    type: Container
kubectl apply -f memory-constraints.yaml --namespace=constraints-mem-example

查看 LimitRange 的详情:

kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml

image-20231107153154899

输出显示预期的最小和最大内存约束。 但请注意,即使你没有在 LimitRange 的配置文件中指定默认值,默认值也会自动生成(且默认值是你 LimitRange 中的 max 值)。

现在,每当在 constraints-mem-example 命名空间中创建 Pod 时,Kubernetes 就会执行下面的步骤:

  • 如果 Pod 中的任何容器未声明自己的内存请求和限制,控制面将为该容器设置默认的内存请求和限制。
  • 确保该 Pod 中的每个容器的内存请求至少 500 MiB。
  • 确保该 Pod 中每个容器内存请求不大于 1 GiB。

以下为包含一个容器的 Pod 清单。该容器声明了 600 MiB 的内存请求和 800 MiB 的内存限制, 这些满足了 LimitRange 施加的最小和最大内存约束。

案例效果与 CPU 约束基本上是一致的,你就是说你的 Pod 也是不能小于或超过 LimitRange 范围值,否则 Pod 将创建失败,这里就不再演示了,大家可去看官方文档。

2.1.3 默认 CPU 申请约束

前面也提到了,当我们创建 LimitRange 资源并指定 CPU max/min 值时,会自动为我们添加上默认的 CPU 约束值(即 default 和 defaultRequest 值)且是将 max 值作为默认值,如下图:

image-20231107143848149

那这两个值有什么用呢?

我们前面提到,如果创建的 Pod 没有指定约束,那 K8s 控制面板就会将 LimitRange 的 default 和 defaultRequest 值应用到 Pod 上。当然了,前提是你已经配置了 LimitRange,否则默认情况下 K8s 集群对 Pod 的资源(CPU/内存)是没有限制的。

案例也是一样,这里不再重复案例演示。

这里要注意的就是一下几种情况:

1、没有声明容器的限制(limits)和请求(requests)

此时 Pod 的 limits 和 requests 值就是 LimitRange 的 default 和 defaultRequest 值。

2、只声明容器的限制(limits)而不声明请求(requests)

此时 Pod 的 limits 和 requests 值就是你当前声明的值 limits。

3、只声明容器的请求(requests)而不声明限制(limits)

此时 Pod 的 limits 值为你 LimitRange 的 default 值,requests 值就是你当前声明的 requests 值。

因此不难总结出 LimitRange 的 limits 的作用:

  • default:在 Pod 没有指定 limits 约束时的 limits 值;

  • defaultRequest:在 Pod 没有指定 requests 约束时的 requests 值;

  • max:在 Pod 指定了 limits 约束时不能超过的最大值;

  • min:在 Pod 指定了 requests 约束时不能小于的最最值;

而且也要记住,你指定的 Pod 值也是不能超过 LimitRange 默认值范围。

2.1.4 默认内存申请约束

前面也提到了,当我们创建 LimitRange 资源并指定内存 max/min 值时,会自动为我们添加上默认的内存约束值(即 default 和 defaultRequest 值)且是将 max 值作为默认值,如下图:

image-20231107153154899

那这两个值有什么用呢?

同理,当创建的 Pod 没有指定约束时,那 K8s 控制面板就会将 LimitRange 的 default 和 defaultRequest 值应用到 Pod 上。

案例也是一样,这里不再重复案例演示。

这里要注意的就是一下几种情况:

1、没有声明容器的限制(limits)和请求(requests)

此时 Pod 的 limits 和 requests 值就是 LimitRange 的 default 和 defaultRequest 值。

2、只声明容器的限制(limits)而不声明请求(requests)

此时 Pod 的 limits 和 requests 值就是你当前声明的值 limits。

3、只声明容器的请求(requests)而不声明限制(limits)

此时 Pod 的 limits 值为你 LimitRange 的 default 值,requests 值就是你当前声明的 requests 值。

因此不难总结出 LimitRange 的 limits 的作用:

  • default:在 Pod 没有指定 limits 约束时的 limits 值;

  • defaultRequest:在 Pod 没有指定 requests 约束时的 requests 值;

  • max:在 Pod 指定了 limits 约束时不能超过的最大值;

  • min:在 Pod 指定了 requests 约束时不能小于的最最值;

而且也要记住,你指定的 Pod 值也是不能超过 LimitRange 默认值范围。

2.2 名称空间总容量限额约束

以上的案例都是使用 LimitRange 对 namespace 中某个 Pod 的 CPU、内存资源约束,当我们希望控制单个名字空间总的可以消耗多少存储空间、CPU、内存以控制成本时,我们就可以使用名称空间存储容量约束-StorageQuota。

而存储约束无非就这几个方面:

  1. 名字空间中持久卷申领(persistent volume claims)的数量
  2. 每个申领(claim)可以请求的存储量
  3. 名字空间可以具有的累计存储量

1、创建命名空间

创建一个命名空间,以便本练习中创建的资源和集群的其余部分相隔离。

kubectl create namespace quota-mem-cpu-example

2、创建 LimitRange

vim quota-mem-cpu.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
kubectl apply -f quota-mem-cpu.yaml --namespace=quota-mem-cpu-example

查看 ResourceQuota 详情:

kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml

image-20231107165339685

ResourceQuota 在 quota-mem-cpu-example 命名空间中设置了如下要求:

  • 在该命名空间中的每个 Pod 的所有容器都必须要有内存请求和限制,以及 CPU 请求和限制。
  • 在该命名空间中所有 Pod 的内存请求总和不能超过 1 GiB。
  • 在该命名空间中所有 Pod 的内存限制总和不能超过 2 GiB。
  • 在该命名空间中所有 Pod 的 CPU 请求总和不能超过 1 cpu。
  • 在该命名空间中所有 Pod 的 CPU 限制总和不能超过 2 cpu。

3、创建 Pod

vim quota-mem-cpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: quota-mem-cpu-demo
spec:
  containers:
  - name: quota-mem-cpu-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "800Mi"
        cpu: "800m"
      requests:
        memory: "600Mi"
        cpu: "400m"
kubectl apply -f quota-mem-cpu-pod.yaml --namespace=quota-mem-cpu-example

查看 Pod 状态:

kubectl get pod quota-mem-cpu-demo --namespace=quota-mem-cpu-example

image-20231107165734288

再次查看 ResourceQuota 的详情:

kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml

image-20231107165825218

输出结果显示了配额以及有多少配额已经被使用,你可以看到 Pod 的内存和 CPU 请求值及限制值没有超过配额。

如果我们再继续创建一个 Pod,如下:

vim quota-mem-cpu-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: quota-mem-cpu-demo-2
spec:
  containers:
  - name: quota-mem-cpu-demo-2-ctr
    image: redis
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"
      requests:
        memory: "700Mi"
        cpu: "400m"
kubectl apply -f quota-mem-cpu-pod-2.yaml --namespace=quota-mem-cpu-example

image-20231107170437885

报错了,为什呢?因为在 quota-mem-cpu-example 名称空间中,内存请求与已经使用的内存请求之和超过了内存请求的配额:600 MiB + 700 MiB > 1 GiB

总结

1、LimitRange

  • 用于对 namespace 中的 Pod 的 CPU、内存约束;
  • 默认情况下 K8s 集群对 Pod 是没有约束的(即没有 LimitRange);
  • 当对 namespace 进行准入控制时,在该 namespace 中的 Pod 需遵循 namespace 中的约束。

2、StorageQuota

  • 用于限制某个 namespace 总的限额(即该 namespace 中的所有的 Pod 资源的 CPU、内存、存储不能超过指定的限额)。

—END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119669.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android View 触摸反馈原理浅析

重写OnTouchEvent() 然后在方法内部写触摸算法 返回true,表示消费事件,所有触摸反馈不再生效,返回事件所有权 if (event.actionMasked MotionEvent.ACTION_UP){performClick()//抬起事件 执行performClick 触发点击 }override fun onTouchEvent(event: MotionEvent): Boolea…

代码随想录算法训练营第四十四天丨 动态规划part07

70. 爬楼梯 思路 这次讲到了背包问题 这道题目 我们在动态规划:爬楼梯 (opens new window)中已经讲过一次了,原题其实是一道简单动规的题目。 既然这么简单为什么还要讲呢,其实本题稍加改动就是一道面试好题。 改为:一步一个…

【代码随想录】算法训练营 第十五天 第六章 二叉树 Part 2

102. 二叉树的层序遍历 层序遍历,就是一层一层地遍历二叉树,最常见的就是从上到下,从左到右来遍历,遍历的方法依然有两种,第一种是借助队列,第二种则是递归,都算是很简单、很容易理解的方法&am…

VLAN与配置

VLAN与配置 什么是VLAN 以最简单的形式为例。如下图,此时有4台主机处于同一局域网中,很明显这4台主机是能够直接通讯。但此时我需要让处于同一局域网中的PC3和PC4能通讯,PC5和PC6能通讯,并且PC3和PC4不能与PC5和PC6通讯。 为了实…

图论——并查集

参考内容: 图论——并查集(详细版) 并查集(Disjoint-set)是一种精巧的树形数据结构,它主要用于处理一些不相交集合的合并及查询问题。一些常见用途,比如求联通子图、求最小生成树的 Kruskal 算法和求最近公共祖先&…

测试接触不到第一手需求,如何保证不漏测?

测试接触不到第一手需求,了解到的需求都是分解过的需求,该怎么做才能保证不漏测? 这个问题还是挺普遍的。因为随着分工越来越精细,每个人可能只能接触到全局的一部分,再加上信息传递过程中的信息丢失,就很…

bootstrap3简单玩法

Bootstrap v3 Bootstrap v3 是一个流行的前端框架,它提供了一系列的模板、组件和工具,可以帮助开发者快速地构建响应式的网站和应用程序。 以下是 Bootstrap v3 的一些常见应用: 响应式布局:Bootstrap v3 提供了一个易于使用的网…

1.性能优化

概述 今日目标: 性能优化的终极目标是什么压力测试压力测试的指标 性能优化的终极目标是什么 用户体验 产品设计(非技术) 系统性能(快,3秒不能更久了) 后端:RT,TPS,并发数 影响因素01:数据库读写,RPC&#xff…

未来已来,“码”上见证---通义灵码

为了撰写一份关于通义灵码的产品测评,我将构建一个基于提供的产品介绍和评测内容要求的框架给大家介绍这款产品。 功能使用维度 代码智能生成 使用场景:开发中遇到需要编写新功能、单元测试、或对现有代码进行注释时。 使用效果:预期通义灵…

个体诊所管理系统电子处方软件,个体诊所人员服务软件,佳易王电子处方开单系统

个体诊所管理系统电子处方软件,个体诊所人员服务软件,佳易王电子处方开单系统 软件功能: 1、常用配方模板:可以自由添加配方分类,预先设置药品配方。 2、正常开药:可以灵活选择药品,用法用量&…

ubuntu| sudo apt-get update 更新失败, 没有 Release 文件 无法安全地用该源进行更新,所以默认禁用该源

xiaoleubt:~$ sudo apt-get update -y 命中:1 https://dl.google.com/linux/chrome/deb stable InRelease 忽略:2 http://ppa.launchpad.net/ubuntu-desktop/ubuntu-make/ubuntu focal InRelease 命中:3 https://packages.microsoft.com/repos/code stable InRelease 命中:4 ht…

老电脑升级内存、固态硬盘、重新装机过程记录

基础环境: 电脑型号:联想XiaoXin700-15ISK系统版本:Windows10 家庭中文版 版本22H2内存:硬盘: 升级想法: 内存升级,固态硬盘升级,系统重装(干净一点) 升级内存…

【java】实现自定义注解校验——方法一

自定义注解校验的实现步骤: 1.创建注解类,编写校验注解,即类似NotEmpty注解 2.编写自定义校验的逻辑实体类,编写具体的校验逻辑。(这个类可以实现ConstraintValidator这个接口,让注解用来校验) 3.开启使用自定义注解进…

超级英雄云计算的技术之旅

超级英雄云计算的技术之旅 超级英雄云计算的技术之旅摘要引言可变参数:Java的超级工具可变参数的用途1. 编写通用工具方法2. 构建日志记录工具3. 构建数据验证工具 云计算在智能家居中的应用1. 远程控制智能设备2. 数据分析和智能决策3. 安全和隐私4. 智能家居应用开…

掌动智能性能压力测试优势有哪些

企业通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。本文将介绍性能压力测试的价值及主要优势! 一、性能压力测试的价值 1、评估系统能力:有助于参数的基准测试,可以度量系统的响应时间;还有助于检查系统是否可…

python-opencv写入视频文件无法播放

python-opencv写入视频文件无法播放 在采用Python写OpenCV的视频时,生成的视频总是无法播放,大小只有不到两百k,播放器提示视频已经损坏。网上搜了一些方法,记录下解决办法。 代码如下 fourcc cv2.VideoWriter_fourcc(*MJPG) fp…

idea中配置spring boot单项目多端口启动

参照文章 https://zhuanlan.zhihu.com/p/610767685 项目配置如下 下面为 idea 2023,不同版本的设置有区别,但是没那么大,idea 2023默认使用新布局,切换为经典布局即可。 在项目根目录的.idea/workspace.xml文件里添加如下配置 &l…

装甲工程车3D虚拟云展厅提升企业在市场占有份额

应急通信车的出现,极大适应了防灾救援大数据背景下数字化、网络化、系统化、多维化的发展需求,为了让更多客户了解到应急通信车,提升企业在市场占有份额及领域,借助web3d开发制作的应急通信车3D云展示平台大大丰富了展示形式及内涵…

10年测试经验分享:新手如何找到适合自己的软件测试项目?

每一个测试新手(特别是自学测试的人)来说,往往不知道到哪里去找项目练手,这应该是最大的困扰了。 实话讲,这个目前没有非常好的、直接的解决办法,不过在这我可以结合我自己之前的一些工作经历,…

Linux实现进度条小程序(包含基础版本和模拟下载过程版本)

Linux实现进度条小程序[包含基础版本和模拟下载过程版本] Linux实现进度条小程序1.预备的两个小知识1.缓冲区1.缓冲区概念的引出2.缓冲区的概念 2.回车与换行1.小例子2.倒计时小程序 2.基础版进度条1.的回车方式的打印2.百分比的打印3.状态提示符的打印 3.升级版进度条1.设计:进…