18、Kubernetes 集群中 Pod 资源管理与调度策略详解

Kubernetes 集群中 Pod 资源管理与调度策略详解

1. Pod 创建异常情况分析

在 Kubernetes 集群中创建 Pod 时,可能会遇到各种因资源请求不合理或违反配额限制而导致的问题。

1.1 过高资源请求的 Pod 创建

当创建一个请求资源( spec.containers.resources.requests )和限制资源( spec.containers.resources.limits )过高,而节点无法提供这些资源的 Pod 时,调度将会失败。以下是一个示例 Pod 对象:

apiVersion: v1
kind: Pod
metadata:
  name: ha-too-high-resource-requests-pod-failure
spec:
  containers:
  - name: ha-too-high-resource-requests-pod-failure-c-1
    image: nginx:1.10.1
    resources:
      limits:
        memory: "500Gi"
        cpu: "100"
      requests:
        memory: "500Gi"
        cpu: "100"

操作步骤如下:
1. 将上述代码保存为一个 YAML 文件,例如 high_request_pod.yaml
2. 使用 kubectl create -f high_request_pod.yaml 命令执行创建操作。
3. 你会看到类似 “Kubernetes rejected the request because it violates one or more constraints.” 的错误信息,表明调度失败是因为 Pod 请求的资源超过了允许的限制。

1.2 违反资源配额限制的 Pod 创建

如果创建的 Pod 违反了资源配额对象指定的限制,调度也会失败。示例如下:

apiVersion: v1
kind: Pod
metadata:
  name: ha-resource-quota-failure-pod
spec:
  containers:
  - name: ha-resource-quota-failure-pod-c-1
    image: nginx:1.10.1
    resources:
      limits:
        memory: "1.1Gi"
        cpu: "1100m"
      requests:
        memory: "600Mi"
        cpu: "600m"

此 Pod 对象的请求和限制违反了资源配额对象的限制,因此创建时会失败。

2. Pod 资源默认值的自动分配

可以使用 LimitRange 对象为命名空间中创建的所有 Pod 自动分配默认的请求和限制值。

2.1 创建 LimitRange 对象
apiVersion: v1
kind: LimitRange
metadata:
  name: ha-limit-range-defaults
spec:
  limits:
  - default:
      memory: 800Mi
      cpu: "800m"
    defaultRequest:
      memory: 600Mi
      cpu: "600m"
    type: Container

上述代码中, spec.limits.default 字段指定了默认的 CPU 和内存限制, spec.limits.defaultRequest 字段指定了默认的 CPU 和内存请求。

2.2 创建无请求和限制值的 Pod 对象
apiVersion: v1
kind: Pod
metadata:
  name: ha-nginx-no-requests-limits-pod
spec:
  containers:
  - name: ha-nginx-no-requests-limits-c-1
    image: nginx:1.10.1
    ports:
    - containerPort: 80

操作步骤如下:
1. 将上述两个 YAML 文件分别保存,例如 limit_range.yaml default_pod.yaml
2. 先使用 kubectl create -f limit_range.yaml 创建 LimitRange 对象。
3. 再使用 kubectl create -f default_pod.yaml 创建 Pod 对象。
4. 运行以下命令检查 Pod 是否使用了默认值:

kubectl describe pod ha-nginx-no-requests-limits-pod
3. Pod 的最小和最大 CPU 及内存约束定义

可以使用 LimitRange 对象定义 Pod 在其生命周期内可接收的最小和最大 CPU 及内存约束。

3.1 创建带有最小和最大资源值的 LimitRange 对象
apiVersion: v1
kind: LimitRange
metadata:
  name: ha-limit-range-min-max
spec:
  limits:
  - max:
      cpu: "500m"
      memory: 500Mi
    min:
      cpu: "100m"
      memory: 100Mi
    type: Container
3.2 测试违反约束的 Pod 创建

使用之前的 ha-resource-quota-failure-pod Pod 对象,其 CPU 请求为 600m ,内存请求为 600Mi ,超过了 LimitRange 对象定义的最大值,因此创建会失败。

4. 无显式 CPU 和内存请求及限制的 Pod 创建情况

创建无显式 CPU 和内存请求及限制的 Pod 时,有两种情况:

