资源管理与 QoS
资源请求与限制、QoS 等级、LimitRange、ResourceQuota
概述
Kubernetes 资源管理确保 Pod 获得合理的资源分配。CKA 考试重点考察 requests/limits 配置、QoS 等级判断、LimitRange 和 ResourceQuota。
一、资源请求(Requests)与限制(Limits)
1.1 基本概念
| 参数 | 说明 | 作用 |
|---|---|---|
requests | 容器保证的最小资源量 | 调度器依据此值选择节点 |
limits | 容器能使用的最大资源量 | 限制资源超额使用 |
1.2 CPU 单位
resources:
requests:
cpu: "0.5" # 500m(毫核),等价于 500m
memory: "256Mi" # 256 Mebibytes
limits:
cpu: "1" # 1 核
memory: "512Mi"
CPU 单位速查:
| 单位 | 等价 |
|---|---|
1 | 1 核(vCPU) |
0.5 | 500m |
100m | 0.1 核 |
1k | 1000m(不常用) |
内存单位速查:
| 单位 | 说明 |
|---|---|
Mi | Mebibytes(2^20, 推荐) |
M | Megabytes(10^6, 不推荐) |
Gi | Gibibytes(2^30, 推荐) |
Ki | Kibibytes(2^10) |
1.3 Pod 资源配置示例
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: 250m
memory: "128Mi"
limits:
cpu: 500m
memory: "256Mi"
1.4 关键命令
kubectl describe node <node-name>
# 查看节点资源分配情况(Requested vs Allocatable)
kubectl describe node <node-name> | grep -A 5 "Allocated resources"
# 查看所有节点的资源情况(考试常用)
kubectl top node
kubectl top pod
# 为 Pod 设置资源限制
kubectl run nginx --image=nginx --dry-run=client -o yaml --limits='cpu=500m,memory=256Mi' --requests='cpu=250m,memory=128Mi'
二、QoS 等级(Quality of Service)
Kubernetes 根据 Pod 的 requests/limits 配置自动分配 QoS 等级。
2.1 三种 QoS 等级
| QoS 等级 | 条件 | 驱逐优先级 |
|---|---|---|
| Guaranteed | 所有容器 requests == limits | 最低 |
| Burstable | 至少一个容器有 requests 或 limits,但不满足 Guaranteed | 中等 |
| BestEffort | 没有任何容器设置 requests/limits | 最高(最先被驱逐) |
2.2 配置示例
Guaranteed(所有容器 requests == limits):
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: 500m
memory: 256Mi
limits:
cpu: 500m
memory: 256Mi
Burstable(requests < limits 或只有 reuqests):
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: 250m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
BestEffort(无 resources 字段):
spec:
containers:
- name: app
image: nginx
# 没有 resources 字段
2.3 判断 QoS 等级
# 查看 Pod QoS 等级
kubectl describe pod <pod-name> | grep QoS
kubectl get pod <pod-name> -o yaml | grep qosClass
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'
2.4 QoS 对 Pod 驱逐的影响
当节点资源不足时,kubelet 按以下顺序驱逐 Pod:
- BestEffort:最先被驱逐
- Burstable:使用资源超出 requests 的 Pod
- Guaranteed:只有在系统进程需要资源时才被驱逐
驱逐依据:
memory.available低于阈值nodefs.available或nodefs.inodesFree低于阈值imagefs.available低于阈值
三、LimitRange
LimitRange 在命名空间级别设置 Pod / 容器的默认资源请求和限制。
3.1 配置示例
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limit-range
namespace: default
spec:
limits:
- default: # 默认 limits
cpu: 500m
memory: 256Mi
defaultRequest: # 默认 requests
cpu: 250m
memory: 128Mi
max: # 最大限制
cpu: "2"
memory: 1Gi
min: # 最小限制
cpu: 100m
memory: 64Mi
type: Container # 适用于 Container
- type: Pod
max:
cpu: "4"
memory: 4Gi
3.2 LimitRange 类型
| 类型 | 作用范围 |
|---|---|
Container | 单个容器(最常用) |
Pod | 整个 Pod 所有容器之和 |
PersistentVolumeClaim | 存储声明大小 |
3.3 使用命令
# 创建 LimitRange
kubectl apply -f limitrange.yaml
# 查看
kubectl get limitrange
kubectl get limits
kubectl describe limitrange cpu-limit-range
# 删除
kubectl delete limitrange cpu-limit-range
注意:LimitRange 只对创建后提交的 Pod 生效,不修改已存在的 Pod。
四、ResourceQuota
ResourceQuota 限制命名空间的资源使用总量。
4.1 配置示例
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: test
spec:
hard:
requests.cpu: "4" # 所有 Pod CPU requests 总和上限
requests.memory: "8Gi" # 所有 Pod 内存 requests 总和上限
limits.cpu: "8" # 所有 Pod CPU limits 总和上限
limits.memory: "16Gi" # 所有 Pod 内存 limits 总和上限
requests.nvidia.com/gpu: 4 # GPU 数量
pods: "10" # Pod 数量上限
services: "5" # Service 数量上限
persistentvolumeclaims: "5" # PVC 数量上限
configmaps: "5" # ConfigMap 数量上限
secrets: "5" # Secret 数量上限
4.2 对象数量配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
namespace: test
spec:
hard:
pods: "10"
services: "5"
configmaps: "5"
secrets: "5"
persistentvolumeclaims: "3"
replicationcontrollers: "5"
deployments.apps: "5" # 不需要计数
resourcequotas: "1"
4.3 最佳实践:同时设置 LimitRange 和 ResourceQuota
# 当设置了 ResourceQuota 的 requests.cpu 时,创建 Pod 必须设置 CPU requests
# 因此需要同时创建 LimitRange 提供默认值
# 步骤 1:创建 LimitRange 提供默认值
kubectl apply -f limitrange.yaml
# 步骤 2:创建 ResourceQuota
kubectl apply -f resourcequota.yaml
# 步骤 3:创建 Pod(会自动应用 LimitRange 的默认值)
kubectl run nginx --image=nginx
4.4 ResourceQuota 命令
# 创建 ResourceQuota
kubectl create quota compute-quota -n test \
--hard=requests.cpu=4,requests.memory=8Gi,limits.cpu=8,limits.memory=16Gi,pods=10
# 查看 ResourceQuota
kubectl get resourcequota -n test
kubectl get quota -n test
kubectl describe quota compute-quota -n test
# 查看 ResourceQuota 使用情况
kubectl get quota -n test -o yaml # 显示 Used 和 Hard
五、实用命令汇总
# 查看节点资源
kubectl top node
kubectl top pod -n <namespace>
# 查看节点可分配资源
kubectl describe node <node-name> | grep -E "Capacity|Allocatable"
# 查看节点已分配资源
kubectl describe node <node-name> | grep -A 5 "Allocated resources"
# 创建带资源限制的 Pod(命令式)
kubectl run nginx --image=nginx --restart=Never \
--requests='cpu=250m,memory=128Mi' \
--limits='cpu=500m,memory=256Mi'
# 快速创建 LimitRange(--dry-run)
kubectl create limitrange cpu-limit --dry-run=client -o yaml > limitrange.yaml
# 编辑添加 default/defaultRequest/max/min
# 快速创建 ResourceQuota
kubectl create quota my-quota --hard=pods=5,services=3 --dry-run=client -o yaml
# 查找 QoS 等级为 BestEffort 的 Pod
kubectl get pods -o json | jq '.items[] | select(.status.qosClass=="BestEffort") | .metadata.name'
# 为命名空间设置 ResourceQuota
kubectl create namespace restricted
kubectl create quota ns-quota -n restricted --hard=requests.cpu=2,requests.memory=4Gi,pods=5
六、常见场景
场景 1:创建名空间并设置资源限制
kubectl create namespace team-a
kubectl create quota team-quota -n team-a --hard=requests.cpu=2,requests.memory=4Gi,pods=10
# 此时创建 Pod 必须指定 requests,否则报错
# 解决方案:先创建 LimitRange 提供默认值
场景 2:Pod 因资源不足无法调度
# 查看 Pod 事件
kubectl describe pod <pod-name> | grep -A 10 Events
# 常见错误:0/3 nodes are available: 1 Insufficient cpu, 2 Insufficient memory
# 解决方案:检查 requests 设置,或添加更多节点
场景 3:OOMKilled(内存超限)
# Pod 状态显示 OOMKilled
kubectl get pod <pod-name>
# 输出:CrashLoopBackOff 或 Error
kubectl describe pod <pod-name> | grep -i oom
# Last State: Terminated
# Reason: OOMKilled
# Exit Code: 137
# 解决方案:增加内存 limits 或优化应用内存使用
🧪 完整操作实例:配置 Pod 资源限制并观察 QoS 等级
场景描述
创建三个 Pod 分别对应三种 QoS 等级(Guaranteed/Burstable/BestEffort),观察差异。
前置条件
- 可用的 Kubernetes 集群
- kubectl 已配置连接集群
操作步骤
Step 1: 创建 Guaranteed QoS Pod(requests == limits)
cat <<'EOF' > pod-guaranteed.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-guaranteed
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "256Mi"
EOF
kubectl apply -f pod-guaranteed.yaml
# 预期输出:pod/pod-guaranteed created
Step 2: 创建 Burstable QoS Pod(requests < limits)
cat <<'EOF' > pod-burstable.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-burstable
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
EOF
kubectl apply -f pod-burstable.yaml
# 预期输出:pod/pod-burstable created
Step 3: 创建 BestEffort QoS Pod(无 resources 字段)
cat <<'EOF' > pod-besteffort.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-besteffort
spec:
containers:
- name: app
image: nginx
EOF
kubectl apply -f pod-besteffort.yaml
# 预期输出:pod/pod-besteffort created
验证结果
# 方法 1:使用 jsonpath 查看 QoS 等级
kubectl get pod pod-guaranteed -o jsonpath='{.status.qosClass}'
# 预期输出:Guaranteed
kubectl get pod pod-burstable -o jsonpath='{.status.qosClass}'
# 预期输出:Burstable
kubectl get pod pod-besteffort -o jsonpath='{.status.qosClass}'
# 预期输出:BestEffort
# 方法 2:使用 describe
kubectl describe pod pod-guaranteed | grep QoS
# 预期输出:QoS Class: Guaranteed
kubectl describe pod pod-burstable | grep QoS
# 预期输出:QoS Class: Burstable
kubectl describe pod pod-besteffort | grep QoS
# 预期输出:QoS Class: BestEffort
# 方法 3:一次性查看所有 Pod 的 QoS
for p in pod-guaranteed pod-burstable pod-besteffort; do
echo "$p: $(kubectl get pod $p -o jsonpath='{.status.qosClass}')"
done
# 预期输出:
# pod-guaranteed: Guaranteed
# pod-burstable: Burstable
# pod-besteffort: BestEffort
# 清理
kubectl delete pod pod-guaranteed pod-burstable pod-besteffort
# 预期输出:pod "pod-guaranteed" deleted
# pod "pod-burstable" deleted
# pod "pod-besteffort" deleted
考试提示
- Guaranteed 的条件是所有容器的 requests 和 limits 必须完全相等(CPU 和 内存都需一致)
- 如果 Pod 中有多个容器,只要一个容器未设置 resources 即为 BestEffort,只要一个容器 requests != limits 即为 Burstable
- 节点资源不足时,驱逐顺序为:BestEffort > Burstable > Guaranteed
- CKA 中常要求创建 Pod 并设置资源限制,然后用
kubectl get pod -o jsonpath或-o yaml | grep qosClass查看 QoS - 资源单位注意:CPU 不要引号也可(
cpu: 1),内存必须带单位(memory: "256Mi")