7. K8s 动态 PV 与节点亲和性及污点与容忍度
本文最后更新于28 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、StorageClass 动态 PV(存储类)⭐

1. 概念

StorageClass 是集群级别资源,定义 PV 动态创建策略,实现动态供给 PV。

静态 PV:管理员手动一个个创建 PV; 动态 PV:用户仅创建 PVC,指定storageClassName,StorageClass 调用provisioner制备器自动创建 PV 并完成绑定,不用人工维护 PV,大规模集群主流方案。

类比:柜子 (StorageClass),需要充电宝 (PV) 直接自动弹出,不用人工预先准备。

核心字段

  1. provisioner(制备器):决定调用哪个存储插件,负责真正去后端存储创建 PV。
    • nfs-subdir‑external‑provisioner 标识:fuseim.pri/ifs,NFS 动态供给
    • 云厂商 EBS、AzureDisk、Ceph‑RBD 都有对应 provisioner
  2. reclaimPolicy:回收策略(Retain / Delete),PVC 删除后底层存储如何处理
  3. volumeBindingMode:卷绑定模式
    • Immediate:PVC 创建立刻创建并绑定 PV(NFS 等不依赖节点存储)
    • WaitForFirstConsumer:等待 Pod 创建才去创建 PV,本地盘、块存储常用
  4. allowVolumeExpansion:是否支持 PVC 存储容量在线扩容

NFS 动态供给组件nfs‑client‑provisioner:是一个 Deployment 控制器 Pod

  • 持续 watch 监听 PVC 资源事件;
  • 需要 ServiceAccount、ClusterRole、ClusterRoleBinding RBAC 权限;
  • 收到 PVC 请求,在 NFS 共享目录自动创建子目录,自动生成 PV。

NFS 动态供给完整流程

  1. 部署 nfs‑client‑provisioner(SA+RBAC+Deployment+StorageClass)
  2. 用户创建 PVC,指定storageClassName: nfs‑storage
  3. provisioner 监听到 PVC 事件
  4. 在 NFS 服务端共享目录自动生成子目录pvc‑xxxx
  5. 自动创建 PV,PVC 与 PV 完成 Bound 绑定
  6. Pod 挂载 PVC 使用存储

⚠重要注意:

  1. StorageClass 是集群资源,没有 namespace
  2. provisioner名称,StorageClass 里面的值必须和 Deployment 环境变量PROVISIONER_NAME完全一致
  3. NFS 服务端共享目录权限要放开,否则 provisioner 无法新建子目录

两种使用场景

  1. Deployment 使用动态存储:手动写 PVC,Pod 挂载 PVC,多个 Pod 可以共用一套 PVC(NFS 支持 RWX)
  2. StatefulSet 使用动态存储:volumeClaimTemplates(卷申领模板)

StatefulSet 的volumeClaimTemplates会为每一个 Pod 自动生成独立 PVC;pod‑0、pod‑1 各自一套 PVC/PV,数据隔离。 ⚠删除 StatefulSet/Pod不会自动删除 PVC(保护数据);需要手动删除 PVC,才会触发 PV 清理。

回收策略为Delete:只有删除 PVC 才会自动删除 PV 以及后端存储目录;只删工作负载 PVC 保留。

常用命令

kubectl get sc                         #查看存储类
kubectl get pv pvc
kubectl describe sc nfs‑storage

二、Pod 调度策略:节点亲和 nodeAffinity

作用:基于节点标签控制 Pod 调度到哪些节点;分为硬亲和、软亲和。

给节点打标签

#打标签
kubectl label nodes k8s‑node01 disktype=ssd
#查看节点标签
kubectl get nodes --show‑labels
#删除标签,key后加"-"
kubectl label nodes k8s‑node01 disktype‑

匹配操作符

表格

操作符含义
In节点标签值在列表之内
NotIn节点标签值不在列表之内
Exists节点存在该标签,不关心 value
DoesNotExist节点不存在该标签
Gt / Lt数值大于、小于

1. 硬亲和 requiredDuringSchedulingIgnoredDuringExecution

