k8s 学习笔记 - LimitRange 限制范围
前情提要
- 在当前工作经验中,从未限制过
namespace
的资源,这次的实施工作中,使用的是第三方定制的 k8s 集群,在namespace
被创建时,因为yaml
文件没有配置limits
和requests
两个参数,当yaml
文件被apply
后,自动对pod
配置了LimitRange
中定义的limits
和requests
,结果资源不够使用,导致容器启动过程中出现OOMKilled
报错- 后续在
yaml
中加上limits
和requests
依然有报错,导致控制器无法创建pod
,原因是LimitRange
中的limits.maxLimitRequestRatio
配置,对于limits
和requests
的比例有限制
开始复盘
下面两个是 k8s 官方文档
借用一下官方文档
什么是限制范围
LimitRange
是限制namespace(命名空间)
内可为每个适用的对象类别 (例如Pod
或PersistentVolumeClaim
)指定的资源分配量(limits
和requests
)的策略对象- 一个
LimitRange(限制范围)
对象提供的限制能够做到:- 在一个
namespace(命名空间)
中实施对每个Pod
或Container
最小和最大的资源使用量的限制。 - 在一个
namespace(命名空间)
中实施对每个PersistentVolumeClaim
能申请的最小和最大的存储空间大小的限制。 - 在一个
namespace(命名空间)
中实施对一种资源的requests(申请值)
和limits(限制值)
的比值的控制。 - 设置一个
namespace(命名空间)
中对计算资源的默认requests(申请值) / limits(限制值)
,并且自动的在运行时注入到多个 Container 中。
- 在一个
- 当某
namespace(命名空间)
中有一个LimitRange
对象时,将在该namespace(命名空间)
中实施LimitRange
限制 LimitRange
的名称必须是合法的DNS 子域名
资源限制和请求的约束
- 管理员在一个
namespace(命名空间)
内创建一个LimitRange
对象。 - 用户在此
namespace(命名空间)
内创建(或尝试创建)Pod
和PersistentVolumeClaim
等对象。 - 首先,
LimitRanger
准入控制器对所有没有设置
计算资源需求的所有 Pod(及其容器)
设置默认请求值与限制值。 - 其次,
LimitRange
跟踪其使用量以保证没有超出命名空间中存在的任意LimitRange
所定义的最小、最大资源使用量以及使用量比值。 - 若尝试创建或更新的对象(
Pod
和PersistentVolumeClaim
)违反了LimitRange
的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码403 Forbidden
以及描述哪一项约束被违反的消息。 - 若你在
namespace(命名空间)
中添加LimitRange
启用了对cpu
和memory
等计算相关资源的限制, 你必须指定这些值的请求使用量与限制使用量。否则,系统将会拒绝创建 Pod
。 LimitRange
的验证仅在Pod 准入阶段
进行,不对正在运行的 Pod
进行验证。 如果你添加或修改LimitRange
,namespace(命名空间)
中已存在的Pod
将继续不变。- 如果命名空间中存在两个或更多
LimitRange
对象,应用哪个默认值是不确定的
实践出真知
- 这里图省事,就直接拿 k8s 自带的
default
这个namespace
来做演示- 这里图省事,就直接部署
pod
,没有使用任何控制器(deployment
,statefulset
,daemonset
这一类)
- 如果是控制器启动的,以下创建
pod
失败的场景,通过kubectl get pod
命令会查看不到pod
被创建的,使用kubectl describe <控制器名称>
命令能查看到同理的报错- 以下的示例都是拿
cpu
做演示,内存是同理的
场景1
pod
配置的requests
超出了LimitRange
配置的limits
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-resource-constraint
spec:
limits:
- default: # 此处定义默认限制值(limits)
cpu: 500m
defaultRequest: # 此处定义默认请求值(requests)
cpu: 500m
type: Container
EOF
可以通过
kubectl get limitrange
命令查看是否创建成功
创建一个 pod 来验证
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "36000"
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 700m
restartPolicy: Always
EOF
- 这个时候就会有报错出现
The Pod "busybox" is invalid: spec.containers[0].resources.requests: Invalid value: "700m": must be less than or equal to cpu limit
- 只需要把
cpu: 700m
调小一点,低于limitrange
里面配置的default
就可以重新运行 pod 了
场景2
继续使用
场景1
的limitrange
,但是创建的pod
同时配置了limits
和requests
,并且均超过limitrange
里面配置的资源限制
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-resource-limits-requests
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "36000"
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 700m
requests:
cpu: 700m
restartPolicy: Always
EOF
此时,pod 是可以被创建的
场景3
继续使用
场景1
的limitrange
,但是创建的pod
没有配置limits
和requests
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-no-resource-set
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "36000"
imagePullPolicy: IfNotPresent
restartPolicy: Always
EOF
pod
是肯定可以创建的,并且会自动给pod
赋值limits
和requests
kubectl get pod busybox-no-resource-set -o yaml | grep 'resources' -A 4
可以看出来,
limits
和requests
都是limitrange
内配置的500m
resources:
limits:
cpu: 500m
requests:
cpu: 500m
场景4
继续使用
场景1
的limitrange
,但是创建的pod
只配置了limits
,并且比limitrange
里面的值要高
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-just-limits
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "36000"
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 700m
restartPolicy: Always
EOF
pod
可以被成功创建,且requests
被赋值和limits
的值一致
kubectl get pod busybox-just-limits -o yaml | grep 'resources' -A 4
resources:
limits:
cpu: 700m
requests:
cpu: 700m
场景5
- 这里图省事,就拿内存来做示例了
limitrange
配置了maxLimitRequestRatio
,创建的pod
的limits/requests
的值不等于 1
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-resource-constraint
spec:
limits:
- default: # 此处定义默认限制值(limits)
memory: 256Mi
defaultRequest: # 此处定义默认请求值(requests)
memory: 256Mi
maxLimitRequestRatio: # 此处定义 limits/requests 的值必须等于 1
memory: 1
type: Container
EOF
创建一个
pod
来验证
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-ratio-ne-one
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "36000"
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 700Mi
requests:
memory: 70Mi
restartPolicy: Always
EOF
- 这个
pod
是无法被创建的,会返回Error from server (Forbidden): error when creating "STDIN": pods "busybox-ratio-ne-one" is forbidden: memory max limit to request ratio per Container is 1, but provided ratio is 10.000000
这样的报错- 这个
10.000000
就是700/70=10
得来的- 只需要把
limits
和requests
的值改成一样的,就可以成功启动pod
了
学习总结
- 当
namespace
配置了limitrange
,并且pod
创建时没有指明limits
或/和requests
时,pod
被创建后由limitrang
的配置来指明pod
的limits
或/和requests
- 当
namespace
配置了limitrange
,并且pod
创建时的requests
超出了limitrange
配置的limits
时,会有报错must be less than or equal to xxx limit
- 当
namespace
配置了limitrange
以及maxLimitRequestRatio
,并且pod
创建时的limits/requests
值大于maxLimitRequestRatio
配置的值,会有报错is forbidden: xxx max limit to request ratio per Container is xxx, but provided ratio is xxx
关于
limits
,requests
,maxLimitRequestRatio
的取值,主要是围绕cpu
和memroy
的单位来的
- 在 k8s 中,
数量(Quantity)
是数字的定点表示,没有数量可以表示大于2的63次方-1
的数,也不可能超过3 个小数位
;更大或更精确的数字将被截断或向上取整(只会显示整数)- 在 k8s 中,
cpu
的单位为m
,1000m
=1核
0.1m
将向上取整为1m
- 在 k8s 中,
memory
的单位为k | M | G | T | P | E
或者Ki | Mi | Gi | Ti | Pi | Ei
- 区别在于换算不同,一个是
1:1000
,另一个是1:1024
:1m
表示1000k
1Mi
表示1024k
- 程序员眼中的整数,必须是
1024
- 区别在于换算不同,一个是
最后,大家也可以去验证,当 memory 这里写 1.5 的时候,pod 创建完,再去 get -o yaml,就会发现 1.5 变成了 1500m
- 在 k8s 中,
分类:
Kubernetes
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!