情况 描述 结果
命名空间无资源配额 由于没有资源配额可被违反,Pod 创建将成功,其请求和限制值由准入控制器或 LimitRange 对象指定的默认值决定。 Pod 成功创建
命名空间有资源配额 Pod 是否能创建取决于分配给它的默认值是否违反资源配额的聚合限制。如果不违反,Pod 将成功创建;否则,创建失败。 可能成功或失败
5. Pod 优先级的概念及应用

Pod 优先级定义了 Pod 的优先级,Kubernetes 控制器会按定义的优先级顺序调度 Pod,优先级高的 Pod 先被调度。

5.1 创建 PriorityClass 对象
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: ha-high-priority
value: 100
globalDefault: false
description: "This priority class is for important pods."

上述代码中, value 字段决定优先级,值越高优先级越高; globalDefault 字段指定是否为默认优先级类。

5.2 创建关联优先级类的 Pod 对象
apiVersion: v1
kind: Pod
metadata:
  name: ha-high-priority-pod
spec:
  containers:
  - name: ha-high-priority-pod-c-1
    image: nginx:1.10.1
  priorityClassName: ha-high-priority

操作步骤如下:
1. 将上述两个 YAML 文件分别保存,例如 priority_class.yaml priority_pod.yaml
2. 使用 kubectl create -f priority_class.yaml 创建 PriorityClass 对象。
3. 使用 kubectl create -f priority_pod.yaml 创建 Pod 对象。
4. 运行以下命令检查优先级信息:

kubectl get priorityclass
kubectl get pod ha-high-priority-pod -o custom-columns='POD_NAME:.metadata.name, PRIORITY_CLASS_NAME:.spec.priorityClassName, PRIORITY_VALUE:.spec.priority'
6. Pod 优先级的其他应用场景
6.1 确保特定 Pod 先被删除

可以创建两个优先级类 POD_HIGH POD_LOW ,将 POD_LOW 优先级类附加到需要先删除的 Pod 上。

6.2 删除现有 PriorityClass 对象的影响

删除正在被运行中的 Pod 引用的 PriorityClass 对象,不会影响这些运行中的 Pod,但新的 Pod 不能使用已删除的 PriorityClass 对象的名称。

7. 低优先级 Pod 的删除和调度

如果 Kubernetes 控制器无法调度高优先级 Pod,调度器会搜索可移除的低优先级 Pod,以便为高优先级 Pod 腾出资源。低优先级 Pod 不会立即被驱逐,如果指定了 spec.terminationGracePeriodSeconds 值,Pod 将在宽限期结束后被驱逐。建议将低优先级 Pod 的 spec.terminationGracePeriodSeconds 值设置得较低,以便快速进行低优先级 Pod 的驱逐和高优先级 Pod 的调度。

8. Taints 和 Tolerations 的概念及应用

Taints 和 Tolerations 用于避免某些 Pod 被调度到某些节点上。可以给节点添加污点(Taint),只有能容忍该污点的 Pod 才能被调度到该节点上。

8.1 给节点添加污点
kubectl taint nodes ha-node tk1=tv1:NoSchedule

上述命令给名为 ha-node 的节点添加了一个污点。

8.2 给 Pod 添加容忍度
tolerations:
- key: "tk1"
  operator: "Equal"
  value: "tv1"
  effect: "NoSchedule"

上述代码指定 Pod 能容忍键为 tk1 、值为 tv1 、效果为 NoSchedule 的污点。需要注意的是,Pod 上存在匹配的容忍度并不保证它会被调度到带有匹配污点的节点上,Kubernetes 调度器还会进行额外检查。

9. Taints 和 Tolerations 的匹配规则
Taint Key-Value Toleration Key-Value Explanation
tk1=tv1 key: “tk1”, operator: “Equal”, value: “tv1” 匹配,因为操作符为 Equal 且键值对匹配
tk1=tv1 key: “tk2”, operator: “Equal”, value: “tv2” 不匹配,因为操作符为 Equal 但键值对不匹配
tk1=tv1 key: “tk1”, operator: “Exists” 匹配,因为操作符为 Exists 时不需要值字段
tk1=tv1, tk2=tv2, tk3=tv3 key: “”, operator: “Exists” 匹配所有类型的污点,因为操作符为 Exists 且键字段无值时为全局容忍度
10. 污点的移除

可以通过在 kubectl taint 命令末尾追加减号( - )来移除污点。例如,移除之前添加的污点:

kubectl taint nodes ha-node tk1=tv1:NoSchedule-
11. Taints 和 Tolerations 的不同效果