强制约束!必须满足条件才能调度;没有符合条件节点,Pod 一直 Pending。 IgnoredDuringExecution 含义:Pod 已经运行之后,节点标签后续发生变化,不会驱逐已经运行的 Pod,只在调度阶段生效。

yaml 片段示例

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values: ["ssd"]

2. 软亲和 preferredDuringSchedulingIgnoredDuringExecution

优先满足,不是强制。优先调度到符合条件节点;没有满足条件节点,Pod 依然可以调度其他节点,不会 Pending。

  • weight权重:1‑100,数字越大优先级越高。

yaml 片段示例

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      preference:
        matchExpressions:
        - key: gpu
          operator: In
          values: ["nvidia8090"]
    - weight: 80
      preference:
        matchExpressions:
        - key: gpu
          operator: In
          values: ["nvidia6090"]

nodeSelector(节点选择器,简单版硬调度)

最简单强制调度,只能精确 key=value 完全匹配,没有 In/Exists 复杂运算符。不匹配则 Pod Pending。

spec:
  nodeSelector:
    disktype: ssd

nodeSelector VS nodeAffinity

  • nodeSelector:简单键值对硬匹配,功能弱;
  • nodeAffinity:支持 In/NotIn/Exists,支持软硬两种策略,权重,企业生产首选。

✨Pod 调度到指定节点的 4 种方式(⭐)

  1. nodeName: 节点名:直接强制指定节点名称,绕过调度器;
  2. nodeSelector:简单标签硬匹配;
  3. nodeAffinity节点亲和性(硬 / 软);
  4. 污点 + 容忍度:taint+tolerations,允许 Pod 调度到被污点隔离的节点;

拓展:还有 podAffinity/podAntiAffinity(Pod 亲和与反亲和,基于其他 Pod 标签调度)。


三、污点 Taint & 容忍度 Tolerations⭐

污点 Taint:定义在【节点】上,排斥 Pod; 容忍度 Tolerations:定义在【Pod】上,表示 Pod 可以接受该污点。

逻辑:节点打污点,普通 Pod 没有容忍度,就不能调度到此节点;Pod 配置对应容忍度才允许调度。

污点格式

key=value:effect effect 有三种效果:

表格

effect说明
NoSchedule仅影响新 Pod 调度;不容忍的新 Pod 不能调度;已经运行在节点上的 Pod 不会被驱逐。
PreferNoSchedule尽量避免调度到此节点

day7 K8s 动态 PV 与节点亲和性及污点与容忍度 复习资料

一、StorageClass 动态 PV⭐重点

1. 概念

StorageClass(存储类)是集群级别资源,实现PV 动态供给。

静态 PV:管理员手动一个个创建 PV; 动态 PV:用户只创建 PVC,StorageClass 调用 provisioner 制备器自动创建 PV 并完成绑定,不用人工维护 PV。

类比:充电宝柜机 (StorageClass),用户 (PVC) 申请,柜子自动弹出充电宝 (PV)。

核心字段

  1. provisioner(制备器):指定存储驱动,决定用什么后端存储 (NFS/Ceph/ 云盘 EBS)
    • nfs 社区制备器:fuseim.pri/ifs(nfs‑subdir‑external‑provisioner)
  2. reclaimPolicy:PV 回收策略 Retain / Delete
  3. volumeBindingMode:卷绑定模式
    • Immediate:PVC 创建完立刻创建 PV 绑定(NFS 这类与节点无关存储)
  4. allowVolumeExpansion:是否支持 PVC 扩容。

nfs‑client‑provisioner 是一个 Deployment 控制器 Pod:

  1. watch 监听集群 PVC 资源事件
  2. PVC 指定对应 storageClassName,控制器收到请求
  3. 在 NFS 共享目录自动创建子目录,自动生成 PV,完成 PVC 绑定。
  4. 需要 ServiceAccount、ClusterRole、Role、RBAC 权限,才能操作 PV/PVC/Events。

