|
| 1 | +--- |
| 2 | +reviewers: |
| 3 | +- johnbelamaric |
| 4 | +- imroc |
| 5 | +title: Service Topology |
| 6 | +feature: |
| 7 | + title: Service Topology |
| 8 | + description: > |
| 9 | + Routing of service traffic based upon cluster topology. |
| 10 | +
|
| 11 | +content_type: concept |
| 12 | +weight: 10 |
| 13 | +--- |
| 14 | + |
| 15 | + |
| 16 | +<!-- overview --> |
| 17 | + |
| 18 | +{{< feature-state for_k8s_version="v1.17" state="alpha" >}} |
| 19 | + |
| 20 | +_Service Topology_ enables a service to route traffic based upon the Node |
| 21 | +topology of the cluster. For example, a service can specify that traffic be |
| 22 | +preferentially routed to endpoints that are on the same Node as the client, or |
| 23 | +in the same availability zone. |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +<!-- body --> |
| 28 | + |
| 29 | +## Introduction |
| 30 | + |
| 31 | +By default, traffic sent to a `ClusterIP` or `NodePort` Service may be routed to |
| 32 | +any backend address for the Service. Since Kubernetes 1.7 it has been possible |
| 33 | +to route "external" traffic to the Pods running on the Node that received the |
| 34 | +traffic, but this is not supported for `ClusterIP` Services, and more complex |
| 35 | +topologies — such as routing zonally — have not been possible. The |
| 36 | +_Service Topology_ feature resolves this by allowing the Service creator to |
| 37 | +define a policy for routing traffic based upon the Node labels for the |
| 38 | +originating and destination Nodes. |
| 39 | + |
| 40 | +By using Node label matching between the source and destination, the operator |
| 41 | +may designate groups of Nodes that are "closer" and "farther" from one another, |
| 42 | +using whatever metric makes sense for that operator's requirements. For many |
| 43 | +operators in public clouds, for example, there is a preference to keep service |
| 44 | +traffic within the same zone, because interzonal traffic has a cost associated |
| 45 | +with it, while intrazonal traffic does not. Other common needs include being able |
| 46 | +to route traffic to a local Pod managed by a DaemonSet, or keeping traffic to |
| 47 | +Nodes connected to the same top-of-rack switch for the lowest latency. |
| 48 | + |
| 49 | + |
| 50 | +## Using Service Topology |
| 51 | + |
| 52 | +If your cluster has Service Topology enabled, you can control Service traffic |
| 53 | +routing by specifying the `topologyKeys` field on the Service spec. This field |
| 54 | +is a preference-order list of Node labels which will be used to sort endpoints |
| 55 | +when accessing this Service. Traffic will be directed to a Node whose value for |
| 56 | +the first label matches the originating Node's value for that label. If there is |
| 57 | +no backend for the Service on a matching Node, then the second label will be |
| 58 | +considered, and so forth, until no labels remain. |
| 59 | + |
| 60 | +If no match is found, the traffic will be rejected, just as if there were no |
| 61 | +backends for the Service at all. That is, endpoints are chosen based on the first |
| 62 | +topology key with available backends. If this field is specified and all entries |
| 63 | +have no backends that match the topology of the client, the service has no |
| 64 | +backends for that client and connections should fail. The special value `"*"` may |
| 65 | +be used to mean "any topology". This catch-all value, if used, only makes sense |
| 66 | +as the last value in the list. |
| 67 | + |
| 68 | +If `topologyKeys` is not specified or empty, no topology constraints will be applied. |
| 69 | + |
| 70 | +Consider a cluster with Nodes that are labeled with their hostname, zone name, |
| 71 | +and region name. Then you can set the `topologyKeys` values of a service to direct |
| 72 | +traffic as follows. |
| 73 | + |
| 74 | +* Only to endpoints on the same node, failing if no endpoint exists on the node: |
| 75 | + `["kubernetes.io/hostname"]`. |
| 76 | +* Preferentially to endpoints on the same node, falling back to endpoints in the |
| 77 | + same zone, followed by the same region, and failing otherwise: `["kubernetes.io/hostname", |
| 78 | + "topology.kubernetes.io/zone", "topology.kubernetes.io/region"]`. |
| 79 | + This may be useful, for example, in cases where data locality is critical. |
| 80 | +* Preferentially to the same zone, but fallback on any available endpoint if |
| 81 | + none are available within this zone: |
| 82 | + `["topology.kubernetes.io/zone", "*"]`. |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +## Constraints |
| 87 | + |
| 88 | +* Service topology is not compatible with `externalTrafficPolicy=Local`, and |
| 89 | + therefore a Service cannot use both of these features. It is possible to use |
| 90 | + both features in the same cluster on different Services, just not on the same |
| 91 | + Service. |
| 92 | + |
| 93 | +* Valid topology keys are currently limited to `kubernetes.io/hostname`, |
| 94 | + `topology.kubernetes.io/zone`, and `topology.kubernetes.io/region`, but will |
| 95 | + be generalized to other node labels in the future. |
| 96 | + |
| 97 | +* Topology keys must be valid label keys and at most 16 keys may be specified. |
| 98 | + |
| 99 | +* The catch-all value, `"*"`, must be the last value in the topology keys, if |
| 100 | + it is used. |
| 101 | + |
| 102 | + |
| 103 | +## Examples |
| 104 | + |
| 105 | +The following are common examples of using the Service Topology feature. |
| 106 | + |
| 107 | +### Only Node Local Endpoints |
| 108 | + |
| 109 | +A Service that only routes to node local endpoints. If no endpoints exist on the node, traffic is dropped: |
| 110 | + |
| 111 | +```yaml |
| 112 | +apiVersion: v1 |
| 113 | +kind: Service |
| 114 | +metadata: |
| 115 | + name: my-service |
| 116 | +spec: |
| 117 | + selector: |
| 118 | + app: my-app |
| 119 | + ports: |
| 120 | + - protocol: TCP |
| 121 | + port: 80 |
| 122 | + targetPort: 9376 |
| 123 | + topologyKeys: |
| 124 | + - "kubernetes.io/hostname" |
| 125 | +``` |
| 126 | +
|
| 127 | +### Prefer Node Local Endpoints |
| 128 | +
|
| 129 | +A Service that prefers node local Endpoints but falls back to cluster wide endpoints if node local endpoints do not exist: |
| 130 | +
|
| 131 | +```yaml |
| 132 | +apiVersion: v1 |
| 133 | +kind: Service |
| 134 | +metadata: |
| 135 | + name: my-service |
| 136 | +spec: |
| 137 | + selector: |
| 138 | + app: my-app |
| 139 | + ports: |
| 140 | + - protocol: TCP |
| 141 | + port: 80 |
| 142 | + targetPort: 9376 |
| 143 | + topologyKeys: |
| 144 | + - "kubernetes.io/hostname" |
| 145 | + - "*" |
| 146 | +``` |
| 147 | +
|
| 148 | +
|
| 149 | +### Only Zonal or Regional Endpoints |
| 150 | +
|
| 151 | +A Service that prefers zonal then regional endpoints. If no endpoints exist in either, traffic is dropped. |
| 152 | +
|
| 153 | +
|
| 154 | +```yaml |
| 155 | +apiVersion: v1 |
| 156 | +kind: Service |
| 157 | +metadata: |
| 158 | + name: my-service |
| 159 | +spec: |
| 160 | + selector: |
| 161 | + app: my-app |
| 162 | + ports: |
| 163 | + - protocol: TCP |
| 164 | + port: 80 |
| 165 | + targetPort: 9376 |
| 166 | + topologyKeys: |
| 167 | + - "topology.kubernetes.io/zone" |
| 168 | + - "topology.kubernetes.io/region" |
| 169 | +``` |
| 170 | +
|
| 171 | +### Prefer Node Local, Zonal, then Regional Endpoints |
| 172 | +
|
| 173 | +A Service that prefers node local, zonal, then regional endpoints but falls back to cluster wide endpoints. |
| 174 | +
|
| 175 | +```yaml |
| 176 | +apiVersion: v1 |
| 177 | +kind: Service |
| 178 | +metadata: |
| 179 | + name: my-service |
| 180 | +spec: |
| 181 | + selector: |
| 182 | + app: my-app |
| 183 | + ports: |
| 184 | + - protocol: TCP |
| 185 | + port: 80 |
| 186 | + targetPort: 9376 |
| 187 | + topologyKeys: |
| 188 | + - "kubernetes.io/hostname" |
| 189 | + - "topology.kubernetes.io/zone" |
| 190 | + - "topology.kubernetes.io/region" |
| 191 | + - "*" |
| 192 | +``` |
| 193 | +
|
| 194 | +
|
| 195 | +
|
| 196 | +
|
| 197 | +## {{% heading "whatsnext" %}} |
| 198 | +
|
| 199 | +
|
| 200 | +* Read about [enabling Service Topology](/docs/tasks/administer-cluster/enabling-service-topology) |
| 201 | +* Read [Connecting Applications with Services](/docs/concepts/services-networking/connect-applications-service/) |
| 202 | +
|
| 203 | +
|
0 commit comments