Taints 和 Tolerations 的 effect 字段有三种值:
- NoSchedule :如果 Pod 的容忍度不匹配节点的污点,Pod 不应被调度到该节点。
- PreferNoSchedule :如果 Pod 的容忍度不匹配节点的污点,Pod “最好” 不被调度到该节点,但调度器认为必要时仍可调度。
- NoExecute :效果与 NoSchedule 相同,但如果添加了具有 NoExecute 效果的污点,且 Pod 没有匹配的容忍度,运行中的 Pod 会被从节点驱逐。

12. 节点上多个污点的情况

一个节点可以有多个污点,只有能容忍所有污点的 Pod 才能被调度到该节点上。以下是一个多污点和容忍度的示例:

12.1 给节点添加多个污点
kubectl taint nodes ha-node tk1=tv1:NoSchedule
kubectl taint nodes ha-node tk2=tv2:NoSchedule
12.2 创建具有相应容忍度的 Pod 对象
apiVersion: v1
kind: Pod
metadata:
  name: ha-taint-toleration-pod-1
spec:
  containers:
  - name: ha-taint-toleration-pod-c-1
    image: nginx:1.10.1
  tolerations:
  - key: "tk1"
    operator: "Equal"
    value: "tv1"
    effect: "NoSchedule"
  - key: "tk2"
    operator: "Equal"
    value: "tv2"
    effect: "NoSchedule"

此 Pod 能容忍节点上的两个污点,因此可以被调度到该节点上。

12.3 负向示例
kubectl taint nodes ha-node tk1=tv1:NoSchedule
kubectl taint nodes ha-node tk2=tv2:NoSchedule
kubectl taint nodes ha-node tk3=tv3:NoExecute
apiVersion: v1
kind: Pod
metadata:
  name: ha-taint-toleration-pod-2
spec:
  containers:
  - name: ha-taint-toleration-pod-c-1
    image: nginx:1.10.1
  tolerations:
  - key: "tk1"
    operator: "Equal"
    value: "tv1"
    effect: "NoSchedule"
  - key: "tk2"
    operator: "Equal"
    value: "tv2"
    effect: "NoSchedule"

此 Pod 不能容忍节点上的第三个污点,因此不能被调度到该节点上。

通过以上介绍,我们详细了解了 Kubernetes 集群中 Pod 资源管理、调度策略以及 Taints 和 Tolerations 的相关知识和操作方法,这些技术可以帮助我们更高效地管理和利用集群资源。

Kubernetes 集群中 Pod 资源管理与调度策略详解

13. Pod 资源管理与调度的综合应用流程

为了更清晰地展示在 Kubernetes 集群中进行 Pod 资源管理和调度的整体流程,我们可以用 mermaid 流程图来表示:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px

    A([开始创建 Pod]):::startend --> B{资源请求是否合理?}:::decision
    B -->|是| C{是否违反资源配额?}:::decision
    B -->|否| D(调度失败: 资源请求过高):::process
    C -->|否| E{是否有默认资源设置?}:::decision
    C -->|是| F(调度失败: 违反资源配额):::process
    E -->|是| G(使用默认资源创建 Pod):::process
    E -->|否| H(按无显式资源请求处理):::process
    H --> I{命名空间有无资源配额?}:::decision
    I -->|有| J{默认值是否违反配额?}:::decision
    I -->|无| K(成功创建 Pod):::process
    J -->|否| K
    J -->|是| F
    G --> L{是否指定优先级?}:::decision
    L -->|是| M(按优先级调度 Pod):::process
    L -->|否| N(按默认规则调度 Pod):::process
    M --> O{高优先级 Pod 调度失败?}:::decision
    O -->|是| P(寻找低优先级 Pod 移除):::process
    O -->|否| Q(成功调度 Pod):::process
    P --> R(低优先级 Pod 宽限期结束后驱逐):::process
    R --> Q
    N --> Q
    Q --> S([结束]):::startend
    D --> S
    F --> S

这个流程图展示了从创建 Pod 开始,经过资源请求检查、资源配额检查、默认资源设置、优先级调度等一系列步骤,最终决定 Pod 是否能成功调度的完整过程。

14. 实际案例分析

假设我们有一个 Kubernetes 集群,其中有一个节点 ha-node 配备了优化的 GPU 处理器,我们希望只有需要 GPU 处理的 Pod 才能被调度到该节点上。

14.1 节点设置

首先,我们给 ha-node 节点添加一个污点:

kubectl taint nodes ha-node hardware=GPU:NoSchedule