NFS 动态存储完整组件清单

  1. StorageClass 存储类定义
  2. ServiceAccount:provisioner Pod 使用的账号
  3. ClusterRole + ClusterRoleBinding:集群级权限,管理 PV/PVC/SC/events
  4. Role + RoleBinding:用于 leader 选举,操作 endpoints 锁
  5. Deployment (nfs‑client‑provisioner):真正干活的控制器,挂载 NFS 共享目录

使用方式

  1. Deployment 使用动态 PV:直接写 PVC,指定storageClassName: nfs‑storage
  2. StatefulSet 使用动态 PV:使用volumeClaimTemplates 卷申请模板,每个 Pod 自动生成独立 PVC。
volumeClaimTemplates:
- metadata:
    name: mysql-data
    annotations:
      volume.beta.kubernetes.io/storage-class: "nfs‑storage"
  spec:
    accessModes: [ "ReadWriteOnce" ]
    resources:
      requests:
        storage: 200Mi

⚠重要:删除 StatefulSet 不会自动删除 PVC!为了保护数据;必须手动删除 PVC,才会触发 PV 清理。

  • SC 回收策略Delete:删除 PVC,自动删 PV 和 NFS 子目录;
  • SC 回收策略Retain:删除 PVC,PV 保留,需要管理员手动删 PV、清理存储目录。

核心命令

kubectl get sc                  #查看storageclass
kubectl get pv,pvc,pod
kubectl describe sc nfs‑storage

二、Pod 调度:节点亲和性 nodeAffinity

作用:基于节点标签控制 Pod 调度到哪些节点。

1. 两种节点亲和

表格

类型字段说明
硬亲和(强制)requiredDuringSchedulingIgnoredDuringExecution必须满足条件,没有匹配节点,Pod 直接 Pending,不调度
软亲和(优先)preferredDuringSchedulingIgnoredDuringExecution优先调度满足条件节点;没有满足的节点,Pod 依然可以调度其他节点,不会 Pending;支持weight权重 1‑100,数字越大优先级越高

后缀IgnoredDuringExecution含义:Pod 已经运行起来之后,节点标签发生变化,不会驱逐已经运行的 Pod,只在调度创建 Pod 的时候生效。

操作符(matchExpressions)

表格

操作符含义
In节点标签值在列表内
NotIn节点标签值不在列表内
Exists节点存在这个标签,不关心 value
DoesNotExist节点不存在该标签
Gt / Lt数值大于、小于

nodeSelector(简单节点选择器)

  • 最简单硬调度,key‑value完全严格匹配,没有权重、没有复杂操作符。
  • 节点标签必须完全等于配置,否则 Pod Pending。
spec:
  nodeSelector:
    disktype: ssd

nodeSelector 对比 nodeAffinity nodeSelector:只能完全相等匹配; nodeAffinity:支持 In/NotIn/Exists/Gt/Lt、支持软硬策略、支持权重,功能更强大。

给节点打标签命令:

kubectl label nodes k8s‑node01 disktype=ssd
kubectl get nodes --show‑labels
#删除标签 key‑
kubectl label nodes k8s‑node01 disktype‑

nodeAffinity 示例片段

spec:
  affinity:
    nodeAffinity:
      #硬亲和,强制必须满足
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values: ["ssd"]
      #软亲和,优先
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight:100
        preference:
          matchExpressions:
          - key: gpu
            operator: In
            values: ["nvidia8090"]

三、污点 Taint & 容忍度 Tolerations⭐

污点 Taint:定义在【节点】上,排斥 Pod; 容忍度 Tolerations:定义在【Pod】上,允许 Pod 容忍节点污点。

逻辑:节点打污点,普通 Pod 会被排斥;只有 Pod 配置对应容忍度,才允许调度到此节点。

污点格式

key=value:effect

effect 三种效果

表格

effect作用
NoSchedule只影响新 Pod 调度;不能容忍污点的新 Pod 不允许调度;已经在节点运行的 Pod 不受任何影响。
PreferNoSchedule尽量不要调度,非强制,实在没有节点还是可以调度过来。
NoExecute最严格;不仅新 Pod 不能调度;已经运行在此节点且不容忍该污点的 Pod 会被驱逐(赶走)。

注意:master 控制平面节点默认自带污点,阻止业务 Pod 调度到 master。

