76·调度与资源进阶

资源请求

kubernetesresourcesrequests

资源请求

学习目标

  1. 理解资源请求(requests)的概念和作用
  2. 掌握 CPU 和内存请求的设置方法
  3. 了解 requests 对调度和资源分配的影响

核心概念

一句话解释

资源请求告诉 Kubernetes 节点需要多少 CPU 和内存,用于调度决策。

Requests vs Limits

┌─────────────────────────────────────────────────────────┐
│                    资源模型                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Requests(请求):                                      │
│  - Pod 运行需要的最小资源量                             │
│  - 用于调度决策(选择有足够资源的节点)                  │
│  - 节点保证这些资源可用                                 │
│                                                         │
│  Limits(限制):                                        │
│  - Pod 可以使用的最大资源量                             │
│  - 超过限制会被限制或杀掉                               │
│  - 可选设置                                             │
│                                                         │
│  ┌─────────────────────────────────────────┐           │
│  │  节点 CPU: 4 核                          │           │
│  │  ┌─────────────────────────────────┐    │           │
│  │  │  Pod A: requests: 1 CPU         │    │           │
│  │  │  ┌─────────────────────────┐    │    │           │
│  │  │  │  实际使用 0.5 CPU       │    │    │           │
│  │  │  └─────────────────────────┘    │    │           │
│  │  └─────────────────────────────────┘    │           │
│  │  ┌─────────────────────────────────┐    │           │
│  │  │  Pod B: requests: 2 CPU         │    │           │
│  │  │  ┌─────────────────────────┐    │    │           │
│  │  │  │  实际使用 1.5 CPU       │    │    │           │
│  │  │  └─────────────────────────┘    │    │           │
│  │  └─────────────────────────────────┘    │           │
│  │  剩余可调度: 1 CPU (4-1-2)              │           │
│  └─────────────────────────────────────────┘           │
│                                                         │
└─────────────────────────────────────────────────────────┘

YAML 语法

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "500m"        # 0.5 核 CPU
        memory: "128Mi"    # 128 MiB 内存

CPU 资源单位

┌─────────────────────────────────────────────────────────┐
│                    CPU 单位                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  1 CPU = 1000m (millicores)                             │
│                                                         │
│  示例:                                                  │
│  - 0.5 CPU = 500m                                       │
│  - 0.1 CPU = 100m                                       │
│  - 2 CPU = 2000m                                        │
│  - 1/4 CPU = 250m                                       │
│                                                         │
│  最小单位:1m (0.001 CPU)                               │
│                                                         │
└─────────────────────────────────────────────────────────┘

内存资源单位

┌─────────────────────────────────────────────────────────┐
│                    内存单位                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  二进制单位:                                            │
│  - 1 KiB = 1024 字节                                    │
│  - 1 MiB = 1024 KiB                                     │
│  - 1 GiB = 1024 MiB                                     │
│  - 1 TiB = 1024 GiB                                     │
│                                                         │
│  十进制单位:                                            │
│  - 1 KB = 1000 字节                                     │
│  - 1 MB = 1000 KB                                       │
│  - 1 GB = 1000 MB                                       │
│  - 1 TB = 1000 GB                                       │
│                                                         │
│  示例:                                                  │
│  - 128Mi = 134,217,728 字节                             │
│  - 128M = 128,000,000 字节                              │
│                                                         │
└─────────────────────────────────────────────────────────┘

调度过程

┌─────────────────────────────────────────────────────────┐
│                    调度决策                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Pod: requests: cpu=500m, memory=256Mi                  │
│                                                         │
│  节点检查:                                              │
│  ┌─────────────────────────────────────────┐           │
│  │  Node1: 可用 CPU=1000m, 可用内存=512Mi  │           │
│  │  1000m >= 500m ✓                        │           │
│  │  512Mi >= 256Mi ✓                       │           │
│  │  → 可以调度                             │           │
│  └─────────────────────────────────────────┘           │
│                                                         │
│  ┌─────────────────────────────────────────┐           │
│  │  Node2: 可用 CPU=200m, 可用内存=1Gi    │           │
│  │  200m < 500m ✗                          │           │
│  │  → 不可调度                             │           │
│  └─────────────────────────────────────────┘           │
│                                                         │
│  结果:Pod 调度到 Node1                                 │
│                                                         │
└─────────────────────────────────────────────────────────┘