这个命令给节点添加了一个键为 hardware 、值为 GPU 、效果为 NoSchedule 的污点。

14.2 Pod 设置

然后,我们创建一个需要 GPU 处理的 Pod,并为其添加容忍度:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: gpu-enabled-image
  tolerations:
  - key: "hardware"
    operator: "Equal"
    value: "GPU"
    effect: "NoSchedule"

这个 Pod 可以容忍 ha-node 节点的污点,因此可以被调度到该节点上。

14.3 验证调度

我们可以使用以下命令来验证 Pod 是否被正确调度到了 ha-node 节点上:

kubectl get pod gpu-pod -o wide

如果输出中显示 ha-node 为该 Pod 的所在节点,则说明调度成功。

15. 常见问题及解决方法

在进行 Pod 资源管理和调度过程中,可能会遇到一些常见问题,以下是一些问题及对应的解决方法:

问题描述 可能原因 解决方法
Pod 调度失败,提示资源请求过高 请求的 CPU 或内存超过节点可用资源 调整 Pod 的资源请求,使其在节点可用资源范围内
Pod 调度失败,提示违反资源配额 Pod 的资源请求超过了命名空间的资源配额限制 调整 Pod 的资源请求,或者增加命名空间的资源配额
低优先级 Pod 未及时被驱逐 spec.terminationGracePeriodSeconds 值设置过高 降低低优先级 Pod 的 spec.terminationGracePeriodSeconds
Pod 未按预期调度到指定节点 容忍度设置不正确或调度器进行了额外检查 检查 Pod 的容忍度设置是否与节点的污点匹配,查看调度器的日志进行进一步排查
16. 总结

通过对 Kubernetes 集群中 Pod 资源管理和调度策略的详细介绍,我们了解到在创建 Pod 时,需要考虑资源请求的合理性、资源配额的限制、默认资源的设置以及 Pod 的优先级等因素。同时,Taints 和 Tolerations 机制为我们提供了一种灵活的方式来控制 Pod 的调度,确保特定的 Pod 可以被调度到特定的节点上。

在实际应用中,我们可以根据集群的实际情况和业务需求,合理配置 Pod 的资源和调度策略,提高集群资源的利用率,保障关键业务的顺利运行。例如,对于重要的业务 Pod,可以设置较高的优先级,确保在资源紧张时优先得到调度;对于有特殊硬件需求的 Pod,可以通过 Taints 和 Tolerations 机制将其调度到合适的节点上。

通过综合运用这些技术和策略,我们能够更高效地管理 Kubernetes 集群,为企业的应用提供稳定、可靠的运行环境。

第三方支付功能的技术人员;尤其适合从事电商、在线教育、SaaS类项目开发的工程师。; 使用场景及目标:① 实现微信支付宝的Native、网页/APP等主流支付方式接入;② 掌握支付过程中关键的安全机制如签名验签、证书管理敏感信息保护;③ 构建完整的支付闭环,包括下单、支付、异步通知、订单状态更新、退款对账功能;④ 通过定时任务处理内容支付超时概要状态不一致问题:本文详细讲解了Java,提升系统健壮性。; 阅读应用接入支付宝和建议:建议结合官方文档沙微信支付的全流程,涵盖支付产品介绍、开发环境搭建箱环境边学边练,重点关注、安全机制、配置管理、签名核心API调用及验签逻辑、异步通知的幂等处理实际代码实现。重点异常边界情况;包括商户号AppID获取、API注意生产环境中的密密钥证书配置钥安全接口调用频率控制、使用官方SDK进行支付。下单、异步通知处理、订单查询、退款、账单下载等功能,并深入解析签名验签、加密解密、内网穿透等关键技术环节,帮助开发者构建安全可靠的支付系统。; 适合人群:具备一定Java开发基础,熟悉Spring框架和HTTP协议,有1-3年工作经验的后端研发人员或希望快速掌握第三方支付集成的开发者。; 使用场景及目标:① 实现微信支付Native模式支付宝PC网页支付的接入;② 掌握支付过程中核心的安全机制如签名验签、证书管理、敏感数据加密;③ 处理支付结果异步通知、订单状态核对、定时任务补偿、退款及对账等生产级功能; 阅读建议:建议结合文档中的代码示例官方API文档同步实践,重点关注支付流程的状态一致性控制、幂等性处理和异常边界情况,建议在沙箱环境中完成全流程测试后再上线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值