[zh] Resync some concepts pages (concepts-4)
This commit is contained in:
@@ -145,8 +145,8 @@ have some advantages for start-up related code:
|
||||
* Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此,Init 容器可以访问
|
||||
应用容器不能访问的 {{< glossary_tooltip text="Secret" term_id="secret" >}} 的权限。
|
||||
|
||||
* 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器
|
||||
提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。
|
||||
* 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init
|
||||
容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。
|
||||
一旦前置条件满足,Pod 内的所有的应用容器会并行启动。
|
||||
|
||||
<!--
|
||||
@@ -156,19 +156,35 @@ Here are some ideas for how to use init containers:
|
||||
|
||||
* Wait for a {{< glossary_tooltip text="Service" term_id="service">}} to
|
||||
be created, using a shell one-line command like:
|
||||
-->
|
||||
### 示例 {#examples}
|
||||
|
||||
下面是一些如何使用 Init 容器的想法:
|
||||
|
||||
* 等待一个 Service 完成创建,通过类似如下 Shell 命令:
|
||||
|
||||
```shell
|
||||
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
|
||||
```
|
||||
|
||||
* Register this Pod with a remote server from the downward API with a command like:
|
||||
<!--
|
||||
* Register this Pod with a remote server from the downward API with a command like:
|
||||
-->
|
||||
* 注册这个 Pod 到远程服务器,通过在命令中调用 API,类似如下:
|
||||
|
||||
```shell
|
||||
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
|
||||
```
|
||||
|
||||
<!--
|
||||
* Wait for some time before starting the app container with a command like
|
||||
-->
|
||||
* 在启动应用容器之前等一段时间,使用类似命令:
|
||||
|
||||
```shell
|
||||
sleep 60
|
||||
```
|
||||
|
||||
<!--
|
||||
* Clone a Git repository into a {{< glossary_tooltip text="Volume" term_id="volume" >}}
|
||||
|
||||
* Place values into a configuration file and run a template tool to dynamically
|
||||
@@ -176,29 +192,6 @@ Here are some ideas for how to use init containers:
|
||||
place the `POD_IP` value in a configuration and generate the main app
|
||||
configuration file using Jinja.
|
||||
-->
|
||||
### 示例 {#examples}
|
||||
|
||||
下面是一些如何使用 Init 容器的想法:
|
||||
|
||||
* 等待一个 Service 完成创建,通过类似如下 shell 命令:
|
||||
|
||||
```shell
|
||||
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
|
||||
```
|
||||
|
||||
* 注册这个 Pod 到远程服务器,通过在命令中调用 API,类似如下:
|
||||
|
||||
```shell
|
||||
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register \
|
||||
-d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
|
||||
```
|
||||
|
||||
* 在启动应用容器之前等一段时间,使用类似命令:
|
||||
|
||||
```shell
|
||||
sleep 60
|
||||
```
|
||||
|
||||
* 克隆 Git 仓库到{{< glossary_tooltip text="卷" term_id="volume" >}}中。
|
||||
|
||||
* 将配置值放到配置文件中,运行模板工具为主应用容器动态地生成配置文件。
|
||||
@@ -249,6 +242,7 @@ kubectl apply -f myapp.yaml
|
||||
The output is similar to this:
|
||||
-->
|
||||
输出类似于:
|
||||
|
||||
```
|
||||
pod/myapp-pod created
|
||||
```
|
||||
@@ -261,10 +255,12 @@ And check on its status with:
|
||||
```shell
|
||||
kubectl get -f myapp.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
The output is similar to this:
|
||||
-->
|
||||
输出类似于:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
myapp-pod 0/1 Init:0/2 0 6m
|
||||
@@ -278,10 +274,12 @@ or for more details:
|
||||
```shell
|
||||
kubectl describe -f myapp.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
The output is similar to this:
|
||||
-->
|
||||
输出类似于:
|
||||
|
||||
```
|
||||
Name: myapp-pod
|
||||
Namespace: default
|
||||
@@ -408,13 +406,26 @@ init containers. [What's next](#what-s-next) contains a link to a more detailed
|
||||
During Pod startup, the kubelet delays running init containers until the networking
|
||||
and storage are ready. Then the kubelet runs the Pod's init containers in the order
|
||||
they appear in the Pod's spec.
|
||||
-->
|
||||
## 具体行为 {#detailed-behavior}
|
||||
|
||||
在 Pod 启动过程中,每个 Init 容器会在网络和数据卷初始化之后按顺序启动。
|
||||
kubelet 运行依据 Init 容器在 Pod 规约中的出现顺序依次运行之。
|
||||
|
||||
<!--
|
||||
Each init container must exit successfully before
|
||||
the next container starts. If a container fails to start due to the runtime or
|
||||
exits with failure, it is retried according to the Pod `restartPolicy`. However,
|
||||
if the Pod `restartPolicy` is set to Always, the init containers use
|
||||
`restartPolicy` OnFailure.
|
||||
-->
|
||||
每个 Init 容器成功退出后才会启动下一个 Init 容器。
|
||||
如果某容器因为容器运行时的原因无法启动,或以错误状态退出,kubelet 会根据
|
||||
Pod 的 `restartPolicy` 策略进行重试。
|
||||
然而,如果 Pod 的 `restartPolicy` 设置为 "Always",Init 容器失败时会使用
|
||||
`restartPolicy` 的 "OnFailure" 策略。
|
||||
|
||||
<!--
|
||||
A Pod cannot be `Ready` until all init containers have succeeded. The ports on an
|
||||
init container are not aggregated under a Service. A Pod that is initializing
|
||||
is in the `Pending` state but should have a condition `Initialized` set to false.
|
||||
@@ -422,17 +433,6 @@ is in the `Pending` state but should have a condition `Initialized` set to false
|
||||
If the Pod [restarts](#pod-restart-reasons), or is restarted, all init containers
|
||||
must execute again.
|
||||
-->
|
||||
## 具体行为 {#detailed-behavior}
|
||||
|
||||
在 Pod 启动过程中,每个 Init 容器会在网络和数据卷初始化之后按顺序启动。
|
||||
kubelet 运行依据 Init 容器在 Pod 规约中的出现顺序依次运行之。
|
||||
|
||||
每个 Init 容器成功退出后才会启动下一个 Init 容器。
|
||||
如果某容器因为容器运行时的原因无法启动,或以错误状态退出,kubelet 会根据
|
||||
Pod 的 `restartPolicy` 策略进行重试。
|
||||
然而,如果 Pod 的 `restartPolicy` 设置为 "Always",Init 容器失败时会使用
|
||||
`restartPolicy` 的 "OnFailure" 策略。
|
||||
|
||||
在所有的 Init 容器没有成功之前,Pod 将不会变成 `Ready` 状态。
|
||||
Init 容器的端口将不会在 Service 中进行聚集。正在初始化中的 Pod 处于 `Pending` 状态,
|
||||
但会将状况 `Initializing` 设置为 false。
|
||||
@@ -446,11 +446,6 @@ Altering an init container image field is equivalent to restarting the Pod.
|
||||
Because init containers can be restarted, retried, or re-executed, init container
|
||||
code should be idempotent. In particular, code that writes to files on `EmptyDirs`
|
||||
should be prepared for the possibility that an output file already exists.
|
||||
|
||||
Init containers have all of the fields of an app container. However, Kubernetes
|
||||
prohibits `readinessProbe` from being used because init containers cannot
|
||||
define readiness distinct from completion. This is enforced during validation.
|
||||
|
||||
-->
|
||||
对 Init 容器规约的修改仅限于容器的 `image` 字段。
|
||||
更改 Init 容器的 `image` 字段,等同于重启该 Pod。
|
||||
@@ -458,6 +453,11 @@ define readiness distinct from completion. This is enforced during validation.
|
||||
因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。
|
||||
特别地,基于 `emptyDirs` 写文件的代码,应该对输出文件可能已经存在做好准备。
|
||||
|
||||
<!--
|
||||
Init containers have all of the fields of an app container. However, Kubernetes
|
||||
prohibits `readinessProbe` from being used because init containers cannot
|
||||
define readiness distinct from completion. This is enforced during validation.
|
||||
-->
|
||||
Init 容器具有应用容器的所有字段。然而 Kubernetes 禁止使用 `readinessProbe`,
|
||||
因为 Init 容器不能定义不同于完成态(Completion)的就绪态(Readiness)。
|
||||
Kubernetes 会在校验时强制执行此检查。
|
||||
@@ -487,31 +487,36 @@ Init 容器一直重复失败。
|
||||
|
||||
Given the ordering and execution for init containers, the following rules
|
||||
for resource usage apply:
|
||||
-->
|
||||
### 资源 {#resources}
|
||||
|
||||
在给定的 Init 容器执行顺序下,资源使用适用于如下规则:
|
||||
|
||||
<!--
|
||||
* The highest of any particular resource request or limit defined on all init
|
||||
containers is the *effective init request/limit*. If any resource has no
|
||||
resource limit specified this is considered as the highest limit.
|
||||
* The Pod's *effective request/limit* for a resource is the higher of:
|
||||
* the sum of all app containers request/limit for a resource
|
||||
* the effective init request/limit for a resource
|
||||
-->
|
||||
* 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为
|
||||
Pod **有效初始 request/limit**。
|
||||
如果任何资源没有指定资源限制,这被视为最高限制。
|
||||
* Pod 对资源的 **有效 limit/request** 是如下两者中的较大者:
|
||||
* 所有应用容器对某个资源的 limit/request 之和
|
||||
* 对某个资源的有效初始 limit/request
|
||||
|
||||
<!--
|
||||
* Scheduling is done based on effective requests/limits, which means
|
||||
init containers can reserve resources for initialization that are not used
|
||||
during the life of the Pod.
|
||||
* The QoS (quality of service) tier of the Pod's *effective QoS tier* is the
|
||||
QoS tier for init containers and app containers alike.
|
||||
-->
|
||||
### 资源 {#resources}
|
||||
|
||||
在给定的 Init 容器执行顺序下,资源使用适用于如下规则:
|
||||
|
||||
* 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为 Pod *有效初始 request/limit*。
|
||||
如果任何资源没有指定资源限制,这被视为最高限制。
|
||||
* Pod 对资源的 *有效 limit/request* 是如下两者的较大者:
|
||||
* 所有应用容器对某个资源的 limit/request 之和
|
||||
* 对某个资源的有效初始 limit/request
|
||||
* 基于有效 limit/request 完成调度,这意味着 Init 容器能够为初始化过程预留资源,
|
||||
这些资源在 Pod 生命周期过程中并没有被使用。
|
||||
* Pod 的 *有效 QoS 层* ,与 Init 容器和应用容器的一样。
|
||||
* Pod 的 **有效 QoS 层** ,与 Init 容器和应用容器的一样。
|
||||
|
||||
<!--
|
||||
Quota and limits are applied based on the effective Pod request and limit.
|
||||
@@ -525,17 +530,18 @@ Pod 级别的 cgroups 是基于有效 Pod 的请求和限制值,和调度器
|
||||
|
||||
A Pod can restart, causing re-execution of init containers, for the following
|
||||
reasons:
|
||||
-->
|
||||
### Pod 重启的原因 {#pod-restart-reasons}
|
||||
|
||||
Pod 重启会导致 Init 容器重新执行,主要有如下几个原因:
|
||||
|
||||
<!--
|
||||
* The Pod infrastructure container is restarted. This is uncommon and would
|
||||
have to be done by someone with root access to nodes.
|
||||
* All containers in a Pod are terminated while `restartPolicy` is set to Always,
|
||||
forcing a restart, and the init container completion record has been lost due
|
||||
to garbage collection.
|
||||
-->
|
||||
### Pod 重启的原因 {#pod-restart-reasons}
|
||||
|
||||
Pod 重启会导致 Init 容器重新执行,主要有如下几个原因:
|
||||
|
||||
* Pod 的基础设施容器 (译者注:如 `pause` 容器) 被重启。这种情况不多见,
|
||||
必须由具备 root 权限访问节点的人员来完成。
|
||||
|
||||
@@ -549,8 +555,8 @@ applies for Kubernetes v1.20 and later. If you are using an earlier version of
|
||||
Kubernetes, consult the documentation for the version you are using.
|
||||
-->
|
||||
当 Init 容器的镜像发生改变或者 Init 容器的完成记录因为垃圾收集等原因被丢失时,
|
||||
Pod 不会被重启。这一行为适用于 Kubernetes v1.20 及更新版本。如果你在使用较早
|
||||
版本的 Kubernetes,可查阅你所使用的版本对应的文档。
|
||||
Pod 不会被重启。这一行为适用于 Kubernetes v1.20 及更新版本。
|
||||
如果你在使用较早版本的 Kubernetes,可查阅你所使用的版本对应的文档。
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
@@ -558,5 +564,6 @@ Pod 不会被重启。这一行为适用于 Kubernetes v1.20 及更新版本。
|
||||
* Read about [creating a Pod that has an init container](/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container)
|
||||
* Learn how to [debug init containers](/docs/tasks/debug/debug-application/debug-init-containers/)
|
||||
-->
|
||||
* 阅读[创建包含 Init 容器的 Pod](/zh/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container)
|
||||
* 学习如何[调试 Init 容器](/zh/docs/tasks/debug/debug-application/debug-init-containers/)
|
||||
* 阅读[创建包含 Init 容器的 Pod](/zh-cn/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container)
|
||||
* 学习如何[调试 Init 容器](/zh-cn/docs/tasks/debug/debug-application/debug-init-containers/)
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ weight: 40
|
||||
You can use _topology spread constraints_ to control how {{< glossary_tooltip text="Pods" term_id="Pod" >}} are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains. This can help to achieve high availability as well as efficient resource utilization.
|
||||
-->
|
||||
你可以使用 _拓扑分布约束(Topology Spread Constraints)_ 来控制
|
||||
{{< glossary_tooltip text="Pods" term_id="Pod" >}} 在集群内故障域
|
||||
之间的分布,例如区域(Region)、可用区(Zone)、节点和其他用户自定义拓扑域。
|
||||
{{< glossary_tooltip text="Pod" term_id="Pod" >}} 在集群内故障域之间的分布,
|
||||
例如区域(Region)、可用区(Zone)、节点和其他用户自定义拓扑域。
|
||||
这样做有助于实现高可用并提升资源利用率。
|
||||
|
||||
<!-- body -->
|
||||
@@ -125,14 +125,13 @@ You can define one or multiple `topologySpreadConstraint` to instruct the kube-s
|
||||
precedence to topologies that would help reduce the skew.
|
||||
-->
|
||||
|
||||
- **maxSkew** 描述 Pod 分布不均的程度。这是给定拓扑类型中任意两个拓扑域中
|
||||
匹配的 pod 之间的最大允许差值。它必须大于零。取决于 `whenUnsatisfiable` 的
|
||||
取值,其语义会有不同。
|
||||
- 当 `whenUnsatisfiable` 等于 "DoNotSchedule" 时,`maxSkew` 是目标拓扑域
|
||||
中匹配的 Pod 数与全局最小值(一个拓扑域中与标签选择器匹配的 Pod 的最小数量。例如,如果你有
|
||||
- **maxSkew** 描述 Pod 分布不均的程度。这是给定拓扑类型中任意两个拓扑域中匹配的
|
||||
Pod 之间的最大允许差值。它必须大于零。取决于 `whenUnsatisfiable` 的取值,
|
||||
其语义会有不同。
|
||||
- 当 `whenUnsatisfiable` 等于 "DoNotSchedule" 时,`maxSkew` 是目标拓扑域中匹配的
|
||||
Pod 数与全局最小值(一个拓扑域中与标签选择器匹配的 Pod 的最小数量。例如,如果你有
|
||||
3 个区域,分别具有 0 个、2 个 和 3 个匹配的 Pod,则全局最小值为 0。)之间可存在的差异。
|
||||
- 当 `whenUnsatisfiable` 等于 "ScheduleAnyway" 时,调度器会更为偏向能够降低
|
||||
偏差值的拓扑域。
|
||||
- 当 `whenUnsatisfiable` 等于 "ScheduleAnyway" 时,调度器会更为偏向能够降低偏差值的拓扑域。
|
||||
|
||||
<!--
|
||||
- **minDomains** indicates a minimum number of eligible domains.
|
||||
@@ -153,9 +152,9 @@ You can define one or multiple `topologySpreadConstraint` to instruct the kube-s
|
||||
符合条件的域是其节点与节点选择器匹配的域。
|
||||
|
||||
- 指定的 `minDomains` 的值必须大于 0。
|
||||
- 当符合条件的、拓扑键匹配的域的数量小于 `minDomains` 时,Pod 拓扑分布将“全局最小值”(global minimum) 设为
|
||||
0,然后进行 `skew` 计算。“全局最小值”是一个符合条件的域中匹配 Pods 的最小数量,
|
||||
如果符合条件的域的数量小于 `minDomains`,则全局最小值为零。
|
||||
- 当符合条件的、拓扑键匹配的域的数量小于 `minDomains` 时,Pod 拓扑分布将“全局最小值”
|
||||
(global minimum)设为 0,然后进行 `skew` 计算。“全局最小值”是一个符合条件的域中匹配
|
||||
Pod 的最小数量,如果符合条件的域的数量小于 `minDomains`,则全局最小值为零。
|
||||
- 当符合条件的拓扑键匹配域的个数等于或大于 `minDomains` 时,该值对调度没有影响。
|
||||
- 当 `minDomains` 为 nil 时,约束的行为等于 `minDomains` 为 1。
|
||||
- 当 `minDomains` 不为 nil 时,`whenUnsatisfiable` 的值必须为 "`DoNotSchedule`" 。
|
||||
@@ -180,16 +179,14 @@ You can define one or multiple `topologySpreadConstraint` to instruct the kube-s
|
||||
- **labelSelector** is used to find matching Pods. Pods that match this label selector are counted to determine the number of Pods in their corresponding topology domain. See [Label Selectors](/docs/concepts/overview/working-with-objects/labels/#label-selectors) for more details.
|
||||
-->
|
||||
- **topologyKey** 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,
|
||||
则调度器会将这两个节点视为处于同一拓扑域中。调度器试图在每个拓扑域中放置数量
|
||||
均衡的 Pod。
|
||||
则调度器会将这两个节点视为处于同一拓扑域中。调度器试图在每个拓扑域中放置数量均衡的 Pod。
|
||||
|
||||
- **whenUnsatisfiable** 指示如果 Pod 不满足分布约束时如何处理:
|
||||
- `DoNotSchedule`(默认)告诉调度器不要调度。
|
||||
- `ScheduleAnyway` 告诉调度器仍然继续调度,只是根据如何能将偏差最小化来对
|
||||
节点进行排序。
|
||||
- `ScheduleAnyway` 告诉调度器仍然继续调度,只是根据如何能将偏差最小化来对节点进行排序。
|
||||
|
||||
- **labelSelector** 用于查找匹配的 pod。匹配此标签的 Pod 将被统计,以确定相应
|
||||
拓扑域中 Pod 的数量。
|
||||
- **labelSelector** 用于查找匹配的 Pod。匹配此标签的 Pod 将被统计,
|
||||
以确定相应拓扑域中 Pod 的数量。
|
||||
有关详细信息,请参考[标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/#label-selectors)。
|
||||
|
||||
<!--
|
||||
@@ -201,8 +198,8 @@ kube-scheduler 会为新的 Pod 寻找一个能够满足所有约束的节点。
|
||||
<!--
|
||||
You can read more about this field by running `kubectl explain Pod.spec.topologySpreadConstraints`.
|
||||
-->
|
||||
你可以执行 `kubectl explain Pod.spec.topologySpreadConstraints` 命令以
|
||||
了解关于 topologySpreadConstraints 的更多信息。
|
||||
你可以执行 `kubectl explain Pod.spec.topologySpreadConstraints`
|
||||
命令以了解关于 topologySpreadConstraints 的更多信息。
|
||||
|
||||
<!--
|
||||
### Example: One TopologySpreadConstraint
|
||||
@@ -243,16 +240,15 @@ If we want an incoming Pod to be evenly spread with existing Pods across zones,
|
||||
`topologyKey: zone` implies the even distribution will only be applied to the nodes which have label pair "zone:<any value>" present. `whenUnsatisfiable: DoNotSchedule` tells the scheduler to let it stay pending if the incoming Pod can’t satisfy the constraint.
|
||||
-->
|
||||
`topologyKey: zone` 意味着均匀分布将只应用于存在标签键值对为
|
||||
"zone:<any value>" 的节点。
|
||||
"zone:<任何值>" 的节点。
|
||||
`whenUnsatisfiable: DoNotSchedule` 告诉调度器如果新的 Pod 不满足约束,
|
||||
则让它保持悬决状态。
|
||||
|
||||
<!--
|
||||
If the scheduler placed this incoming Pod into "zoneA", the Pods distribution would become [3, 1],
|
||||
hence the actual skew is 2 (3 - 1) - which violates `maxSkew: 1`. In this example, the incoming Pod can only be placed onto "zoneB":
|
||||
If the scheduler placed this incoming Pod into "zoneA", the Pods distribution would become [3, 1], hence the actual skew is 2 (3 - 1) - which violates `maxSkew: 1`. In this example, the incoming Pod can only be placed onto "zoneB":
|
||||
-->
|
||||
如果调度器将新的 Pod 放入 "zoneA",Pods 分布将变为 [3, 1],因此实际的偏差
|
||||
为 2(3 - 1)。这违反了 `maxSkew: 1` 的约定。此示例中,新 Pod 只能放置在
|
||||
如果调度器将新的 Pod 放入 "zoneA",Pods 分布将变为 [3, 1],因此实际的偏差为
|
||||
2(3 - 1)。这违反了 `maxSkew: 1` 的约定。此示例中,新 Pod 只能放置在
|
||||
"zoneB" 上:
|
||||
|
||||
{{<mermaid>}}
|
||||
@@ -355,8 +351,8 @@ You can use 2 TopologySpreadConstraints to control the Pods spreading on both zo
|
||||
In this case, to match the first constraint, the incoming Pod can only be placed onto "zoneB"; while in terms of the second constraint, the incoming Pod can only be placed onto "node4". Then the results of 2 constraints are ANDed, so the only viable option is to place on "node4".
|
||||
-->
|
||||
在这种情况下,为了匹配第一个约束,新的 Pod 只能放置在 "zoneB" 中;而在第二个约束中,
|
||||
新的 Pod 只能放置在 "node4" 上。最后两个约束的结果加在一起,唯一可行的选择是放置
|
||||
在 "node4" 上。
|
||||
新的 Pod 只能放置在 "node4" 上。最后两个约束的结果加在一起,唯一可行的选择是放置在
|
||||
"node4" 上。
|
||||
|
||||
<!--
|
||||
Multiple constraints can lead to conflicts. Suppose you have a 3-node cluster across 2 zones:
|
||||
@@ -383,7 +379,7 @@ graph BT
|
||||
{{< /mermaid >}}
|
||||
|
||||
<!--
|
||||
If you apply "two-constraints.yaml" to this cluster, you will notice "mypod" stays in `Pending` state. This is because: to satisfy the first constraint, "mypod" can only be put to "zoneB"; while in terms of the second constraint, "mypod" can only put to "node2". Then a joint result of "zoneB" and "node2" returns nothing.
|
||||
If you apply "two-constraints.yaml" to this cluster, you will notice "mypod" stays in `Pending` state. This is because: to satisfy the first constraint, "mypod" can only be put to "zoneB"; while in terms of the second constraint, "mypod" can only put onto "node2". Then a joint result of "zoneB" and "node2" returns nothing.
|
||||
-->
|
||||
如果对集群应用 "two-constraints.yaml",会发现 "mypod" 处于 `Pending` 状态。
|
||||
这是因为:为了满足第一个约束,"mypod" 只能放在 "zoneB" 中,而第二个约束要求
|
||||
@@ -448,7 +444,7 @@ class zoneC cluster;
|
||||
|
||||
|
||||
<!--
|
||||
and you know that "zoneC" must be excluded. In this case, you can compose the yaml as below, so that "mypod" will be placed onto "zoneB" instead of "zoneC". Similarly `spec.nodeSelector` is also respected.
|
||||
and you know that "zoneC" must be excluded. In this case, you can compose the yaml as below, so that "mypod" will be placed into "zoneB" instead of "zoneC". Similarly `spec.nodeSelector` is also respected.
|
||||
-->
|
||||
而且你知道 "zoneC" 必须被排除在外。在这种情况下,可以按如下方式编写 YAML,
|
||||
以便将 "mypod" 放置在 "zoneB" 上,而不是 "zoneC" 上。同样,`spec.nodeSelector`
|
||||
@@ -479,7 +475,7 @@ There are some implicit conventions worth noting here:
|
||||
- The scheduler will bypass the nodes without `topologySpreadConstraints[*].topologyKey` present. This implies that:
|
||||
|
||||
1. the Pods located on those nodes do not impact `maxSkew` calculation - in the above example, suppose "node1" does not have label "zone", then the 2 Pods will be disregarded, hence the incoming Pod will be scheduled into "zoneA".
|
||||
2. the incoming Pod has no chances to be scheduled onto this kind of nodes - in the above example, suppose a "node5" carrying label `{zone-typo: zoneC}` joins the cluster, it will be bypassed due to the absence of label key "zone".
|
||||
2. the incoming Pod has no chances to be scheduled onto such nodes - in the above example, suppose a "node5" carrying label `{zone-typo: zoneC}` joins the cluster, it will be bypassed due to the absence of label key "zone".
|
||||
-->
|
||||
- 只有与新的 Pod 具有相同命名空间的 Pod 才能作为匹配候选者。
|
||||
- 调度器会忽略没有 `topologySpreadConstraints[*].topologyKey` 的节点。这意味着:
|
||||
@@ -494,8 +490,8 @@ There are some implicit conventions worth noting here:
|
||||
<!--
|
||||
- Be aware of what will happen if the incomingPod’s `topologySpreadConstraints[*].labelSelector` doesn’t match its own labels. In the above example, if we remove the incoming Pod’s labels, it can still be placed onto "zoneB" since the constraints are still satisfied. However, after the placement, the degree of imbalance of the cluster remains unchanged - it’s still zoneA having 2 Pods which hold label {foo:bar}, and zoneB having 1 Pod which holds label {foo:bar}. So if this is not what you expect, we recommend the workload’s `topologySpreadConstraints[*].labelSelector` to match its own labels.
|
||||
-->
|
||||
- 注意,如果新 Pod 的 `topologySpreadConstraints[*].labelSelector` 与自身的
|
||||
标签不匹配,将会发生什么。
|
||||
- 注意,如果新 Pod 的 `topologySpreadConstraints[*].labelSelector`
|
||||
与自身的标签不匹配,将会发生什么。
|
||||
在上面的例子中,如果移除新 Pod 上的标签,Pod 仍然可以调度到 "zoneB",因为约束仍然满足。
|
||||
然而,在调度之后,集群的不平衡程度保持不变。zoneA 仍然有 2 个带有 {foo:bar} 标签的 Pod,
|
||||
zoneB 有 1 个带有 {foo:bar} 标签的 Pod。
|
||||
@@ -513,8 +509,8 @@ topology spread constraints are applied to a Pod if, and only if:
|
||||
-->
|
||||
### 集群级别的默认约束 {#cluster-level-default-constraints}
|
||||
|
||||
为集群设置默认的拓扑分布约束也是可能的。默认拓扑分布约束在且仅在以下条件满足
|
||||
时才会应用到 Pod 上:
|
||||
为集群设置默认的拓扑分布约束也是可能的。
|
||||
默认拓扑分布约束在且仅在以下条件满足时才会被应用到 Pod 上:
|
||||
|
||||
- Pod 没有在其 `.spec.topologySpreadConstraints` 设置任何约束;
|
||||
- Pod 隶属于某个服务、副本控制器、ReplicaSet 或 StatefulSet。
|
||||
|
||||
Reference in New Issue
Block a user