K8s学习笔记(十九) K8s资源限制
1 pod资源限制
1.1 2 个核心概念:requests vs limits
这是 K8s 资源限制的基础,二者作用完全不同,必须分清。
概念 | 作用 | 关键说明 |
---|---|---|
requests(资源请求) | 告诉 K8s “这个 Pod 至少需要这么多资源才能运行” | 1. K8s 只会把 Pod 调度到有足够空闲资源的节点上(比如请求 1 核 CPU,节点空闲 CPU 必须≥1 核才会调度);2. 这是 “保障下限”,确保 Pod 有基本运行资源。 |
limits(资源上限) | 告诉 K8s “这个 Pod 最多只能用这么多资源” | 1. 当 Pod 实际使用资源超过 limits 时,会被 K8s “限制”(CPU 超了会变慢,内存超了可能被杀死);2. 这是 “限制上限”,防止 Pod 占用过多资源影响其他 Pod。 |
1.2 实战:写一个带资源限制的 Pod YAML
直接看配置示例,关键是resources
字段,里面包含requests
和limits
。
apiVersion: v1
kind: Pod
metadata:name: my-resource-demo
spec:containers:- name: demo-containerimage: nginx # 用nginx举例,换成你的应用镜像resources:requests: # 资源请求(保障下限)cpu: "100m" # CPU请求:100毫核(1核=1000m,即0.1核)memory: "128Mi"# 内存请求:128兆字节limits: # 资源上限(限制上限)cpu: "500m" # CPU最多用500毫核(0.5核)memory: "256Mi"# 内存最多用256兆字节
关键细节解释:
- CPU 单位:用 “毫核(m)” 表示,1 核 = 1000m。
- 比如
500m
就是 0.5 核,2000m
就是 2 核。
- 比如
- 内存单位:用 “Mi/Gi”(1Mi=1024Ki,1Gi=1024Mi),避免用 “MB/GB”(十进制),防止计算偏差。
- 配置位置:
resources
在container 层级配置,因为每个容器的资源需求可能不同(一个 Pod 里可以有多个容器)。
1.3 资源超限时,K8s 会怎么处理?
这是实际运维中必须知道的 “后果”,避免踩坑。
1.3.1 CPU 超限额(超过 limits.cpu)
- 不会杀死 Pod,只会被 K8s “限流”(Throttle)。
- 比如 Pod 要用到 1 核,但 limits 设为 0.5 核,K8s 会强制让 Pod 的 CPU 使用 “降速”,相当于给 Pod “限速”,保证不会占用更多 CPU。
1.3.2 内存超限额(超过 limits.memory)
- 后果更严重:会触发 “内存溢出(OOM)”,K8s 会直接杀死这个 Pod(Evict),然后根据 Pod 的重启策略(RestartPolicy)决定是否重启。
- 比如 Pod 用了 300Mi 内存,但 limits 设为 256Mi,K8s 会判定这个 Pod “资源超标”,直接终止它,避免耗尽节点内存。
1.4 3 个最佳实践,避免踩坑
- requests 不要设太高:如果 requests 设得和 limits 一样高,会导致节点资源 “被占满”(比如节点有 2 核 CPU,一个 Pod 的 requests 设 2 核,其他 Pod 就无法调度到这个节点),浪费资源。
- 根据应用类型调整:
- 无状态服务(如 Web 服务):CPU limits 可以设高一点,内存 limits 精准控制(避免 OOM);
- 数据库服务(如 MySQL):内存 requests 和 limits 尽量接近,保证数据库有稳定的内存可用,避免被限流。
- 监控资源使用:用
kubectl top pod
命令查看 Pod 实际资源使用情况,再调整 requests/limits(比如发现 Pod 一直只用 50m CPU,就把 requests 从 100m 降到 50m)。
Namespace 资源限制的核心是通过 ResourceQuota(资源配额) 和 LimitRange(限制范围) 两种机制,对整个命名空间下的所有资源进行 “总量管控” 和 “个体约束”,避免单个命名空间过度占用集群资源,实现多团队 / 业务间的资源隔离。
2 Namespace 级限制
Pod 级别的requests/limits
是控制单个 Pod 的资源使用,而 Namespace 级限制解决的是更宏观的问题:
- 防止某个团队的 Namespace(如测试环境)创建过多 Pod 或占用过多 CPU / 内存,导致其他 Namespace(如生产环境)资源不足。
- 给每个 Namespace 设定 “资源天花板”,确保集群资源在多业务间合理分配。
- 自动为 Namespace 内未配置资源的 Pod 补充默认
requests/limits
,避免 “裸奔” Pod 无序占用资源。
2.1 核心机制 1:ResourceQuota(资源配额)—— 控制 Namespace 总资源
作用:限制整个 Namespace 能使用的资源总量(如总 CPU、总内存)和对象数量(如最多创建多少个 Pod、Service),是 Namespace 资源的 “总闸门”。
2.1.1 配置示例(YAML)
apiVersion: v1
kind: ResourceQuota
metadata:name: ns-quota # 配额名称namespace: dev # 要限制的Namespace(这里以dev为例)
spec:hard: # 硬限制,必须遵守,超了就无法创建新资源# 1. 计算资源总量(CPU/内存)requests.cpu: "2" # 整个Namespace的总CPU请求 ≤ 2核requests.memory: "2Gi" # 整个Namespace的总内存请求 ≤ 2Gilimits.cpu: "4" # 整个Namespace的总CPU上限 ≤ 4核limits.memory: "4Gi" # 整个Namespace的总内存上限 ≤ 4Gi# 2. 对象数量限制(避免创建过多资源导致集群混乱)pods: "10" # 整个Namespace最多创建10个Podservices: "5" # 整个Namespace最多创建5个Servicepersistentvolumeclaims: "3" # 最多创建3个PVC(存储声明)
2.1.2 关键说明
-
hard
字段:所有限制都是 “强制性” 的,当 Namespace 内资源使用达到hard
值时,再创建新资源(如 Pod)会被 K8s 拒绝。 -
查看配额使用情况:执行
kubectl describe resourcequota ns-quota -n dev
,能看到已使用资源和剩余配额(如Used: requests.cpu=1.2, limits.memory=1.5Gi
)。 -
灵活匹配资源:可通过
scopeSelector
只对特定标签的资源生效(如只限制 “环境 = test” 的 Pod),示例如下:
spec:scopeSelector:matchExpressions:- operator: InscopeName: PriorityClassvalues: [high-priority] # 只对高优先级的资源生效配额
2.2 核心机制 2:LimitRange(限制范围)—— 控制 Pod / 容器的默认值与范围
作用:为 Namespace 内的单个 Pod / 容器设置资源默认值和取值范围约束,解决 “Pod 未配置资源” 或 “单个 Pod 资源超标” 的问题。
2.2.1 配置示例(YAML)
apiVersion: v1
kind: LimitRange
metadata:name: ns-limit-rangenamespace: dev
spec:limits:- type: Container # 对容器生效的限制default: # 容器未配置limits时,自动填充的默认值cpu: "500m"memory: "256Mi"defaultRequest: # 容器未配置requests时,自动填充的默认值cpu: "100m"memory: "128Mi"max: # 容器的资源上限,不能超过这个值cpu: "1000m" # 单个容器最多用1核CPUmemory: "512Mi"min: # 容器的资源下限,不能低于这个值cpu: "50m" # 单个容器至少请求50毫核CPUmemory: "64Mi"- type: Pod # 对Pod生效的限制(所有容器资源总和)max:cpu: "2000m" # 单个Pod的所有容器CPU总和 ≤ 2核memory: "1Gi" # 单个Pod的所有容器内存总和 ≤ 1Gi
2.2.2 关键说明
- 默认值自动填充:如果在该 Namespace 下创建 Pod 时,容器未配置
requests/limits
,K8s 会自动使用default
和defaultRequest
的值填充,避免 “裸奔”。 - 范围约束强制生效:如果 Pod 的资源配置超出
max
或低于min
(如容器请求2000m
CPU,超过max:1000m
),K8s 会直接拒绝创建该 Pod。
2.3 实战:如何使用这两种机制?
-
先创建 LimitRange:确保单个 Pod / 容器的资源配置合规,且未配置资源时能自动补全默认值。
kubectl apply -f ns-limit-range.yaml -n dev
-
再创建 ResourceQuota:设定 Namespace 的总资源上限,防止整体资源超用。
kubectl apply -f ns-quota.yaml -n dev
-
验证配置:
- 查看 LimitRange:
kubectl get limitrange -n dev
- 查看 ResourceQuota:
kubectl get resourcequota -n dev
- 查看配额使用:
kubectl describe resourcequota ns-quota -n dev
- 查看 LimitRange: