From e0b1ba3ef15b74aa9cf9d9312b1a973f7c8f94d6 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Mon, 11 Jan 2021 14:54:20 +0800 Subject: [PATCH 1/2] Normalize current translation --- .../scheduling-eviction/assign-pod-node.md | 353 ++++++++++-------- 1 file changed, 204 insertions(+), 149 deletions(-) diff --git a/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md index 2318f59e6f..47ebab9f88 100644 --- a/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -5,6 +5,10 @@ weight: 50 --- - -你可以约束一个 {{< glossary_tooltip text="Pod" term_id="pod" >}} 只能在特定的 {{< glossary_tooltip text="Node(s)" term_id="node" >}} 上运行,或者优先运行在特定的节点上。有几种方法可以实现这点,推荐的方法都是用[标签选择器](/zh/docs/concepts/overview/working-with-objects/labels/)来进行选择。通常这样的约束不是必须的,因为调度器将自动进行合理的放置(比如,将 pod 分散到节点上,而不是将 pod 放置在可用资源不足的节点上等等),但在某些情况下,你可能需要更多控制 pod 停靠的节点,例如,确保 pod 最终落在连接了 SSD 的机器上,或者将来自两个不同的服务且有大量通信的 pod 放置在同一个可用区。 +你可以约束一个 {{< glossary_tooltip text="Pod" term_id="pod" >}} 只能在特定的 +{{< glossary_tooltip text="节点" term_id="node" >}} 上运行,或者优先运行在特定的节点上。 +有几种方法可以实现这点,推荐的方法都是用 +[标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/)来进行选择。 +通常这样的约束不是必须的,因为调度器将自动进行合理的放置(比如,将 Pod 分散到节点上, +而不是将 Pod 放置在可用资源不足的节点上等等)。但在某些情况下,你可能需要进一步控制 +Pod 停靠的节点,例如,确保 Pod 最终落在连接了 SSD 的机器上,或者将来自两个不同的服务 +且有大量通信的 Pods 被放置在同一个可用区。 @@ -38,36 +48,34 @@ additional labels as well). The most common usage is one key-value pair. --> `nodeSelector` 是节点选择约束的最简单推荐形式。`nodeSelector` 是 PodSpec 的一个字段。 -它包含键值对的映射。为了使 pod 可以在某个节点上运行,该节点的标签中必须包含这里的每个键值对(它也可以具有其他标签)。最常见的用法的是一对键值对。 +它包含键值对的映射。为了使 pod 可以在某个节点上运行,该节点的标签中 +必须包含这里的每个键值对(它也可以具有其他标签)。 +最常见的用法的是一对键值对。 - 让我们来看一个使用 `nodeSelector` 的例子。 -### 步骤零:先决条件 - - +### 步骤零:先决条件 + 本示例假设你已基本了解 Kubernetes 的 Pod 并且已经[建立一个 Kubernetes 集群](/zh/docs/setup/)。 ### 步骤一:添加标签到节点 {#attach-labels-to-node} - - 执行 `kubectl get nodes` 命令获取集群的节点名称。 -选择一个你要增加标签的节点,然后执行 `kubectl label nodes =` +选择一个你要增加标签的节点,然后执行 +`kubectl label nodes =` 命令将标签添加到你所选择的节点上。 例如,如果你的节点名称为 'kubernetes-foo-node-1.c.a-robinson.internal' 并且想要的标签是 'disktype=ssd',则可以执行 @@ -76,17 +84,17 @@ Run `kubectl get nodes` to get the names of your cluster's nodes. Pick out the o -你可以通过重新运行 `kubectl get nodes --show-labels`,查看节点当前具有了所指定的标签来验证它是否有效。 +你可以通过重新运行 `kubectl get nodes --show-labels`, +查看节点当前具有了所指定的标签来验证它是否有效。 你也可以使用 `kubectl describe node "nodename"` 命令查看指定节点的标签完整列表。 ### 步骤二:添加 nodeSelector 字段到 Pod 配置中 - 选择任何一个你想运行的 Pod 的配置文件,并且在其中添加一个 nodeSelector 部分。 例如,如果下面是我的 pod 配置: @@ -106,7 +114,6 @@ spec: - 然后像下面这样添加 nodeSelector: {{< codenew file="pods/pod-nginx.yaml" >}} @@ -118,19 +125,19 @@ verify that it worked by running `kubectl get pods -o wide` and looking at the "NODE" that the Pod was assigned to. --> 当你之后运行 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 命令, -Pod 将会调度到将标签添加到的节点上。你可以通过运行 `kubectl get pods -o wide` 并查看分配给 pod 的 “NODE” 来验证其是否有效。 +Pod 将会调度到将标签添加到的节点上。 +你可以通过运行 `kubectl get pods -o wide` 并查看分配给 pod 的 “NODE” 来验证其是否有效。 -## 插曲:内置的节点标签 {#built-in-node-labels} - - -除了你[附加](#attach-labels-to-node)的标签外,节点还预先填充了一组标准标签。这些标签是 +## 插曲:内置的节点标签 {#built-in-node-labels} + +除了你[添加](#attach-labels-to-node)的标签外,节点还预先填充了一组标准标签。 +这些标签有: * [`kubernetes.io/hostname`](/zh/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-hostname) * [`failure-domain.beta.kubernetes.io/zone`](/zh/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesiozone) @@ -148,31 +155,34 @@ The value of these labels is cloud provider specific and is not guaranteed to be For example, the value of `kubernetes.io/hostname` may be the same as the Node name in some environments and a different value in other environments. --> -这些标签的值是特定于云供应商的,因此不能保证可靠。例如,`kubernetes.io/hostname` 的值在某些环境中可能与节点名称相同,但在其他环境中可能是一个不同的值。 +这些标签的值是特定于云供应商的,因此不能保证可靠。 +例如,`kubernetes.io/hostname` 的值在某些环境中可能与节点名称相同, +但在其他环境中可能是一个不同的值。 {{< /note >}} -## 节点隔离/限制 - - +## 节点隔离/限制 {#node-isolation-restriction} -向 Node 对象添加标签可以将 pod 定位到特定的节点或节点组。这可以用来确保指定的 pod 只能运行在具有一定隔离性,安全性或监管属性的节点上。当为此目的使用标签时,强烈建议选择节点上的 kubelet 进程无法修改的标签键。这可以防止受感染的节点使用其 kubelet 凭据在自己的 Node 对象上设置这些标签,并影响调度器将工作负载调度到受感染的节点。 +向 Node 对象添加标签可以将 pod 定位到特定的节点或节点组。 +这可以用来确保指定的 Pod 只能运行在具有一定隔离性,安全性或监管属性的节点上。 +当为此目的使用标签时,强烈建议选择节点上的 kubelet 进程无法修改的标签键。 +这可以防止受感染的节点使用其 kubelet 凭据在自己的 Node 对象上设置这些标签, +并影响调度器将工作负载调度到受感染的节点。 - -`NodeRestriction` 准入插件防止 kubelet 使用 `node-restriction.kubernetes.io/` 前缀设置或修改标签。要使用该标签前缀进行节点隔离: +`NodeRestriction` 准入插件防止 kubelet 使用 `node-restriction.kubernetes.io/` +前缀设置或修改标签。要使用该标签前缀进行节点隔离: - 1. 检查是否在使用 Kubernetes v1.11+,以便 NodeRestriction 功能可用。 2. 确保你在使用[节点授权](/zh/docs/reference/access-authn-authz/node/)并且已经_启用_ [NodeRestriction 准入插件](/zh/docs/reference/access-authn-authz/admission-controllers/#noderestriction)。 -3. 将 `node-restriction.kubernetes.io/` 前缀下的标签添加到 Node 对象,然后在节点选择器中使用这些标签。例如,`example.com.node-restriction.kubernetes.io/fips=true` 或 `example.com.node-restriction.kubernetes.io/pci-dss=true`。 +3. 将 `node-restriction.kubernetes.io/` 前缀下的标签添加到 Node 对象, + 然后在节点选择器中使用这些标签。 + 例如,`example.com.node-restriction.kubernetes.io/fips=true` 或 + `example.com.node-restriction.kubernetes.io/pci-dss=true`。 -## 亲和与反亲和 - - +## 亲和性与反亲和性 -`nodeSelector` 提供了一种非常简单的方法来将 pod 约束到具有特定标签的节点上。亲和/反亲和功能极大地扩展了你可以表达约束的类型。关键的增强点是 +`nodeSelector` 提供了一种非常简单的方法来将 Pod 约束到具有特定标签的节点上。 +亲和性/反亲和性功能极大地扩展了你可以表达约束的类型。关键的增强点包括: - -1. 语言更具表现力(不仅仅是“完全匹配的 AND”) -2. 你可以发现规则是“软”/“偏好”,而不是硬性要求,因此,如果调度器无法满足该要求,仍然调度该 pod -3. 你可以使用节点上(或其他拓扑域中)的 pod 的标签来约束,而不是使用节点本身的标签,来允许哪些 pod 可以或者不可以被放置在一起。 +1. 语言更具表现力(不仅仅是“对完全匹配规则的 AND”) +2. 你可以发现规则是“软需求”/“偏好”,而不是硬性要求,因此, + 如果调度器无法满足该要求,仍然调度该 Pod +3. 你可以使用节点上(或其他拓扑域中)的 Pod 的标签来约束,而不是使用 + 节点本身的标签,来允许哪些 pod 可以或者不可以被放置在一起。 - -亲和功能包含两种类型的亲和,即“节点亲和”和“pod 间亲和/反亲和”。节点亲和就像现有的 `nodeSelector`(但具有上面列出的前两个好处),然而 pod 间亲和/反亲和约束 pod 标签而不是节点标签(在上面列出的第三项中描述,除了具有上面列出的第一和第二属性)。 +亲和性功能包含两种类型的亲和性,即“节点亲和性”和“Pod 间亲和性/反亲和性”。 +节点亲和性就像现有的 `nodeSelector`(但具有上面列出的前两个好处),然而 +Pod 间亲和性/反亲和性约束 Pod 标签而不是节点标签(在上面列出的第三项中描述, +除了具有上面列出的第一和第二属性)。 -### 节点亲和 - - +### 节点亲和性 {#node-affinity} -节点亲和概念上类似于 `nodeSelector`,它使你可以根据节点上的标签来约束 pod 可以调度到哪些节点。 +节点亲和性概念上类似于 `nodeSelector`,它使你可以根据节点上的标签来约束 +Pod 可以调度到哪些节点。 - -目前有两种类型的节点亲和,分别为 `requiredDuringSchedulingIgnoredDuringExecution` 和 -`preferredDuringSchedulingIgnoredDuringExecution`。你可以视它们为“硬”和“软”,意思是,前者指定了将 pod 调度到一个节点上*必须*满足的规则(就像 `nodeSelector` 但使用更具表现力的语法),后者指定调度器将尝试执行但不能保证的*偏好*。名称的“IgnoredDuringExecution”部分意味着,类似于 `nodeSelector` 的工作原理,如果节点的标签在运行时发生变更,从而不再满足 pod 上的亲和规则,那么 pod 将仍然继续在该节点上运行。将来我们计划提供 `requiredDuringSchedulingRequiredDuringExecution`,它将类似于 `requiredDuringSchedulingIgnoredDuringExecution`,除了它会将 pod 从不再满足 pod 的节点亲和要求的节点上驱逐。 +目前有两种类型的节点亲和性,分别为 `requiredDuringSchedulingIgnoredDuringExecution` 和 +`preferredDuringSchedulingIgnoredDuringExecution`。 +你可以视它们为“硬需求”和“软需求”,意思是,前者指定了将 Pod 调度到一个节点上 +*必须*满足的规则(就像 `nodeSelector` 但使用更具表现力的语法), +后者指定调度器将尝试执行但不能保证的*偏好*。 +名称的“IgnoredDuringExecution”部分意味着,类似于 `nodeSelector` 的工作原理, +如果节点的标签在运行时发生变更,从而不再满足 Pod 上的亲和性规则,那么 Pod +将仍然继续在该节点上运行。 +将来我们计划提供 `requiredDuringSchedulingRequiredDuringExecution`, +它将类似于 `requiredDuringSchedulingIgnoredDuringExecution`, +除了它会将 pod 从不再满足 pod 的节点亲和性要求的节点上驱逐。 - -因此,`requiredDuringSchedulingIgnoredDuringExecution` 的示例将是“仅将 pod 运行在具有 Intel CPU 的节点上”,而 `preferredDuringSchedulingIgnoredDuringExecution` 的示例为“尝试将这组 pod 运行在 XYZ 故障区域,如果这不可能的话,则允许一些 pod 在其他地方运行”。 +因此,`requiredDuringSchedulingIgnoredDuringExecution` 的示例将是 +“仅将 Pod 运行在具有 Intel CPU 的节点上”,而 +`preferredDuringSchedulingIgnoredDuringExecution` 的示例为 +“尝试将这组 Pod 运行在 XYZ 故障区域,如果这不可能的话,则允许一些 +Pod 在其他地方运行”。 - -节点亲和通过 PodSpec 的 `affinity` 字段下的 `nodeAffinity` 字段进行指定。 +节点亲和性通过 PodSpec 的 `affinity` 字段下的 `nodeAffinity` 字段进行指定。 - -下面是一个使用节点亲和的 pod 的实例: +下面是一个使用节点亲和性的 Pod 的实例: {{< codenew file="pods/pod-with-node-affinity.yaml" >}} @@ -276,58 +296,60 @@ This node affinity rule says the pod can only be placed on a node with a label w among nodes that meet that criteria, nodes with a label whose key is `another-node-label-key` and whose value is `another-node-label-value` should be preferred. --> - -此节点亲和规则表示,pod 只能放置在具有标签键为 `kubernetes.io/e2e-az-name` 且 标签值为 `e2e-az1` 或 `e2e-az2` 的节点上。另外,在满足这些标准的节点中,具有标签键为 `another-node-label-key` 且标签值为 `another-node-label-value` 的节点应该优先使用。 +此节点亲和性规则表示,Pod 只能放置在具有标签键 `kubernetes.io/e2e-az-name` +且标签值为 `e2e-az1` 或 `e2e-az2` 的节点上。 +另外,在满足这些标准的节点中,具有标签键为 `another-node-label-key` +且标签值为 `another-node-label-value` 的节点应该优先使用。 - -你可以在上面的例子中看到 `In` 操作符的使用。新的节点亲和语法支持下面的操作符: +你可以在上面的例子中看到 `In` 操作符的使用。新的节点亲和性语法支持下面的操作符: `In`,`NotIn`,`Exists`,`DoesNotExist`,`Gt`,`Lt`。 -你可以使用 `NotIn` 和 `DoesNotExist` 来实现节点反亲和行为,或者使用 -[节点污点](/zh/docs/concepts/scheduling-eviction/taint-and-toleration/)将 pod 从特定节点中驱逐。 +你可以使用 `NotIn` 和 `DoesNotExist` 来实现节点反亲和性行为,或者使用 +[节点污点](/zh/docs/concepts/scheduling-eviction/taint-and-toleration/) +将 Pod 从特定节点中驱逐。 -如果你同时指定了 `nodeSelector` 和 `nodeAffinity`,*两者*必须都要满足,才能将 pod 调度到候选节点上。 - - +如果你同时指定了 `nodeSelector` 和 `nodeAffinity`,*两者*必须都要满足, +才能将 Pod 调度到候选节点上。 -如果你指定了多个与 `nodeAffinity` 类型关联的 `nodeSelectorTerms`,则**如果其中一个** `nodeSelectorTerms` 满足的话,pod将可以调度到节点上。 +如果你指定了多个与 `nodeAffinity` 类型关联的 `nodeSelectorTerms`,则 +**如果其中一个** `nodeSelectorTerms` 满足的话,pod将可以调度到节点上。 -如果你指定了多个与 `nodeSelectorTerms` 关联的 `matchExpressions`,则**只有当所有** `matchExpressions` 满足的话,pod 才会可以调度到节点上。 - - -如果你修改或删除了 pod 所调度到的节点的标签,pod 不会被删除。换句话说,亲和选择只在 pod 调度期间有效。 +如果你指定了多个与 `nodeSelectorTerms` 关联的 `matchExpressions`,则 +**只有当所有** `matchExpressions` 满足的话,Pod 才会可以调度到节点上。 + +如果你修改或删除了 pod 所调度到的节点的标签,Pod 不会被删除。 +换句话说,亲和性选择只在 Pod 调度期间有效。 - -`preferredDuringSchedulingIgnoredDuringExecution` 中的 `weight` 字段值的范围是 1-100。对于每个符合所有调度要求(资源请求,RequiredDuringScheduling 亲和表达式等)的节点,调度器将遍历该字段的元素来计算总和,并且如果节点匹配对应的MatchExpressions,则添加“权重”到总和。然后将这个评分与该节点的其他优先级函数的评分进行组合。总分最高的节点是最优选的。 +`preferredDuringSchedulingIgnoredDuringExecution` 中的 `weight` 字段值的 +范围是 1-100。 +对于每个符合所有调度要求(资源请求、RequiredDuringScheduling 亲和性表达式等) +的节点,调度器将遍历该字段的元素来计算总和,并且如果节点匹配对应的 +MatchExpressions,则添加“权重”到总和。 +然后将这个评分与该节点的其他优先级函数的评分进行组合。 +总分最高的节点是最优选的。 -### pod 间亲和与反亲和 - - +### pod 间亲和性与反亲和性 {#inter-pod-affinity-and-anti-affinity} -pod 间亲和与反亲和使你可以*基于已经在节点上运行的 pod 的标签*来约束 pod 可以调度到的节点,而不是基于节点上的标签。规则的格式为“如果 X 节点上已经运行了一个或多个 满足规则 Y 的pod,则这个 pod 应该(或者在非亲和的情况下不应该)运行在 X 节点”。Y 表示一个具有可选的关联命令空间列表的 LabelSelector;与节点不同,因为 pod 是命名空间限定的(因此 pod 上的标签也是命名空间限定的),因此作用于 pod 标签的标签选择器必须指定选择器应用在哪个命名空间。从概念上讲,X 是一个拓扑域,如节点,机架,云供应商地区,云供应商区域等。你可以使用 `topologyKey` 来表示它,`topologyKey` 是节点标签的键以便系统用来表示这样的拓扑域。请参阅上面[插曲:内置的节点标签](#built-in-node-labels)部分中列出的标签键。 +Pod 间亲和性与反亲和性使你可以 *基于已经在节点上运行的 Pod 的标签* 来约束 +Pod 可以调度到的节点,而不是基于节点上的标签。 +规则的格式为“如果 X 节点上已经运行了一个或多个 满足规则 Y 的 Pod, +则这个 Pod 应该(或者在反亲和性的情况下不应该)运行在 X 节点”。 +Y 表示一个具有可选的关联命令空间列表的 LabelSelector; +与节点不同,因为 Pod 是命名空间限定的(因此 Pod 上的标签也是命名空间限定的), +因此作用于 Pod 标签的标签选择算符必须指定选择算符应用在哪个命名空间。 +从概念上讲,X 是一个拓扑域,如节点、机架、云供应商可用区、云供应商地理区域等。 +你可以使用 `topologyKey` 来表示它,`topologyKey` 是节点标签的键以便系统 +用来表示这样的拓扑域。 +请参阅上面[插曲:内置的节点标签](#built-in-node-labels)部分中列出的标签键。 {{< note >}} -Pod 间亲和与反亲和需要大量的处理,这可能会显著减慢大规模集群中的调度。我们不建议在超过数百个节点的集群中使用它们。 +Pod 间亲和性与反亲和性需要大量的处理,这可能会显著减慢大规模集群中的调度。 +我们不建议在超过数百个节点的集群中使用它们。 {{< /note >}} {{< note >}} -Pod 反亲和需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配 `topologyKey`。如果某些或所有节点缺少指定的 `topologyKey` 标签,可能会导致意外行为。 +Pod 反亲和性需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配 +`topologyKey`。如果某些或所有节点缺少指定的 `topologyKey` 标签,可能会导致意外行为。 {{< /note >}} - -与节点亲和一样,当前有两种类型的 pod 亲和与反亲和,即 `requiredDuringSchedulingIgnoredDuringExecution` 和 -`preferredDuringSchedulingIgnoredDuringExecution`,分别表示“硬性”与“软性”要求。请参阅前面节点亲和部分中的描述。`requiredDuringSchedulingIgnoredDuringExecution` 亲和的一个示例是“将服务 A 和服务 B 的 pod 放置在同一区域,因为它们之间进行大量交流”,而 `preferredDuringSchedulingIgnoredDuringExecution` 反亲和的示例将是“将此服务的 pod 跨区域分布”(硬性要求是说不通的,因为你可能拥有的 pod 数多于区域数)。 +与节点亲和性一样,当前有两种类型的 Pod 亲和性与反亲和性,即 +`requiredDuringSchedulingIgnoredDuringExecution` 和 +`preferredDuringSchedulingIgnoredDuringExecution`,分别表示“硬性”与“软性”要求。 +请参阅前面节点亲和性部分中的描述。 +`requiredDuringSchedulingIgnoredDuringExecution` 亲和性的一个示例是 +“将服务 A 和服务 B 的 Pod 放置在同一区域,因为它们之间进行大量交流”,而 +`preferredDuringSchedulingIgnoredDuringExecution` 反亲和性的示例将是 +“将此服务的 pod 跨区域分布”(硬性要求是说不通的,因为你可能拥有的 +Pod 数多于区域数)。 - -Pod 间亲和通过 PodSpec 中 `affinity` 字段下的 `podAffinity` 字段进行指定。而 pod 间反亲和通过 PodSpec 中 `affinity` 字段下的 `podAntiAffinity` 字段进行指定。 +Pod 间亲和性通过 PodSpec 中 `affinity` 字段下的 `podAffinity` 字段进行指定。 +而 Pod 间反亲和性通过 PodSpec 中 `affinity` 字段下的 `podAntiAffinity` 字段进行指定。 - -### Pod 使用 pod 亲和 的示例: +### Pod 使用 pod 亲和性 的示例: {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} @@ -402,22 +442,34 @@ label having key "security" and value "S2".) See the for many more examples of pod affinity and anti-affinity, both the `requiredDuringSchedulingIgnoredDuringExecution` flavor and the `preferredDuringSchedulingIgnoredDuringExecution` flavor. --> - -在这个 pod 的 affinity 配置定义了一条 pod 亲和规则和一条 pod 反亲和规则。在此示例中,`podAffinity` 配置为 `requiredDuringSchedulingIgnoredDuringExecution`,然而 `podAntiAffinity` 配置为 `preferredDuringSchedulingIgnoredDuringExecution`。pod 亲和规则表示,仅当节点和至少一个已运行且有键为“security”且值为“S1”的标签的 pod 处于同一区域时,才可以将该 pod 调度到节点上。(更确切的说,如果节点 N 具有带有键 `topology.kubernetes.io/zone` 和某个值 V 的标签,则 pod 有资格在节点 N 上运行,以便集群中至少有一个节点具有键 `topology.kubernetes.io/zone` 和值为 V 的节点正在运行具有键“security”和值“S1”的标签的 pod。)pod 反亲和规则表示,如果节点已经运行了一个具有键“security”和值“S2”的标签的 pod,则该 pod 不希望将其调度到该节点上。(如果 `topologyKey` 为 `topology.kubernetes.io/zone`,则意味着当节点和具有键“security”和值“S2”的标签的 pod 处于相同的区域,pod 不能被调度到该节点上。)查阅[设计文档](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)来获取更多 pod 亲和与反亲和的样例,包括 `requiredDuringSchedulingIgnoredDuringExecution` +在这个 Pod 的亲和性配置定义了一条 Pod 亲和性规则和一条 Pod 反亲和性规则。 +在此示例中,`podAffinity` 配置为 `requiredDuringSchedulingIgnoredDuringExecution`, +然而 `podAntiAffinity` 配置为 `preferredDuringSchedulingIgnoredDuringExecution`。 +Pod 亲和性规则表示,仅当节点和至少一个已运行且有键为“security”且值为“S1”的标签 +的 Pod 处于同一区域时,才可以将该 Pod 调度到节点上。 +(更确切的说,如果节点 N 具有带有键 `topology.kubernetes.io/zone` 和某个值 V 的标签, +则 Pod 有资格在节点 N 上运行,以便集群中至少有一个节点具有键 +`topology.kubernetes.io/zone` 和值为 V 的节点正在运行具有键“security”和值 +“S1”的标签的 pod。) +Pod 反亲和性规则表示,如果节点已经运行了一个具有键“security”和值“S2”的标签的 Pod, +则该 pod 不希望将其调度到该节点上。 +(如果 `topologyKey` 为 `topology.kubernetes.io/zone`,则意味着当节点和具有键 +“security”和值“S2”的标签的 Pod 处于相同的区域,Pod 不能被调度到该节点上。) +查阅[设计文档](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md) +以获取 Pod 亲和性与反亲和性的更多样例,包括 +`requiredDuringSchedulingIgnoredDuringExecution` 和 `preferredDuringSchedulingIgnoredDuringExecution` 两种配置。 -Pod 亲和与反亲和的合法操作符有 `In`,`NotIn`,`Exists`,`DoesNotExist`。 - - +Pod 亲和性与反亲和性的合法操作符有 `In`,`NotIn`,`Exists`,`DoesNotExist`。 -原则上,`topologyKey` 可以是任何合法的标签键。然而,出于性能和安全原因,topologyKey 受到一些限制: +原则上,`topologyKey` 可以是任何合法的标签键。 +然而,出于性能和安全原因,topologyKey 受到一些限制: - -1. 对于亲和与 `requiredDuringSchedulingIgnoredDuringExecution` 要求的 pod 反亲和,`topologyKey` 不允许为空。 -2. 对于 `requiredDuringSchedulingIgnoredDuringExecution` 要求的 pod 反亲和,准入控制器 `LimitPodHardAntiAffinityTopology` 被引入来限制 `topologyKey` 不为 `kubernetes.io/hostname`。如果你想使它可用于自定义拓扑结构,你必须修改准入控制器或者禁用它。 -3. 对于 `preferredDuringSchedulingIgnoredDuringExecution` 要求的 pod 反亲和,空的 `topologyKey` 被解释为“所有拓扑结构”(这里的“所有拓扑结构”限制为 `kubernetes.io/hostname`,`topology.kubernetes.io/zone` 和 `topology.kubernetes.io/region` 的组合)。 +1. 对于亲和性与 `requiredDuringSchedulingIgnoredDuringExecution` 要求的 + Pod 反亲和性,`topologyKey` 不允许为空。 +2. 对于 `requiredDuringSchedulingIgnoredDuringExecution` 要求的 Pod 反亲和性, + 准入控制器 `LimitPodHardAntiAffinityTopology` 被引入来限制 `topologyKey` + 不为 `kubernetes.io/hostname`。 + 如果你想使它可用于自定义拓扑结构,你必须修改准入控制器或者禁用它。 +3. 对于 `preferredDuringSchedulingIgnoredDuringExecution` 要求的 Pod 反亲和性, + 空的 `topologyKey` 被解释为“所有拓扑结构”(这里的“所有拓扑结构”限制为 + `kubernetes.io/hostname`,`topology.kubernetes.io/zone` 和 + `topology.kubernetes.io/region` 的组合)。 4. 除上述情况外,`topologyKey` 可以是任何合法的标签键。 - -除了 `labelSelector` 和 `topologyKey`,你也可以指定表示命名空间的 `namespaces` 队列,`labelSelector` 也应该匹配它(这个与 `labelSelector` 和 `topologyKey` 的定义位于相同的级别)。如果忽略或者为空,则默认为 pod 亲和/反亲和的定义所在的命名空间。 +除了 `labelSelector` 和 `topologyKey`,你也可以指定表示命名空间的 +`namespaces` 队列,`labelSelector` 也应该匹配它 +(这个与 `labelSelector` 和 `topologyKey` 的定义位于相同的级别)。 +如果忽略或者为空,则默认为 Pod 亲和性/反亲和性的定义所在的命名空间。 - -所有与 `requiredDuringSchedulingIgnoredDuringExecution` 亲和与反亲和关联的 `matchExpressions` 必须满足,才能将 pod 调度到节点上。 +所有与 `requiredDuringSchedulingIgnoredDuringExecution` 亲和性与反亲和性 +关联的 `matchExpressions` 必须满足,才能将 pod 调度到节点上。 -#### 更实际的用例 - - +#### 更实际的用例 -Pod 间亲和与反亲和在与更高级别的集合(例如 ReplicaSets,StatefulSets,Deployments 等)一起使用时,它们可能更加有用。可以轻松配置一组应位于相同定义拓扑(例如,节点)中的工作负载。 +Pod 间亲和性与反亲和性在与更高级别的集合(例如 ReplicaSets、StatefulSets、 +Deployments 等)一起使用时,它们可能更加有用。 +可以轻松配置一组应位于相同定义拓扑(例如,节点)中的工作负载。 -##### 始终放置在相同节点上 - - +##### 始终放置在相同节点上 -在三节点集群中,一个 web 应用程序具有内存缓存,例如 redis。我们希望 web 服务器尽可能与缓存放置在同一位置。 +在三节点集群中,一个 web 应用程序具有内存缓存,例如 redis。 +我们希望 web 服务器尽可能与缓存放置在同一位置。 - -下面是一个简单 redis deployment 的 yaml 代码段,它有三个副本和选择器标签 `app=store`。Deployment 配置了 `PodAntiAffinity`,用来确保调度器不会将副本调度到单个节点上。 +下面是一个简单 redis Deployment 的 YAML 代码段,它有三个副本和选择器标签 `app=store`。 +Deployment 配置了 `PodAntiAffinity`,用来确保调度器不会将副本调度到单个节点上。 ```yaml apiVersion: apps/v1 @@ -512,8 +569,9 @@ spec: - -下面 webserver deployment 的 yaml 代码段中配置了 `podAntiAffinity` 和 `podAffinity`。这将通知调度器将它的所有副本与具有 `app=store` 选择器标签的 pod 放置在一起。这还确保每个 web 服务器副本不会调度到单个节点上。 +下面 webserver Deployment 的 YAML 代码段中配置了 `podAntiAffinity` 和 `podAffinity`。 +这将通知调度器将它的所有副本与具有 `app=store` 选择器标签的 Pod 放置在一起。 +这还确保每个 web 服务器副本不会调度到单个节点上。 ```yaml apiVersion: apps/v1 @@ -557,8 +615,7 @@ spec: - -如果我们创建了上面的两个 deployment,我们的三节点集群将如下表所示。 +如果我们创建了上面的两个 Deployment,我们的三节点集群将如下表所示。 | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| @@ -568,7 +625,6 @@ If we create the above two deployments, our three node cluster should look like - 如你所见,`web-server` 的三个副本都按照预期那样自动放置在同一位置。 ``` @@ -592,20 +648,18 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 -##### 永远不放置在相同节点 - - +##### 永远不放置在相同节点 + 上面的例子使用 `PodAntiAffinity` 规则和 `topologyKey: "kubernetes.io/hostname"` 来部署 redis 集群以便在同一主机上没有两个实例。 参阅 [ZooKeeper 教程](/zh/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure), -以获取配置反亲和来达到高可用性的 StatefulSet 的样例(使用了相同的技巧)。 +以获取配置反亲和性来达到高可用性的 StatefulSet 的样例(使用了相同的技巧)。 ## nodeName @@ -617,30 +671,33 @@ kubelet running on the named node tries to run the pod. Thus, if `nodeName` is provided in the PodSpec, it takes precedence over the above methods for node selection. --> -`nodeName` 是节点选择约束的最简单方法,但是由于其自身限制,通常不使用它。`nodeName` 是 PodSpec 的一个字段。如果它不为空,调度器将忽略 pod,并且运行在它指定节点上的 kubelet 进程尝试运行该 pod。因此,如果 `nodeName` 在 PodSpec 中指定了,则它优先于上面的节点选择方法。 +`nodeName` 是节点选择约束的最简单方法,但是由于其自身限制,通常不使用它。 +`nodeName` 是 PodSpec 的一个字段。 +如果它不为空,调度器将忽略 Pod,并且给定节点上运行的 kubelet 进程尝试执行该 Pod。 +因此,如果 `nodeName` 在 PodSpec 中指定了,则它优先于上面的节点选择方法。 使用 `nodeName` 来选择节点的一些限制: - -- 如果指定的节点不存在, -- 如果指定的节点没有资源来容纳 pod,pod 将会调度失败并且其原因将显示为,比如 OutOfmemory 或 OutOfcpu。 -- 云环境中的节点名称并非总是可预测或稳定的。 +- 如果指定的节点不存在, +- 如果指定的节点没有资源来容纳 Pod,Pod 将会调度失败并且其原因将显示为, + 比如 OutOfmemory 或 OutOfcpu。 +- 云环境中的节点名称并非总是可预测或稳定的。 -下面的是使用 `nodeName` 字段的 pod 配置文件的例子: +下面的是使用 `nodeName` 字段的 Pod 配置文件的例子: ```yaml apiVersion: v1 @@ -657,7 +714,6 @@ spec: - 上面的 pod 将运行在 kube-01 节点上。 ## {{% heading "whatsnext" %}} @@ -665,24 +721,23 @@ The above pod will run on the node kube-01. - -[污点](/zh/docs/concepts/scheduling-eviction/taint-and-toleration/)允许节点*排斥*一组 pod。 +[污点](/zh/docs/concepts/scheduling-eviction/taint-and-toleration/) +允许节点*排斥*一组 Pod。 - -[节点亲和](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)与 -[pod 间亲和/反亲和](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)的设计文档包含这些功能的其他背景信息。 +[节点亲和性](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)与 +[pod 间亲和性/反亲和性](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md) +的设计文档包含这些功能的其他背景信息。 - 一旦 Pod 分配给 节点,kubelet 应用将运行该 pod 并且分配节点本地资源。 [拓扑管理器](/zh/docs/tasks/administer-cluster/topology-manager/) 可以参与到节点级别的资源分配决定中。 From 8c834f22c0f08a61a70c7768f2644f7aa4db420e Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Mon, 11 Jan 2021 15:18:08 +0800 Subject: [PATCH 2/2] Resync concepts/scheduling-eviction/assign-pod-node.md --- .../scheduling-eviction/assign-pod-node.md | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md index 47ebab9f88..807e674e20 100644 --- a/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/zh/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -347,6 +347,72 @@ MatchExpressions,则添加“权重”到总和。 然后将这个评分与该节点的其他优先级函数的评分进行组合。 总分最高的节点是最优选的。 + +#### 逐个调度方案中设置节点亲和性 {#node-affinity-per-scheduling-profile} + +{{< feature-state for_k8s_version="v1.20" state="beta" >}} + + +在配置多个[调度方案](/zh/docs/reference/scheduling/config/#multiple-profiles)时, +你可以将某个方案与节点亲和性关联起来,如果某个调度方案仅适用于某组 +特殊的节点时,这样做是很有用的。 +要实现这点,可以在[调度器配置](/zh/docs/reference/scheduling/config/)中为 +[`NodeAffinity` 插件](/zh/docs/reference/scheduling/config/#scheduling-plugins) +添加 `addedAffinity` 参数。 +例如: + +```yaml +apiVersion: kubescheduler.config.k8s.io/v1beta1 +kind: KubeSchedulerConfiguration + +profiles: + - schedulerName: default-scheduler + - schedulerName: foo-scheduler + pluginConfig: + - name: NodeAffinity + args: + addedAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: scheduler-profile + operator: In + values: + - foo +``` + + +这里的 `addedAffinity` 除遵从 Pod 规约中设置的节点亲和性之外,还 +适用于将 `.spec.schedulerName` 设置为 `foo-scheduler`。 + + +{{< note >}} +DaemonSet 控制器[为 DaemonSet 创建 Pods](/zh/docs/concepts/workloads/controllers/daemonset/#scheduled-by-default-scheduler), +但该控制器不理会调度方案。因此,建议你保留一个调度方案,例如 +`default-scheduler`,不要在其中设置 `addedAffinity`。 +这样,DaemonSet 的 Pod 模板将会使用此调度器名称。 +否则,DaemonSet 控制器所创建的某些 Pods 可能持续处于不可调度状态。 +{{< /note >}} +