资源配额影响

# ResourceQuota 限制 Namespace 总资源
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: my-namespace
spec:
  hard:
    requests.cpu: "10"           # 总 CPU 请求上限
    requests.memory: "20Gi"      # 总内存请求上限
    pods: "20"                   # Pod 数量上限

LimitRange 默认值

# LimitRange 设置默认 requests
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: my-namespace
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container

实践练习

练习 1:设置资源请求

# pod-requests.yaml
apiVersion: v1
kind: Pod
metadata:
  name: requests-pod
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:
        cpu: "250m"
        memory: "128Mi"
kubectl apply -f pod-requests.yaml
kubectl describe pod requests-pod | grep -A 5 "Requests"

练习 2:观察资源分配

# 查看节点资源分配
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

# 查看 Pod 的资源请求
kubectl get pod <pod-name> -o yaml | grep -A 5 resources

练习 3:资源不足时的调度

# pod-big-requests.yaml
apiVersion: v1
kind: Pod
metadata:
  name: big-pod
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:
        cpu: "100"          # 请求 100 核 CPU
        memory: "200Gi"     # 请求 200 GiB 内存
kubectl apply -f pod-big-requests.yaml
kubectl get pod big-pod
# 状态应该是 Pending

# 查看调度失败原因
kubectl describe pod big-pod | grep -A 10 Events

练习 4:多容器 Pod 资源请求

# pod-multi-container.yaml
apiVersion: v1
kind: Pod
metadata:
  name: multi-container
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "200m"
        memory: "128Mi"
  - name: sidecar
    image: busybox
    command: ["sleep", "3600"]
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
# 总请求:cpu=300m, memory=192Mi

练习 5:查看资源使用

# 安装 metrics-server(如果未安装)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 查看 Pod 实际资源使用
kubectl top pod <pod-name>

# 查看节点资源使用
kubectl top node

最佳实践

1. 设置合理的 requests
   - 基于实际资源使用情况
   - 留有一定余量

2. 使用工具测量
   - kubectl top 查看实际使用
   - Prometheus 监控历史数据

3. 避免资源浪费
   - 不要设置过大的 requests
   - 会导致资源利用率低

4. 避免资源不足
   - 不要设置过小的 requests
   - 会导致 OOM 或性能问题

常见问题

1. Pod 一直 Pending

# 检查节点可用资源
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

# 检查 Pod 的 requests
kubectl get pod <pod-name> -o yaml | grep -A 5 resources

# 检查是否有 ResourceQuota 限制
kubectl get resourcequota -n <namespace>

2. 如何确定合适的 requests

# 查看实际资源使用
kubectl top pod <pod-name>

# 查看历史数据(需要 Prometheus)
# 建议 requests 设置为实际使用的 1.5-2 倍

3. requests 和 limits 的关系

# 建议设置
resources:
  requests:
    cpu: "500m"      # 保证的资源
    memory: "256Mi"
  limits:
    cpu: "1000m"     # 最大资源
    memory: "512Mi"

# 不设置 limits 时
# - CPU: Pod 可以使用节点所有可用 CPU(共享)
# - 内存: 无限制,可能导致 OOM

小结

要点说明
requestsPod 需要的最小资源量
作用用于调度决策,节点保证这些资源
CPU 单位1 CPU = 1000m (millicores)
内存单位MiB (二进制), MB (十进制)
调度影响节点必须有足够的可用资源
最佳实践基于实际使用设置合理的 requests

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「资源限制」 以巩固所学知识。