一、StorageClass 动态 PV(存储类)⭐
1. 概念
StorageClass 是集群级别资源,定义 PV 动态创建策略,实现动态供给 PV。
静态 PV:管理员手动一个个创建 PV; 动态 PV:用户仅创建 PVC,指定
storageClassName,StorageClass 调用provisioner制备器自动创建 PV 并完成绑定,不用人工维护 PV,大规模集群主流方案。
类比:柜子 (StorageClass),需要充电宝 (PV) 直接自动弹出,不用人工预先准备。
核心字段
- provisioner(制备器):决定调用哪个存储插件,负责真正去后端存储创建 PV。
- nfs-subdir‑external‑provisioner 标识:
fuseim.pri/ifs,NFS 动态供给 - 云厂商 EBS、AzureDisk、Ceph‑RBD 都有对应 provisioner
- nfs-subdir‑external‑provisioner 标识:
reclaimPolicy:回收策略(Retain / Delete),PVC 删除后底层存储如何处理volumeBindingMode:卷绑定模式Immediate:PVC 创建立刻创建并绑定 PV(NFS 等不依赖节点存储)WaitForFirstConsumer:等待 Pod 创建才去创建 PV,本地盘、块存储常用
allowVolumeExpansion:是否支持 PVC 存储容量在线扩容
NFS 动态供给组件
nfs‑client‑provisioner:是一个 Deployment 控制器 Pod
- 持续 watch 监听 PVC 资源事件;
- 需要 ServiceAccount、ClusterRole、ClusterRoleBinding RBAC 权限;
- 收到 PVC 请求,在 NFS 共享目录自动创建子目录,自动生成 PV。
NFS 动态供给完整流程
- 部署 nfs‑client‑provisioner(SA+RBAC+Deployment+StorageClass)
- 用户创建 PVC,指定
storageClassName: nfs‑storage - provisioner 监听到 PVC 事件
- 在 NFS 服务端共享目录自动生成子目录
pvc‑xxxx - 自动创建 PV,PVC 与 PV 完成 Bound 绑定
- Pod 挂载 PVC 使用存储
⚠重要注意:
- StorageClass 是集群资源,没有 namespace
provisioner名称,StorageClass 里面的值必须和 Deployment 环境变量PROVISIONER_NAME完全一致- NFS 服务端共享目录权限要放开,否则 provisioner 无法新建子目录
两种使用场景
- Deployment 使用动态存储:手动写 PVC,Pod 挂载 PVC,多个 Pod 可以共用一套 PVC(NFS 支持 RWX)
- 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 种方式(⭐)
nodeName: 节点名:直接强制指定节点名称,绕过调度器;nodeSelector:简单标签硬匹配;nodeAffinity节点亲和性(硬 / 软);- 污点 + 容忍度: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)。
核心字段
- provisioner(制备器):指定存储驱动,决定用什么后端存储 (NFS/Ceph/ 云盘 EBS)
- nfs 社区制备器:
fuseim.pri/ifs(nfs‑subdir‑external‑provisioner)
- nfs 社区制备器:
reclaimPolicy:PV 回收策略Retain / DeletevolumeBindingMode:卷绑定模式Immediate:PVC 创建完立刻创建 PV 绑定(NFS 这类与节点无关存储)
allowVolumeExpansion:是否支持 PVC 扩容。
nfs‑client‑provisioner 是一个 Deployment 控制器 Pod:
- watch 监听集群 PVC 资源事件
- PVC 指定对应 storageClassName,控制器收到请求
- 在 NFS 共享目录自动创建子目录,自动生成 PV,完成 PVC 绑定。
- 需要 ServiceAccount、ClusterRole、Role、RBAC 权限,才能操作 PV/PVC/Events。
NFS 动态存储完整组件清单
- StorageClass 存储类定义
- ServiceAccount:provisioner Pod 使用的账号
- ClusterRole + ClusterRoleBinding:集群级权限,管理 PV/PVC/SC/events
- Role + RoleBinding:用于 leader 选举,操作 endpoints 锁
- Deployment (nfs‑client‑provisioner):真正干活的控制器,挂载 NFS 共享目录
使用方式
- Deployment 使用动态 PV:直接写 PVC,指定
storageClassName: nfs‑storage - 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:
Equal:key、value、effect 三者必须全部完全匹配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 种方式(⭐)
- nodeName:直接写节点名字,强制调度,绕过调度器;
spec:
nodeName: k8s‑node01
- nodeSelector:简单标签硬匹配
- nodeAffinity 节点亲和性:软硬策略、权重、丰富操作符
- podAffinity /podAntiAffinity Pod 亲和 / 反亲和:基于其他 Pod 标签调度(把 Pod 调度到和别的 Pod 相同 / 不同节点)
- Taint + Tolerations 污点容忍:解除节点排斥,配合亲和性使用。
五、汇总
- StorageClass 作用?动态 PV 工作流程? StorageClass 实现 PV 动态供给,不用管理员手动创建 PV; 流程:用户创建 PVC,指定 storageClassName → provisioner 控制器监听 PVC 事件 → 自动创建底层存储资源、自动生成 PV → PV 与 PVC 自动绑定。
- StatefulSet 使用 volumeClaimTemplates 注意点? volumeClaimTemplates 为每一个 Pod 自动生成独立 PVC;删除 StatefulSet 不会删除 PVC,防止丢失业务数据;需要手动删除 PVC 才会触发 PV 回收。
- nodeAffinity 中 required 和 preferred 区别?
- required(硬亲和):强制条件,不满足 Pod 直接 Pending,无法调度;
- preferred(软亲和):优先满足,不满足也能调度其他节点,不会 Pending,weight 设置优先级。 后缀 IgnoredDuringExecution:仅调度生效,节点标签后期变化不会驱逐已经运行的 Pod。
- Taint 三种 effect 区别?
- NoSchedule:仅阻止新 Pod 调度;已运行 Pod 不受影响
- PreferNoSchedule:尽量避免,非强制
- NoExecute:新 Pod 禁止调度,同时驱逐节点上不匹配容忍度的正在运行 Pod。
- 污点与容忍度和节点亲和的区别? 节点亲和:Pod 主动挑选节点(正向,我要去哪里); 污点:节点排斥 Pod;容忍度:Pod 拿到许可,消除排斥(反向,允许我可以去被排斥的节点)。容忍度不会主动选择节点,仅解除排斥,一般要配合亲和性使用。
- 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