污点操作命令

#给节点增加污点
kubectl taint node k8s‑node01 gpu=nvidia4090:NoSchedule
#删除污点,末尾加 "-"
kubectl taint node k8s‑node01 gpu=nvidia4090:NoSchedule‑
#查看节点污点
kubectl describe node k8s‑node01 | grep Taints

Pod 容忍度 Tolerations

两种 operator:

  1. Equal:key、value、effect 三者必须全部完全匹配
  2. Exists:只匹配 key+effect,忽略 value 值(常用于 master 节点容忍)

yaml 片段示例

spec:
  tolerations:
  - key: "gpu"
    operator: "Equal"
    value: "nvidia4090"
    effect: "NoSchedule"

容忍 master 节点污点示例(Exists)

tolerations:
- key: "node‑role.kubernetes.io/master"
  operator: "Exists"
  effect: "NoSchedule"

⚠重点区分:

  • 节点亲和性 nodeAffinity:Pod 主动挑选想要去哪些节点(正向选择)
  • 污点 Taint:节点拒绝不想要的 Pod;容忍度 Tolerations:Pod 获得许可,可以突破节点排斥(反向放行) 想要强制 Pod 跑到某特殊节点:亲和性 + 容忍度两者配合;容忍只是消除排斥,不会主动选择节点。

四、Pod 调度到指定节点的 5 种方式(⭐)

  1. nodeName:直接写节点名字,强制调度,绕过调度器;
spec:
  nodeName: k8s‑node01
  1. nodeSelector:简单标签硬匹配
  2. nodeAffinity 节点亲和性:软硬策略、权重、丰富操作符
  3. podAffinity /podAntiAffinity Pod 亲和 / 反亲和:基于其他 Pod 标签调度(把 Pod 调度到和别的 Pod 相同 / 不同节点)
  4. Taint + Tolerations 污点容忍:解除节点排斥,配合亲和性使用。

五、汇总

  1. StorageClass 作用?动态 PV 工作流程? StorageClass 实现 PV 动态供给,不用管理员手动创建 PV; 流程:用户创建 PVC,指定 storageClassName → provisioner 控制器监听 PVC 事件 → 自动创建底层存储资源、自动生成 PV → PV 与 PVC 自动绑定。
  2. StatefulSet 使用 volumeClaimTemplates 注意点? volumeClaimTemplates 为每一个 Pod 自动生成独立 PVC;删除 StatefulSet 不会删除 PVC,防止丢失业务数据;需要手动删除 PVC 才会触发 PV 回收。
  3. nodeAffinity 中 required 和 preferred 区别?
  • required(硬亲和):强制条件,不满足 Pod 直接 Pending,无法调度;
  • preferred(软亲和):优先满足,不满足也能调度其他节点,不会 Pending,weight 设置优先级。 后缀 IgnoredDuringExecution:仅调度生效,节点标签后期变化不会驱逐已经运行的 Pod。
  1. Taint 三种 effect 区别?
  • NoSchedule:仅阻止新 Pod 调度;已运行 Pod 不受影响
  • PreferNoSchedule:尽量避免,非强制
  • NoExecute:新 Pod 禁止调度,同时驱逐节点上不匹配容忍度的正在运行 Pod。
  1. 污点与容忍度和节点亲和的区别? 节点亲和:Pod 主动挑选节点(正向,我要去哪里); 污点:节点排斥 Pod;容忍度:Pod 拿到许可,消除排斥(反向,允许我可以去被排斥的节点)。容忍度不会主动选择节点,仅解除排斥,一般要配合亲和性使用。
  2. Pod 调度到指定节点有哪几种方式? nodeName、nodeSelector、nodeAffinity、podAffinity/podAntiAffinity、taint+tolerations。

六、核心命令汇总

#存储类
kubectl get sc
kubectl describe sc xxx

#节点标签
kubectl label nodes <node> key=value
kubectl get nodes --show‑labels

#污点
kubectl taint node xxx key=val:effect
kubectl describe node xxx | grep Taints

#排错看调度事件
kubectl describe pod xxx
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