下面用“节点排斥 / Pod 选择 / Pod 靠近 / Pod 分散”这个角度来理解 Kubernetes 中的 Taints 污点、Tolerations 容忍、Affinity 亲和、Anti-Affinity 反亲和。
| 机制 | 英文 | 作用对象 | 核心语义 | 典型场景 |
|---|---|---|---|---|
| 污点 | Taints | Node | 节点主动排斥某些 Pod | 专用节点、GPU 节点、故障节点、控制面节点 |
| 容忍 | Tolerations | Pod | Pod 允许自己被调度到带有某些污点的节点 | 数据库上专用节点、GPU Pod 上 GPU 节点 |
| 节点亲和 | NodeAffinity | Pod -> Node | Pod 想调度到某些节点,或避免某些节点 | SSD 节点、GPU 机型、特定可用区、特定 OS |
| Pod 亲和 | PodAffinity | Pod -> Pod | Pod 想调度到某些已有 Pod 所在的拓扑域附近 | 缓存和业务同可用区、同机架 |
| Pod 反亲和 | PodAntiAffinity | Pod -> Pod | Pod 不想和其他 Pod 调度到同一拓扑域 | 多副本分散到不同节点、不同可用区 |
可以打个比方:
Taint 是设置在 Node 上的属性。
它的意思是:
这个节点上带有某种“污点”,默认情况下,某些 Pod 不允许调度到该节点。
Taint 写在 Node 的 spec.taints 中:
apiVersion: v1
kind: Node
metadata:
name: node-1
spec:
taints:
- key: "app"
value: "redis"
effect: "NoSchedule"通常我们用 kubectl 操作:
kubectl taint nodes node-1 app=redis:NoSchedule语法:
key=value:Effect如果没有 value:
key:Effect例如:
kubectl taint nodes node-1 gpu:NoScheduleTaint 有三种 effect:
| Effect | 含义 | 对新 Pod | 对已有 Pod |
|---|---|---|---|
NoSchedule | 不调度 | 新 Pod 如果没有对应 Toleration,不能调度到该节点 | 已有 Pod 不受影响 |
PreferNoSchedule | 尽量不调度 | 调度器会尽量避开,但实在没有别的节点时也可以调度 | 不受影响 |
NoExecute | 不调度并驱逐 | 新 Pod 如果没有对应 Toleration,不能调度 | 已有 Pod 如果没有对应 Toleration,会被驱逐 |
NoSchedule最常见的类型。
例子:
kubectl taint nodes node-1 redis=true:NoSchedule效果:
node-1。node-1 上的 Pod 不会被驱逐。适合场景:
PreferNoSchedule软性排斥。
例子:
kubectl taint nodes node-1 large-memory:PreferNoSchedule效果:
适合场景:
NoExecute最强类型。
不仅新 Pod 不能调度,已有 Pod 也会被驱逐,除非它们容忍了这个污点。
常见于节点故障:
node.kubernetes.io/not-ready:NoExecute
node.kubernetes.io/unreachable:NotReady
node.kubernetes.io/disk-pressure:NoExecute
node.kubernetes.io/memory-pressure:NoExecute例子:
kubectl taint nodes node-1 bad-node:NoExecute效果:
node-1。node-1 上已有 Pod 如果没有 Toleration,会被驱逐。适合场景:
一些系统会自带或自动添加 Taints。
kubectl cordon node-1等价于给节点加上:
node.kubernetes.io/unschedulable:NoSchedule效果:
节点异常时可能出现:
node.kubernetes.io/not-ready:NoExecute效果:
node.kubernetes.io/unreachable:NoExecute例如:
node.kubernetes.io/disk-pressure:NoExecute
node.kubernetes.io/memory-pressure:NoExecute
node.kubernetes.io/pid-pressure:NoExecute现代 Kubernetes 控制面节点通常有类似污点:
node-role.kubernetes.io/control-plane:NoSchedule旧版本可能是:
node-role.kubernetes.io/master:NoSchedule目的:
Toleration 是写在 Pod 上的属性。
它的意思是:
这个 Pod 可以容忍节点上的某些 Taint,因此可以调度到带这些 Taint 的节点。
Toleration 写在 Pod 的 spec.tolerations 中:
通常我们不会手写 Node 对象,而是在 Deployment、StatefulSet、Pod 模板里写 Toleration:
字段含义:
| 字段 | 含义 |
|---|---|
key | 匹配 Taint 的 key |
operator | 匹配方式,通常是 Equal 或 Exists |
value |
生产环境建议显式写清楚:
常见匹配方式:
Taint:
app=redis:NoScheduleToleration:
含义:
只容忍
app=redis:NoSchedule这个污点。
Taint:
app=redis:NoSchedule也可以是:
app=other:NoScheduleToleration:
- key: "app"
operator
含义:
只要 key 是
app,effect 是NoSchedule,不管 value 是什么,都容忍。
Toleration:
- operator: "Exists"
effect: "NoSchedule"含义:
容忍所有 effect 为
NoSchedule的 Taint。
这个比较宽泛,一般用于特殊系统组件,不建议普通业务随意使用。
Toleration:
- operator: "Exists"含义:
容忍所有 Taint。
非常危险,一般只用于极少数系统级组件,普通业务不要这样写。
如果一个节点有多个会影响调度的 Taints,Pod 必须能容忍所有这些 Taints,否则不能调度上去。
例如节点有:
dedicated=redis:NoSchedule
disktype=ssd:NoSchedulePod 需要:
否则调度器会认为该 Pod 不能调度到这些节点。
tolerationSeconds 主要对 NoExecute 有效。
场景:
节点 NotReady 后,Kubernetes 会给节点加上:
node.kubernetes.io/not-ready:NoExecute如果 Pod 不想立即被驱逐,可以写:
含义:
节点 NotReady 或 Unreachable 后,这个 Pod 最多还能在节点上运行 300 秒,之后才被驱逐。
适合场景:
你希望 Redis 只运行在指定节点上,其他普通 Pod 不要跑到这些节点。
kubectl taint nodes node-1 node-2 redis-dedicated=true:NoSchedule普通 Pod 没有 Toleration,所以不能调度到 node-1、node-2。
解释:
tolerations:允许这个 Pod 调度到带 redis-dedicated=true:NoSchedule 的节点。nodeAffinity:要求这个 Pod 必须调度到 redis=true 且 disktype=ssd 的节点。 污点,所以不会调度到这些节点。这就是典型组合:
Taint 负责“排除别人”,NodeAffinity 负责“选择自己该去的节点”。
GPU 节点比较贵,通常不希望普通 Pod 占用。
效果:
gpu-node-1。gpu-node-1。某个关键 Pod 希望节点短暂 NotReady 时不要立即迁移。
含义:
Affinity 分为两大类:
它们都支持:
字段名字虽然很长,但含义很固定:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution可以拆解理解:
| 字段 | 含义 |
|---|---|
requiredDuringScheduling | 调度阶段必须满足 |
preferredDuringScheduling | 调度阶段尽量满足 |
IgnoredDuringExecution | Pod 运行后,不因为节点/Pod 变化而强制执行 |
NodeAffinity 是根据 节点标签 来选择节点。
你可以把它理解成高级版 nodeSelector。
nodeSelector 只支持简单精确匹配:
nodeSelector:
disktype: ssd而 NodeAffinity 支持:
InNotInExistsDoesNotExistGt含义:
Pod 必须调度到满足条件的节点,否则 Pending。
例子:
要求 Pod 必须调度到 disktype=ssd 的节点。
含义:
disktype=ssd 的节点。同一个 nodeSelectorTerms 下的多个 matchExpressions 是 AND 关系。
例子:
要求:
os=linuxdisktype=ssdzone=us-east-1a含义:
必须同时满足这三个条件。
nodeSelectorTerms 数组里多个 term 是 OR 关系。
例子:
满足下面任一条件即可:
disktype=ssddisktype=nvme含义:
SSD 节点可以,NVMe 节点也可以。
含义:
调度器会尽量满足,但如果没有满足条件的节点,也可以调度到其他节点。
例子:
希望优先调度到 SSD 节点,但如果没有 SSD 节点,也可以调度到 HDD 节点。
含义:
disktype=ssd 的节点,权重 100。us-east-1a 可用区,权重 50。weight 范围是 1 到 100,越大优先级越高。
PodAffinity 是根据 已经调度出去的 Pod 的标签 来决定新 Pod 调度到哪里。
它经常和 topologyKey 一起使用。
意思是:
如果某个拓扑域内已经有我喜欢的 Pod,那么我也尽量去那个拓扑域。
拓扑域可以理解为:
rack、datacentertopologyKey 是一个节点标签 key。
常见值:
| topologyKey | 含义 |
|---|---|
kubernetes.io/hostname | 节点主机名,通常可以表示“同一台节点” |
topology.kubernetes.io/zone | 可用区 |
topology.kubernetes.io/region | Region |
rack | 自定义机架标签 |
|
例如:
topologyKey: kubernetes.io/hostname表示:
以节点 hostname 作为拓扑边界。
如果两个节点 hostname 相同,它们属于同一个拓扑域。实际上一台节点通常 hostname 唯一,所以这通常等价于“同一台节点”。
例如:
topologyKey: topology.kubernetes.io/zone表示:
以可用区作为拓扑边界。
同一个可用区内的不同节点属于同一个拓扑域。
例子:
你有一个 cache 服务,现在要部署 api 服务。
你希望 api 必须和某个 cache Pod 在同一个可用区,以减少网络延迟。
含义:
app=cache Pod 的可用区。api 必须调度到这些可用区中的某一个。cache Pod 所在可用区都不可调度,api 会 Pending。例子:
希望 api 尽量和 cache 在同一个可用区,但如果不行也可以调度到其他可用区。
含义:
api 调度到已经有 cache 的可用区。例如:
order-serviceredis-cache如果跨可用区访问,延迟可能更高。
可以写:
效果:
order-service尽量和 Redis 在同一个可用区。
例如:
例如:
PodAntiAffinity 是 PodAffinity 的反面。
PodAffinity:
我想和某些 Pod 靠近。
PodAntiAffinity:
我不想和某些 Pod 太靠近。
通常用于:
例子:
你部署 3 个 Redis 副本,希望它们不要在同一台节点上。
含义:
app=redis 的 Pod 不能调度到已经有 app=redis Pod 的节点。topologyKey: kubernetes.io/hostname 表示以节点 hostname 为边界。如果集群只有 2 台可用节点,那么第 3 个 Redis Pod 会 Pending。
如果你希望“尽量分散,但不要强制”,可以使用 preferred。
含义:
生产环境更推荐这种软性反亲和,除非你明确要保证强分散。
你希望 Redis 副本不要都落在同一个可用区。
含义:
尽量让 Redis 副本分散到不同可用区。
如果集群只有 2 个可用区,但你有 3 个副本,那么至少有一个可用区会有 2 个副本。
更稳的做法:
含义:
如果资源充足,效果是:
每个 Redis 副本都尽量在不同节点、不同可用区。
你有两台节点:
node-1
node-2希望:
kubectl taint nodes node-1 node-2 redis-dedicated=true:NoSchedule让 Redis Pod 可以调度到带有 redis-dedicated=true:NoSchedule 的节点。
其他普通 Pod 如果没有这个 Toleration,就不能调度到 node-1、node-2。
让 Redis Pod 只调度到:
redis=true
disktype=ssd的节点。
让两个 Redis 副本不能在同一台节点。
因为 replicas: 2,所以最终会分别调度到 node-1 和 node-2。
Taint:
这个节点不希望某些 Pod 来。
Affinity:
这个 Pod 希望去某些地方,或者靠近某些 Pod。
例如:
nodeSelector 或 NodeAffinity。Taint + Redis Pod 的 Toleration。。错误示范:
kubectl taint nodes node-1 disktype=ssd:NoSchedule然后希望某些 Pod 调度到 SSD 节点。
这不对。
Taint 的含义是:
排斥没有 Toleration 的 Pod。
不是:
选择某个标签的节点。
正确做法:
kubectl label nodes node-1 disktype=ssdPod 里用:
或者简单场景:
nodeSelector:
disktype: ssd如果还要独占节点,再加 Taint:
kubectl taint nodes node-1 ssd-dedicated=true:NoScheduleTaint:
节点说:我不欢迎某类 Pod。Toleration:
Pod 说:我容忍你这个污点。NodeAffinity:
Pod 说:我想去有某个标签的节点。PodAffinity:
Pod 说:我想去某个 Pod 所在的拓扑域。PodAntiAffinity:
Pod 说:我不想去某个 Pod 所在的拓扑域。例如:
requiredDuringSchedulingIgnoredDuringExecution或 Taint 的:
NoSchedule
NoExecute特点:
适合:
风险:
例如:
preferredDuringSchedulingIgnoredDuringExecution或 Taint 的:
PreferNoSchedule特点:
适合:
风险:
调度器选择节点时,大致会经历:
会考虑:
nodeSelector 是否匹配。NodeAffinity required 是否满足。PodAffinity required 是否满足。PodAntiAffinity required 是否满足。会考虑:
NodeAffinity preferred。PodAffinity preferred。PodAntiAffinity preferred。PreferNoSchedule Taint。如果没有任何可行节点,Pod 会进入:
Pendingkubectl describe pod 通常会看到类似事件:
0/3 nodes are available: 1 node(s) had taint {app=redis:NoSchedule}, that the pod didn't tolerate.或者:
0/3 nodes are available: 3 node(s) didn't match Pod's node affinity.或者:
0/3 nodes are available: 1 node(s) had one pod that anti-affinity doesn't allow.目标:
方案:
Pod:
目标:
方案:
Pod:
目标:
方案:
目标:
订单服务 Pod:
效果:
订单服务尽量调度到已有 Redis 的可用区。
目标:
方案:
kubectl cordon node-1等价于加:
node.kubernetes.io/unschedulable:NoSchedule维护完成后:
kubectl uncordon node-1如果还要驱逐已有 Pod:
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data目标:
Pod:
错误:
kubectl taint nodes node-1 disktype=ssd:NoSchedule然后期望某个 Pod 调度到 SSD 节点。
正确:
选择节点用:
nodeSelector或:
nodeAffinityTaint 用于排斥,不用于选择。
现象:
Pod Pending。
事件:
0/3 nodes are available: 1 node(s) had taint {app=redis:NoSchedule}, that the pod didn't tolerate.原因:
节点有:
app=redis:NoSchedule但 Pod 没有对应:
例如:
如果只有 1 个可用节点,但有 3 个 Redis 副本,那么后续副本会 Pending。
解决:
preferredDuringSchedulingIgnoredDuringExecution。例如你写了:
topologyKey: topology.kubernetes.io/zone但节点没有这个标签。
可能导致:
检查:
kubectl get nodes --show-labels节点有:
dedicated=redis:NoSchedule
disktype=ssd:NoSchedulePod 只容忍:
可能仍然不能调度,因为还有 disktype=ssd:NoSchedule 没被容忍。
需要把所有影响调度的 Taint 都容忍掉。
例如:
tolerations:
- operator: "Exists"这会容忍所有 Taint。
风险:
普通业务建议精确匹配:
用:
nodeSelector或:
nodeAffinity例如:
nodeSelector:
disktype: ssd复杂一点用 NodeAffinity。
用:
Taint + Toleration例如:
kubectl taint nodes node-1 redis-dedicated=true:NoSchedulePod:
用:
podAffinity例如:
用:
podAntiAffinity例如:
用:
NoExecute配合:
tolerationSeconds调度判断:
redis-dedicated=true:NoSchedule?
disktype=ssd 满足。app=redis Pod,则不满足软性反亲和,会降低分数。可以这样记:
Taint 是节点说“不欢迎”。
Toleration 是 Pod 说“我无所谓,我可以上去”。
NodeAffinity 是 Pod 说“我想去某类节点”。
PodAffinity 是 Pod 说“我想和某个 Pod 住同一个拓扑域”。
PodAntiAffinity 是 Pod 说“我不想和某个 Pod 住同一个拓扑域”。再简化:
污点:排斥。
容忍:豁免。
节点亲和:选节点。
Pod 亲和:靠近 Pod。
Pod 反亲和:远离 Pod。生产中最常见组合:
专用节点:Taint + Toleration + NodeAffinity
高可用副本:PodAntiAffinity
低延迟服务:PodAffinity
节点故障:NoExecute + tolerationSecondsapiVersion: v1
kind: Pod
metadata:
name: redis
spec:
tolerations:
- key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"
containers:
- name: redis
image: redis:7apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
tolerations:
- key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"
containers:
- name: redis
image: redis:7tolerations:
- key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"
tolerationSeconds: 300| 匹配 Taint 的 value |
effect | 匹配 Taint 的 effect,例如 NoSchedule |
tolerationSeconds | 主要针对 NoExecute,表示节点异常后最多允许运行多少秒 |
key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"- key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"tolerations:
- key: "dedicated"
operator: "Equal"
value: "redis"
effect: "NoSchedule"
- key: "disktype"
operator: "Equal"
value: "ssd"
effect: "NoSchedule"tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300kubectl label nodes node-1 node-2 redis=true
kubectl label nodes node-1 node-2 disktype=ssdapiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
tolerations:
- key: "redis-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "redis"
operator: "In"
values:
- "true"
- key: "disktype"
operator: "In"
values:
- "ssd"
containers:
- name: redis
image: redis:7kubectl label nodes gpu-node-1 nvidia.com/gpu.present=true
kubectl taint nodes gpu-node-1 nvidia.com/gpu-dedicated=true:NoScheduleapiVersion: apps/v1
kind: Deployment
metadata:
name: inference
spec:
replicas: 1
selector:
matchLabels:
app: inference
template:
metadata:
labels:
app: inference
spec:
tolerations:
- key: "nvidia.com/gpu-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "nvidia.com/gpu.present"
operator: "In"
values:
- "true"
containers:
- name: inference
image: inference-server:latest
resources:
limits:
nvidia.com/gpu: 1apiVersion: v1
kind: Pod
metadata:
name: critical-service
spec:
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
containers:
- name: app
image: my-app:latestapiVersion: v1
kind: Pod
metadata:
name: app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "disktype"
operator: "In"
values:
- "ssd"
containers:
- name: app
image: nginxaffinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/os"
operator: "In"
values:
- "linux"
- key: "disktype"
operator: "In"
values:
- "ssd"
- key: "topology.kubernetes.io/zone"
operator: "In"
values:
- "us-east-1a"affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "disktype"
operator: "In"
values:
- "ssd"
- matchExpressions:
- key: "disktype"
operator: "In"
values:
- "nvme"apiVersion: v1
kind: Pod
metadata:
name: app
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: "disktype"
operator: "In"
values:
- "ssd"
- weight: 50
preference:
matchExpressions:
- key: "topology.kubernetes.io/zone"
operator: "In"
values:
- "us-east-1a"
containers:
- name: app
image: nginx| 自定义机房标签 |
apiVersion: v1
kind: Pod
metadata:
name: api
labels:
app: api
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: cache
topologyKey: topology.kubernetes.io/zone
containers:
- name: api
image: my-api:latestapiVersion: v1
kind: Pod
metadata:
name: api
labels:
app: api
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: cache
topologyKey: topology.kubernetes.io/zone
containers:
- name: api
image: my-api:latestaffinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zoneapiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zoneaffinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zonekubectl label nodes node-1 node-2 redis=true
kubectl label nodes node-1 node-2 disktype=ssdapiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 2
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
# 1. 允许调度到带 redis-dedicated 污点的节点
tolerations:
- key: "redis-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"
# 2. 节点选择 + 副本分散
affinity:
# 必须调度到 redis=true 且 disktype=ssd 的节点
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "redis"
operator: "In"
values:
- "true"
- key: "disktype"
operator: "In"
values:
- "ssd"
# 两个 redis 副本尽量/必须分散到不同节点
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7
ports:
- containerPort: 6379tolerations:
- key: "redis-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "redis"
operator: "In"
values:
- "true"
- key: "disktype"
operator: "In"
values:
- "ssd"podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostnamePodAntiAffinity。nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "disktype"
operator: "In"
values:
- "ssd"kubectl label nodes gpu-node-1 nvidia.com/gpu.present=true
kubectl taint nodes gpu-node-1 nvidia.com/gpu-dedicated=true:NoScheduletolerations:
- key: "nvidia.com/gpu-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "nvidia.com/gpu.present"
operator: "In"
values:
- "true"kubectl label nodes db-node-1 db=true
kubectl taint nodes db-node-1 db-dedicated=true:NoScheduletolerations:
- key: "db-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "db"
operator: "In"
values:
- "true"affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zoneaffinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zonetolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300tolerations:
- key: "app"
operator: "Equal"
value: "redis"
effect: "NoSchedule"podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname- key: "dedicated"
operator: "Equal"
value: "redis"
effect: "NoSchedule"- key: "redis-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"tolerations:
- key: "redis-dedicated"
operator: "Equal"
value: "true"
effect: "NoSchedule"affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: topology.kubernetes.io/zoneaffinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostnameNode:
labels:
disktype: ssd
zone: us-east-1a
taints:
- redis-dedicated=true:NoSchedule
Pod:
tolerations:
- redis-dedicated=true:NoSchedule
affinity:
nodeAffinity:
required: disktype=ssd
preferred: zone=us-east-1a
podAntiAffinity:
preferred: app=redis 不要同 hostname