Qingular

资源管理与 QoS

·CKAk8s练习

资源请求与限制、QoS 等级、LimitRange、ResourceQuota

← 返回 CKA 练习目录

概述

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 单位速查

单位等价
11 核(vCPU)
0.5500m
100m0.1 核
1k1000m(不常用)

内存单位速查

单位说明
MiMebibytes(2^20, 推荐)
MMegabytes(10^6, 不推荐)
GiGibibytes(2^30, 推荐)
KiKibibytes(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:

  1. BestEffort:最先被驱逐
  2. Burstable:使用资源超出 requests 的 Pod
  3. Guaranteed:只有在系统进程需要资源时才被驱逐

驱逐依据:

  • memory.available 低于阈值
  • nodefs.availablenodefs.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"

官方文档链接