|
| 1 | +--- |
| 2 | +reviewers: |
| 3 | +- robscott |
| 4 | +title: 拓扑感知路由 |
| 5 | +content_type: concept |
| 6 | +weight: 100 |
| 7 | +description: >- |
| 8 | + **拓扑感知路由**提供了一种机制帮助保持网络流量处于流量发起的区域内。 |
| 9 | + 在集群中 Pod 之间优先使用相同区域的流量有助于提高可靠性、性能(网络延迟和吞吐量)或降低成本。 |
| 10 | +--- |
| 11 | +<!-- |
| 12 | +reviewers: |
| 13 | +- robscott |
| 14 | +title: Topology Aware Routing |
| 15 | +content_type: concept |
| 16 | +weight: 100 |
| 17 | +description: >- |
| 18 | + _Topology Aware Routing_ provides a mechanism to help keep network traffic within the zone |
| 19 | + where it originated. Preferring same-zone traffic between Pods in your cluster can help |
| 20 | + with reliability, performance (network latency and throughput), or cost. |
| 21 | +--> |
| 22 | + |
| 23 | +<!-- overview --> |
| 24 | + |
| 25 | +{{< feature-state for_k8s_version="v1.23" state="beta" >}} |
| 26 | + |
| 27 | +{{< note >}} |
| 28 | +<!-- |
| 29 | +Prior to Kubernetes 1.27, this feature was known as _Topology Aware Hints_. |
| 30 | +--> |
| 31 | +在 Kubernetes 1.27 之前,此特性称为**拓扑感知提示(Topology Aware Hint)**。 |
| 32 | +{{</ note >}} |
| 33 | + |
| 34 | +<!-- |
| 35 | +_Topology Aware Routing_ adjusts routing behavior to prefer keeping traffic in |
| 36 | +the zone it originated from. In some cases this can help reduce costs or improve |
| 37 | +network performance. |
| 38 | +--> |
| 39 | +**拓扑感知路由(Toplogy Aware Routing)** 调整路由行为,以优先保持流量在其发起区域内。 |
| 40 | +在某些情况下,这有助于降低成本或提高网络性能。 |
| 41 | + |
| 42 | +<!-- body --> |
| 43 | + |
| 44 | +<!-- |
| 45 | +## Motivation |
| 46 | +
|
| 47 | +Kubernetes clusters are increasingly deployed in multi-zone environments. |
| 48 | +_Topology Aware Routing_ provides a mechanism to help keep traffic within the |
| 49 | +zone it originated from. When calculating the endpoints for a {{< |
| 50 | +glossary_tooltip term_id="Service" >}}, the EndpointSlice controller considers |
| 51 | +the topology (region and zone) of each endpoint and populates the hints field to |
| 52 | +allocate it to a zone. Cluster components such as {{< glossary_tooltip |
| 53 | +term_id="kube-proxy" text="kube-proxy" >}} can then consume those hints, and use |
| 54 | +them to influence how the traffic is routed (favoring topologically closer |
| 55 | +endpoints). |
| 56 | +--> |
| 57 | +## 动机 {#motivation} |
| 58 | + |
| 59 | +Kubernetes 集群越来越多地部署在多区域环境中。 |
| 60 | +**拓扑感知路由** 提供了一种机制帮助流量保留在其发起所在的区域内。 |
| 61 | +计算 {{<glossary_tooltip term_id="Service">}} 的端点时, |
| 62 | +EndpointSlice 控制器考虑每个端点的物理拓扑(地区和区域),并填充提示字段以将其分配到区域。 |
| 63 | +诸如 {{<glossary_tooltip term_id="kube-proxy" text="kube-proxy">}} |
| 64 | +等集群组件可以使用这些提示,影响流量的路由方式(优先考虑物理拓扑上更近的端点)。 |
| 65 | + |
| 66 | +<!-- |
| 67 | +## Enabling Topology Aware Routing |
| 68 | +--> |
| 69 | +## 启用拓扑感知路由 {#enabling-topology-aware-routing} |
| 70 | + |
| 71 | +{{< note >}} |
| 72 | +<!-- |
| 73 | +Prior to Kubernetes 1.27, this behavior was controlled using the |
| 74 | +`service.kubernetes.io/topology-aware-hints` annotation. |
| 75 | +--> |
| 76 | +在 Kubernetes 1.27 之前,此行为是通过 `service.kubernetes.io/topology-aware-hints` 注解来控制的。 |
| 77 | +{{</ note >}} |
| 78 | + |
| 79 | +<!-- |
| 80 | +You can enable Topology Aware Routing for a Service by setting the |
| 81 | +`service.kubernetes.io/topology-mode` annotation to `Auto`. When there are |
| 82 | +enough endpoints available in each zone, Topology Hints will be populated on |
| 83 | +EndpointSlices to allocate individual endpoints to specific zones, resulting in |
| 84 | +traffic being routed closer to where it originated from. |
| 85 | +--> |
| 86 | +你可以通过将 `service.kubernetes.io/topology-mode` 注解设置为 `Auto` 来启用 Service 的拓扑感知路由。 |
| 87 | +当每个区域中有足够的端点可用时,系统将为 EndpointSlices 填充拓扑提示,把每个端点分配给特定区域, |
| 88 | +从而使流量被路由到更接近其来源的位置。 |
| 89 | + |
| 90 | +<!-- |
| 91 | +## When it works best |
| 92 | +
|
| 93 | +This feature works best when: |
| 94 | +--> |
| 95 | +## 何时效果最佳 {#when-it-works-best} |
| 96 | + |
| 97 | +此特性在以下场景中的工作效果最佳: |
| 98 | + |
| 99 | +<!-- |
| 100 | +### 1. Incoming traffic is evenly distributed |
| 101 | +
|
| 102 | +If a large proportion of traffic is originating from a single zone, that traffic |
| 103 | +could overload the subset of endpoints that have been allocated to that zone. |
| 104 | +This feature is not recommended when incoming traffic is expected to originate |
| 105 | +from a single zone. |
| 106 | +--> |
| 107 | +### 1. 入站流量均匀分布 {#incoming-traffic-is-evently-distributed} |
| 108 | + |
| 109 | +如果大部分流量源自同一个区域,则该流量可能会使分配到该区域的端点子集过载。 |
| 110 | +当预计入站流量源自同一区域时,不建议使用此特性。 |
| 111 | + |
| 112 | +<!-- |
| 113 | +### 2. The Service has 3 or more endpoints per zone {#three-or-more-endpoints-per-zone} |
| 114 | +
|
| 115 | +In a three zone cluster, this means 9 or more endpoints. If there are fewer than |
| 116 | +3 endpoints per zone, there is a high (≈50%) probability that the EndpointSlice |
| 117 | +controller will not be able to allocate endpoints evenly and instead will fall |
| 118 | +back to the default cluster-wide routing approach. |
| 119 | +--> |
| 120 | +### 2. 服务在每个区域具有至少 3 个端点 {#three-or-more-endpoints-per-zone} |
| 121 | + |
| 122 | +在一个三区域的集群中,这意味着有至少 9 个端点。如果每个区域的端点少于 3 个, |
| 123 | +则 EndpointSlice 控制器很大概率(约 50%)无法平均分配端点,而是回退到默认的集群范围的路由方法。 |
| 124 | + |
| 125 | +<!-- |
| 126 | +## How It Works |
| 127 | +
|
| 128 | +The "Auto" heuristic attempts to proportionally allocate a number of endpoints |
| 129 | +to each zone. Note that this heuristic works best for Services that have a |
| 130 | +significant number of endpoints. |
| 131 | +--> |
| 132 | +## 工作原理 {#how-it-works} |
| 133 | + |
| 134 | +“自动”启发式算法会尝试按比例分配一定数量的端点到每个区域。 |
| 135 | +请注意,这种启发方式对具有大量端点的 Service 效果最佳。 |
| 136 | + |
| 137 | +<!-- |
| 138 | +### EndpointSlice controller {#implementation-control-plane} |
| 139 | +
|
| 140 | +The EndpointSlice controller is responsible for setting hints on EndpointSlices |
| 141 | +when this heuristic is enabled. The controller allocates a proportional amount of |
| 142 | +endpoints to each zone. This proportion is based on the |
| 143 | +[allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) |
| 144 | +CPU cores for nodes running in that zone. For example, if one zone had 2 CPU |
| 145 | +cores and another zone only had 1 CPU core, the controller would allocate twice |
| 146 | +as many endpoints to the zone with 2 CPU cores. |
| 147 | +--> |
| 148 | +### EndpointSlice 控制器 {#implementation-control-plane} |
| 149 | + |
| 150 | +当启用此启发方式时,EndpointSlice 控制器负责在各个 EndpointSlice 上设置提示信息。 |
| 151 | +控制器按比例给每个区域分配一定比例数量的端点。 |
| 152 | +这个比例基于在该区域中运行的节点的[可分配](/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) |
| 153 | +CPU 核心数。例如,如果一个区域有 2 个 CPU 核心,而另一个区域只有 1 个 CPU 核心, |
| 154 | +那么控制器将给那个有 2 CPU 的区域分配两倍数量的端点。 |
| 155 | + |
| 156 | +<!-- |
| 157 | +The following example shows what an EndpointSlice looks like when hints have |
| 158 | +been populated: |
| 159 | +--> |
| 160 | +以下示例展示了提供提示信息后 EndpointSlice 的样子: |
| 161 | + |
| 162 | +```yaml |
| 163 | +apiVersion: discovery.k8s.io/v1 |
| 164 | +kind: EndpointSlice |
| 165 | +metadata: |
| 166 | + name: example-hints |
| 167 | + labels: |
| 168 | + kubernetes.io/service-name: example-svc |
| 169 | +addressType: IPv4 |
| 170 | +ports: |
| 171 | + - name: http |
| 172 | + protocol: TCP |
| 173 | + port: 80 |
| 174 | +endpoints: |
| 175 | + - addresses: |
| 176 | + - "10.1.2.3" |
| 177 | + conditions: |
| 178 | + ready: true |
| 179 | + hostname: pod-1 |
| 180 | + zone: zone-a |
| 181 | + hints: |
| 182 | + forZones: |
| 183 | + - name: "zone-a" |
| 184 | +``` |
| 185 | +
|
| 186 | +### kube-proxy {#implementation-kube-proxy} |
| 187 | +
|
| 188 | +<!-- |
| 189 | +The kube-proxy component filters the endpoints it routes to based on the hints set by |
| 190 | +the EndpointSlice controller. In most cases, this means that the kube-proxy is able |
| 191 | +to route traffic to endpoints in the same zone. Sometimes the controller allocates endpoints |
| 192 | +from a different zone to ensure more even distribution of endpoints between zones. |
| 193 | +This would result in some traffic being routed to other zones. |
| 194 | +--> |
| 195 | +kube-proxy 组件依据 EndpointSlice 控制器设置的提示,过滤由它负责路由的端点。 |
| 196 | +在大多数场合,这意味着 kube-proxy 可以把流量路由到同一个区域的端点。 |
| 197 | +有时,控制器在另一不同的区域中分配端点,以确保在多个区域之间更平均地分配端点。 |
| 198 | +这会导致部分流量被路由到其他区域。 |
| 199 | +
|
| 200 | +<!-- |
| 201 | +## Safeguards |
| 202 | +--> |
| 203 | +## 保护措施 {#safeguards} |
| 204 | +
|
| 205 | +<!-- |
| 206 | +The Kubernetes control plane and the kube-proxy on each node apply some |
| 207 | +safeguard rules before using Topology Aware Hints. If these don't check out, |
| 208 | +the kube-proxy selects endpoints from anywhere in your cluster, regardless of the |
| 209 | +zone. |
| 210 | +--> |
| 211 | +Kubernetes 控制平面和每个节点上的 kube-proxy 在使用拓扑感知提示信息前,会应用一些保护措施规则。 |
| 212 | +如果规则无法顺利通过,kube-proxy 将无视区域限制,从集群中的任意位置选择端点。 |
| 213 | +
|
| 214 | +<!-- |
| 215 | +1. **Insufficient number of endpoints:** If there are less endpoints than zones |
| 216 | + in a cluster, the controller will not assign any hints. |
| 217 | +--> |
| 218 | +1. **端点数量不足:** 如果一个集群中,端点数量少于区域数量,控制器不创建任何提示。 |
| 219 | +
|
| 220 | +<!-- |
| 221 | +2. **Impossible to achieve balanced allocation:** In some cases, it will be |
| 222 | + impossible to achieve a balanced allocation of endpoints among zones. For |
| 223 | + example, if zone-a is twice as large as zone-b, but there are only 2 |
| 224 | + endpoints, an endpoint allocated to zone-a may receive twice as much traffic |
| 225 | + as zone-b. The controller does not assign hints if it can't get this "expected |
| 226 | + overload" value below an acceptable threshold for each zone. Importantly this |
| 227 | + is not based on real-time feedback. It is still possible for individual |
| 228 | + endpoints to become overloaded. |
| 229 | +--> |
| 230 | +2. **不可能实现均衡分配:** 在一些场合中,不可能实现端点在区域中的平衡分配。 |
| 231 | + 例如,假设 zone-a 比 zone-b 大两倍,但只有 2 个端点, |
| 232 | + 那分配到 zone-a 的端点可能收到比 zone-b 多两倍的流量。 |
| 233 | + 如果控制器不能确保此“期望的过载”值低于每一个区域可接受的阈值,控制器将不添加提示信息。 |
| 234 | + 重要的是,这不是基于实时反馈。所以对于特定的端点仍有可能超载。 |
| 235 | +
|
| 236 | +<!-- |
| 237 | +3. **One or more Nodes has insufficient information:** If any node does not have |
| 238 | + a `topology.kubernetes.io/zone` label or is not reporting a value for |
| 239 | + allocatable CPU, the control plane does not set any topology-aware endpoint |
| 240 | + hints and so kube-proxy does not filter endpoints by zone. |
| 241 | +--> |
| 242 | +3. **一个或多个 Node 信息不足:** 如果任一节点没有设置标签 `topology.kubernetes.io/zone`, |
| 243 | + 或没有上报可分配的 CPU 数据,控制平面将不会设置任何拓扑感知提示, |
| 244 | + 进而 kube-proxy 也就不能根据区域来过滤端点。 |
| 245 | + |
| 246 | +<!-- |
| 247 | +4. **One or more endpoints does not have a zone hint:** When this happens, |
| 248 | + the kube-proxy assumes that a transition from or to Topology Aware Hints is |
| 249 | + underway. Filtering endpoints for a Service in this state would be dangerous |
| 250 | + so the kube-proxy falls back to using all endpoints. |
| 251 | +--> |
| 252 | +4. **至少一个端点没有设置区域提示:** 当这种情况发生时, |
| 253 | + kube-proxy 会假设从拓扑感知提示到拓扑感知路由(或反方向)的迁移仍在进行中, |
| 254 | + 在这种场合下过滤 Service 的端点是有风险的,所以 kube-proxy 回退到使用所有端点。 |
| 255 | + |
| 256 | +<!-- |
| 257 | +5. **A zone is not represented in hints:** If the kube-proxy is unable to find |
| 258 | + at least one endpoint with a hint targeting the zone it is running in, it falls |
| 259 | + back to using endpoints from all zones. This is most likely to happen as you add |
| 260 | + a new zone into your existing cluster. |
| 261 | +--> |
| 262 | +5. **提示中不存在某区域:** 如果 kube-proxy 无法找到提示中指向它当前所在的区域的端点, |
| 263 | + 它将回退到使用来自所有区域的端点。当你向现有集群新增新的区域时,这种情况发生概率很高。 |
| 264 | + |
| 265 | +<!-- |
| 266 | +## Constraints |
| 267 | +--> |
| 268 | +## 限制 {#constraints} |
| 269 | + |
| 270 | +<!-- |
| 271 | +* Topology Aware Hints are not used when either `externalTrafficPolicy` or |
| 272 | + `internalTrafficPolicy` is set to `Local` on a Service. It is possible to use |
| 273 | + both features in the same cluster on different Services, just not on the same |
| 274 | + Service. |
| 275 | +--> |
| 276 | +* 当 Service 的 `externalTrafficPolicy` 或 `internalTrafficPolicy` 设置值为 `Local` 时, |
| 277 | + 系统将不使用拓扑感知提示信息。你可以在同一集群中的不同服务上使用这两个特性,但不能在同一个服务上这么做。 |
| 278 | + |
| 279 | +<!-- |
| 280 | +* This approach will not work well for Services that have a large proportion of |
| 281 | + traffic originating from a subset of zones. Instead this assumes that incoming |
| 282 | + traffic will be roughly proportional to the capacity of the Nodes in each |
| 283 | + zone. |
| 284 | +--> |
| 285 | +* 这种方法不适用于大部分流量来自于一部分区域的 Service。 |
| 286 | + 相反,这项技术的假设是入站流量与各区域中节点的服务能力成比例关系。 |
| 287 | + |
| 288 | +<!-- |
| 289 | +* The EndpointSlice controller ignores unready nodes as it calculates the |
| 290 | + proportions of each zone. This could have unintended consequences if a large |
| 291 | + portion of nodes are unready. |
| 292 | +--> |
| 293 | +* EndpointSlice 控制器在计算各区域的比例时,会忽略未就绪的节点。 |
| 294 | + 在大部分节点未就绪的场景下,这样做会带来非预期的结果。 |
| 295 | + |
| 296 | +<!-- |
| 297 | +* The EndpointSlice controller ignores nodes with the |
| 298 | + `node-role.kubernetes.io/control-plane` or `node-role.kubernetes.io/master` |
| 299 | + label set. This could be problematic if workloads are also running on those |
| 300 | + nodes. |
| 301 | +--> |
| 302 | +* EndpointSlice 控制器忽略设置了 `node-role.kubernetes.io/control-plane` 或 |
| 303 | + `node-role.kubernetes.io/master` 标签的节点。如果工作负载也在这些节点上运行,也可能会产生问题。 |
| 304 | + |
| 305 | +<!-- |
| 306 | +* The EndpointSlice controller does not take into account {{< glossary_tooltip |
| 307 | + text="tolerations" term_id="toleration" >}} when deploying or calculating the |
| 308 | + proportions of each zone. If the Pods backing a Service are limited to a |
| 309 | + subset of Nodes in the cluster, this will not be taken into account. |
| 310 | +--> |
| 311 | +* EndpointSlice 控制器在分派或计算各区域的比例时,并不会考虑 |
| 312 | + {{< glossary_tooltip text="容忍度" term_id="toleration" >}}。 |
| 313 | + 如果 Service 背后的各 Pod 被限制只能运行在集群节点的一个子集上,计算比例时不会考虑这点。 |
| 314 | + |
| 315 | +<!-- |
| 316 | +* This may not work well with autoscaling. For example, if a lot of traffic is |
| 317 | + originating from a single zone, only the endpoints allocated to that zone will |
| 318 | + be handling that traffic. That could result in {{< glossary_tooltip |
| 319 | + text="Horizontal Pod Autoscaler" term_id="horizontal-pod-autoscaler" >}} |
| 320 | + either not picking up on this event, or newly added pods starting in a |
| 321 | + different zone. |
| 322 | +--> |
| 323 | +* 这项技术和自动扩缩容机制之间可能存在冲突。例如,如果大量流量来源于同一个区域, |
| 324 | + 那只有分配到该区域的端点才可用来处理流量。这会导致 |
| 325 | + {{< glossary_tooltip text="Pod 自动水平扩缩容" term_id="horizontal-pod-autoscaler" >}} |
| 326 | + 要么不能处理这种场景,要么会在别的区域添加 Pod。 |
| 327 | + |
| 328 | +<!-- |
| 329 | +## Custom heuristics |
| 330 | +--> |
| 331 | +## 自定义启发方式 {#custom-heuristics} |
| 332 | + |
| 333 | +<!-- |
| 334 | +Kubernetes is deployed in many different ways, there is no single heuristic for |
| 335 | +allocating endpoints to zones will work for every use case. A key goal of this |
| 336 | +feature is to enable custom heuristics to be developed if the built in heuristic |
| 337 | +does not work for your use case. The first steps to enable custom heuristics |
| 338 | +were included in the 1.27 release. This is a limited implementation that may not |
| 339 | +yet cover some relevant and plausible situations. |
| 340 | +--> |
| 341 | +Kubernetes 的部署方式有很多种,没有一种按区域分配端点的启发式方法能够适用于所有场景。 |
| 342 | +此特性的一个关键目标是:如果内置的启发方式不能满足你的使用场景,则可以开发自定义的启发方式。 |
| 343 | +启用自定义启发方式的第一步包含在了 1.27 版本中。 |
| 344 | +这是一个限制性较强的实现,可能尚未涵盖一些重要的、可进一步探索的场景。 |
| 345 | + |
| 346 | +## {{% heading "whatsnext" %}} |
| 347 | + |
| 348 | +<!-- |
| 349 | +* Follow the [Connecting Applications with Services](/docs/tutorials/services/connect-applications-service/) tutorial |
| 350 | +--> |
| 351 | +* 参阅[使用 Service 连接到应用](/zh-cn/docs/tutorials/services/connect-applications-service/)教程 |
0 commit comments