前情提要
开始复盘
什么是限制范围
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
对象,应用哪个默认值是不确定的
实践出真知
场景1
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
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
场景2
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
场景3
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
kubectl get pod busybox-no-resource-set -o yaml | grep 'resources' -A 4
resources:
limits:
cpu: 500m
requests:
cpu: 500m
场景4
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
kubectl get pod busybox-just-limits -o yaml | grep 'resources' -A 4
resources:
limits:
cpu: 700m
requests:
cpu: 700m
场景5
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
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
学习总结
- 当
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
- 在 k8s 中,
数量(Quantity)
是数字的定点表示,没有数量可以表示大于 2的63次方-1
的数,也不可能超过 3 个小数位
;更大或更精确的数字将被截断或向上取整(只会显示整数) - 在 k8s 中,
cpu
的单位为 m
,1000m
= 1核
- 在 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