在 Kubernetes 中,亲和性和反亲和性可以用来控制 Pod 如何调度到节点上,而污点和容忍则可以用来控制节点是否接受 Pod。在本文中,我们将介绍 Kubernetes 中亲和性、反亲和性、污点和容忍的概念,并提供一些示例来帮助读者更好地理解这些概念。
亲和性和反亲和性
亲和性和反亲和性可以用来控制 Pod 如何调度到节点上。亲和性表示 Pod 要求与特定的节点调度在一起,反亲和性表示 Pod 不希望与特定的节点调度在一起。
在 Kubernetes 中,亲和性和反亲和性可以通过 NodeSelector 和 NodeAffinity 两种方式来实现。NodeSelector 适用于简单的场景,只能指定一个键值对,而 NodeAffinity 可以进行更复杂的匹配。
以下是一个使用 NodeSelector 来控制 Pod 调度的示例:
代码语言:javascript复制apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
disk: ssd
这个示例中,我们指定 Pod 只能调度到具有标签 disk=ssd 的节点上。
以下是一个使用 NodeAffinity 来控制 Pod 调度的示例:
代码语言:javascript复制apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disk-type
operator: In
values:
- ssd
这个示例中,我们指定 Pod 只能调度到具有标签 disk-type=ssd 的节点上。
反亲和性与亲和性的实现类似,只是条件相反。以下是一个使用 NodeAffinity 和 NotIn 进行反亲和性的示例:
代码语言:javascript复制apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: disk-type
operator: NotIn
values:
- hdd
weight: 1
这个示例中,我们指定 Pod 不希望调度到具有标签 disk-type=hdd 的节点上。
污点和容忍
污点和容忍可以用来控制节点是否接受 Pod。污点是一个节点的属性,用于表示节点上可能存在的问题,例如磁盘空间不足、内存不足等。容忍则是 Pod 的属性,用于表示 Pod 是否愿意在存在某些污点的节点上运行。
在 Kubernetes 中,污点和容忍可以通过 Taints 和 Tolerations 两种方式来实现。Taints 是节点的属性,用于标记节点上存在的问题,而 Tolerations 是 Pod 的属性,用于表示 Pod 是否愿意在存在某些 Taints 的节点上运行。
以下是一个使用 Taints 和 Tolerations 来控制 Pod 调度的示例:
代码语言:javascript复制apiVersion: v1
kind: Node
metadata:
name: node-1
spec:
taints:
- key: disk-pressure
value: "true"
effect: NoSchedule
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: disk-pressure
operator: Equal
value: "true"
effect: NoSchedule
这个示例中,我们在 node-1 节点上添加了一个 Taints,用于表示节点存在磁盘压力问题,该 Taints 的效果为 NoSchedule,表示不会有新的 Pod 调度到该节点上。然后我们在 Pod 中添加了一个 Tolerations,表示 Pod 愿意在存在 disk-pressure=Ture 的节点上运行。
除了 NoSchedule,还有 NoExecute 和 PreferNoSchedule 两种 Taints 的效果。NoExecute 表示节点上已经存在的 Pod 不受影响,但不会再有新的 Pod 调度到该节点上;PreferNoSchedule 表示尽量不要在节点上调度新的 Pod,但不是绝对的,如果没有其他可用节点,Pod 还是会调度到该节点上。
以下是一个使用 Taints 和 Tolerations 来控制 Pod 调度的示例,其中有多个 Taints 和 Tolerations:
代码语言:javascript复制apiVersion: v1
kind: Node
metadata:
name: node-1
spec:
taints:
- key: disk-pressure
value: "true"
effect: NoSchedule
- key: gpu
value: "nvidia"
effect: NoSchedule
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: disk-pressure
operator: Equal
value: "true"
effect: NoSchedule
- key: gpu
operator: Exists
effect: NoSchedule
- key: custom-taint
operator: Exists
effect: PreferNoSchedule
这个示例中,我们在 node-1 节点上添加了两个 Taints,一个用于表示节点存在磁盘压力问题,另一个用于表示节点有 Nvidia GPU,两个 Taints 的效果均为 NoSchedule。然后我们在 Pod 中添加了三个 Tolerations,一个用于容忍 disk-pressure=Ture 的节点,一个用于容忍存在 Nvidia GPU 的节点,一个用于容忍存在自定义 Taints 的节点,但只是尽量不要调度到该节点上。
在使用亲和性、反亲和性、污点和容忍时需要注意以下几点:
- 亲和性和反亲和性只在节点之间的调度时生效,而不会影响 Pod 内容器之间的调度。
- 污点和容忍只在 Pod 调度时生效,而不会影响已经在节点上运行的 Pod。
- 在实际使用中,需要根据具体的业务场景和需求来设置亲和性、反亲和性、污点和容忍,避免影响系统的性能和可用性。
- 可以使用 kubectl describe node 命令来查看节点上的 Taints 和 Pod 中的 Tolerations。
- 可以使用 kubectl taint node 命令来添加或删除节点上的 Taints。
- 可以使用 kubectl annotate pod 命令来添加或删除 Pod 中的 Tolerations。
- 可以使用 kubectl get nodes --show-labels 命令来查看节点的标签。
- 可以使用 kubectl label node 命令来为节点添加或删除标签。
总之,亲和性、反亲和性、污点和容忍是 Kubernetes 中非常重要的概念,可以用来控制 Pod 的调度和部署,提高系统的可用性和性能。在实际应用中,需要根据具体的业务需求来合理设置这些参数,以达到最优的效果。