From 73ea29af3a949a8108199731d1a3972712c244d6 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 19 Dec 2022 21:41:32 +0000 Subject: [PATCH] Revise Service concept These changes reorganize the structure of the page to provide a new focus on the 4 types of Service. --- .../concepts/services-networking/service.md | 421 ++++++++++-------- 1 file changed, 232 insertions(+), 189 deletions(-) diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index d096096ec2ae1..9708c08321d22 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -94,8 +94,7 @@ mechanisms to find the target it wants to connect to. ## Defining a Service -A Service in Kubernetes is an -{{< glossary_tooltip text="object" term_id="object" >}} +A Service is an {{< glossary_tooltip text="object" term_id="object" >}} (the same way that a Pod or a ConfigMap is an object). You can create, view or modify Service definitions using the Kubernetes API. Usually you use a tool such as `kubectl` to make those API calls for you. @@ -139,6 +138,8 @@ for convenience, the `targetPort` is set to the same value as the `port` field. {{< /note >}} +### Port definitions {#field-spec-ports} + Port definitions in Pods have names, and you can reference these names in the `targetPort` attribute of a Service. For example, we can bind the `targetPort` of the Service to the Pod port in the following way: @@ -184,8 +185,8 @@ The default protocol for Services is [TCP](/docs/reference/networking/service-protocols/#protocol-tcp); you can also use any other [supported protocol](/docs/reference/networking/service-protocols/). -As many Services need to expose more than one port, Kubernetes supports multiple -port definitions on a Service object. +Because many Services need to expose more than one port, Kubernetes supports +[multiple port definitions](#multi-port-services) for a single Service. Each port definition can have the same `protocol`, or a different one. ### Services without selectors @@ -353,7 +354,7 @@ This field follows standard Kubernetes label syntax. Values should either be [IANA standard service names](https://www.iana.org/assignments/service-names) or domain prefixed names such as `mycompany.com/my-custom-protocol`. -## Multi-Port Services +### Multi-port Services For some Services, you need to expose more than one port. Kubernetes lets you configure multiple port definitions on a Service object. @@ -388,157 +389,73 @@ also start and end with an alphanumeric character. For example, the names `123-abc` and `web` are valid, but `123_abc` and `-web` are not. {{< /note >}} -## Choosing your own IP address - -You can specify your own cluster IP address as part of a `Service` creation -request. To do this, set the `.spec.clusterIP` field. For example, if you -already have an existing DNS entry that you wish to reuse, or legacy systems -that are configured for a specific IP address and difficult to re-configure. - -The IP address that you choose must be a valid IPv4 or IPv6 address from within the -`service-cluster-ip-range` CIDR range that is configured for the API server. -If you try to create a Service with an invalid clusterIP address value, the API -server will return a 422 HTTP status code to indicate that there's a problem. - -## Discovering services - -Kubernetes supports 2 primary modes of finding a Service - environment -variables and DNS. - -### Environment variables - -When a Pod is run on a Node, the kubelet adds a set of environment variables -for each active Service. It adds `{SVCNAME}_SERVICE_HOST` and `{SVCNAME}_SERVICE_PORT` variables, -where the Service name is upper-cased and dashes are converted to underscores. -It also supports variables (see [makeLinkVariables](https://github.com/kubernetes/kubernetes/blob/dd2d12f6dc0e654c15d5db57a5f9f6ba61192726/pkg/kubelet/envvars/envvars.go#L72)) -that are compatible with Docker Engine's -"_[legacy container links](https://docs.docker.com/network/links/)_" feature. - -For example, the Service `redis-primary` which exposes TCP port 6379 and has been -allocated cluster IP address 10.0.0.11, produces the following environment -variables: - -```shell -REDIS_PRIMARY_SERVICE_HOST=10.0.0.11 -REDIS_PRIMARY_SERVICE_PORT=6379 -REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379 -REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379 -REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcp -REDIS_PRIMARY_PORT_6379_TCP_PORT=6379 -REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11 -``` - -{{< note >}} -When you have a Pod that needs to access a Service, and you are using -the environment variable method to publish the port and cluster IP to the client -Pods, you must create the Service *before* the client Pods come into existence. -Otherwise, those client Pods won't have their environment variables populated. - -If you only use DNS to discover the cluster IP for a Service, you don't need to -worry about this ordering issue. -{{< /note >}} - -### DNS - -You can (and almost always should) set up a DNS service for your Kubernetes -cluster using an [add-on](/docs/concepts/cluster-administration/addons/). -A cluster-aware DNS server, such as CoreDNS, watches the Kubernetes API for new -Services and creates a set of DNS records for each one. If DNS has been enabled -throughout your cluster then all Pods should automatically be able to resolve -Services by their DNS name. +## Service type {#publishing-services-service-types} -For example, if you have a Service called `my-service` in a Kubernetes -namespace `my-ns`, the control plane and the DNS Service acting together -create a DNS record for `my-service.my-ns`. Pods in the `my-ns` namespace -should be able to find the service by doing a name lookup for `my-service` -(`my-service.my-ns` would also work). +For some parts of your application (for example, frontends) you may want to expose a +Service onto an external IP address, one that's accessible from outside of your +cluster. -Pods in other namespaces must qualify the name as `my-service.my-ns`. These names -will resolve to the cluster IP assigned for the Service. +Kubernetes Service types allow you to specify what kind of Service you want. -Kubernetes also supports DNS SRV (Service) records for named ports. If the -`my-service.my-ns` Service has a port named `http` with the protocol set to -`TCP`, you can do a DNS SRV query for `_http._tcp.my-service.my-ns` to discover -the port number for `http`, as well as the IP address. +The available `type` values and their behaviors are: -The Kubernetes DNS server is the only way to access `ExternalName` Services. -You can find more information about `ExternalName` resolution in -[DNS for Services and Pods](/docs/concepts/services-networking/dns-pod-service/). +[`ClusterIP`](#type-clusterip) +: Exposes the Service on a cluster-internal IP. Choosing this value + makes the Service only reachable from within the cluster. This is the + default that is used if you don't explicitly specify a `type` for a Service. + You can expose the Service to the public internet using an [Ingress](/docs/concepts/services-networking/ingress/) or a + [Gateway](https://gateway-api.sigs.k8s.io/). -## Headless Services +[`NodePort`](#type-nodeport) +: Exposes the Service on each Node's IP at a static port (the `NodePort`). + To make the node port available, Kubernetes sets up a cluster IP address, + the same as if you had requested a Service of `type: ClusterIP`. -Sometimes you don't need load-balancing and a single Service IP. In -this case, you can create what are termed "headless" Services, by explicitly -specifying `"None"` for the cluster IP (`.spec.clusterIP`). +[`LoadBalancer`](#loadbalancer) +: Exposes the Service externally using an external load balancer. Kubernetes + does not directly offer a load balancing component; you must provide one, or + you can integrate your Kubernetes cluster with a cloud provider. -You can use a headless Service to interface with other service discovery mechanisms, -without being tied to Kubernetes' implementation. +[`ExternalName`](#externalname) +: Maps the Service to the contents of the `externalName` field (for example, + to the hostname `api.foo.bar.example`). The mapping configures your cluster's + DNS server to return a `CNAME` record with that external hostname value. + No proxying of any kind is set up. -For headless `Services`, a cluster IP is not allocated, kube-proxy does not handle -these Services, and there is no load balancing or proxying done by the platform -for them. How DNS is automatically configured depends on whether the Service has -selectors defined: +The `type` field in the Service API is designed as nested functionality - each level +adds to the previous. This is not strictly required on all cloud providers, but +the Kubernetes API design for Service requires it anyway. -### With selectors +### `type: ClusterIP` {#type-clusterip} -For headless Services that define selectors, the Kubernetes control plane creates -EndpointSlice objects in the Kubernetes API, and modifies the DNS configuration to return -A or AAAA records (IPv4 or IPv6 addresses) that point directly to the Pods backing -the Service. +This default Service type assigns an IP address from a pool of IP addresses that +your cluster has reserved for that purpose. -### Without selectors +Several of the other types for Service build on the `ClusterIP` type as a +foundation. -For headless Services that do not define selectors, the control plane does -not create EndpointSlice objects. However, the DNS system looks for and configures -either: +If you define a Service that has the `.spec.clusterIP` set to `"None"` then +Kubernetes does not assign an IP address. See [headless Services](#headless-services) +for more information. -* DNS CNAME records for [`type: ExternalName`](#externalname) Services. -* DNS A / AAAA records for all IP addresses of the Service's ready endpoints, - for all Service types other than `ExternalName`. - * For IPv4 endpoints, the DNS system creates A records. - * For IPv6 endpoints, the DNS system creates AAAA records. +#### Choosing your own IP address -## Publishing Services (ServiceTypes) {#publishing-services-service-types} - -For some parts of your application (for example, frontends) you may want to expose a -Service onto an external IP address, that's outside of your cluster. +You can specify your own cluster IP address as part of a `Service` creation +request. To do this, set the `.spec.clusterIP` field. For example, if you +already have an existing DNS entry that you wish to reuse, or legacy systems +that are configured for a specific IP address and difficult to re-configure. -Kubernetes `ServiceTypes` allow you to specify what kind of Service you want. +The IP address that you choose must be a valid IPv4 or IPv6 address from within the +`service-cluster-ip-range` CIDR range that is configured for the API server. +If you try to create a Service with an invalid `clusterIP` address value, the API +server will return a 422 HTTP status code to indicate that there's a problem. -`Type` values and their behaviors are: +Read [avoiding collisions](#avoiding-collisions) +to learn how Kubernetes helps reduce the risk and impact of two different Services +both trying to use the same IP address. -* `ClusterIP`: Exposes the Service on a cluster-internal IP. Choosing this value - makes the Service only reachable from within the cluster. This is the - default that is used if you don't explicitly specify a `type` for a Service. - You can expose the service to the public with an [Ingress](/docs/concepts/services-networking/ingress/) or the - [Gateway API](https://gateway-api.sigs.k8s.io/). -* [`NodePort`](#type-nodeport): Exposes the Service on each Node's IP at a static port - (the `NodePort`). - To make the node port available, Kubernetes sets up a cluster IP address, - the same as if you had requested a Service of `type: ClusterIP`. -* [`LoadBalancer`](#loadbalancer): Exposes the Service externally using a cloud - provider's load balancer. -* [`ExternalName`](#externalname): Maps the Service to the contents of the - `externalName` field (e.g. `foo.bar.example.com`), by returning a `CNAME` record - with its value. No proxying of any kind is set up. - {{< note >}} - You need either `kube-dns` version 1.7 or CoreDNS version 0.0.8 or higher - to use the `ExternalName` type. - {{< /note >}} - -The `type` field was designed as nested functionality - each level adds to the -previous. This is not strictly required on all cloud providers (for example: Google -Compute Engine does not need to allocate a node port to make `type: LoadBalancer` work, -but another cloud provider integration might do). Although strict nesting is not required, -but the Kubernetes API design for Service requires it anyway. - -You can also use [Ingress](/docs/concepts/services-networking/ingress/) to expose your Service. -Ingress is not a Service type, but it acts as the entry point for your cluster. -It lets you consolidate your routing rules into a single resource as it can expose multiple -services under the same IP address. - -### Type NodePort {#type-nodeport} +### `type: NodePort` {#type-nodeport} If you set the `type` field to `NodePort`, the Kubernetes control plane allocates a port from a range specified by `--service-node-port-range` flag (default: 30000-32767). @@ -566,7 +483,7 @@ You also have to use a valid port number, one that's inside the range configured for NodePort use. Here is an example manifest for a Service of `type: NodePort` that specifies -a NodePort value (30007, in this example). +a NodePort value (30007, in this example): ```yaml apiVersion: v1 @@ -613,7 +530,7 @@ If the `--nodeport-addresses` flag for kube-proxy or the equivalent field in the kube-proxy configuration file is set, `` would be a filtered node IP address (or possibly IP addresses). {{< /note >}} -### Type LoadBalancer {#loadbalancer} +### `type: LoadBalancer` {#loadbalancer} On cloud providers which support external load balancers, setting the `type` field to `LoadBalancer` provisions a load balancer for your Service. @@ -642,19 +559,21 @@ status: - ip: 192.0.2.127 ``` -Traffic from the external load balancer is directed at the backend Pods. -The cloud provider decides how it is load balanced. +Traffic from the external load balancer is directed at the backend Pods. The cloud +provider decides how it is load balanced. + +Some cloud providers allow you to specify the `loadBalancerIP` field. In those +cases, the load-balancer is created with the user-specified `loadBalancerIP`. If the +`loadBalancerIP` field is not specified, the load balancer is set up with an ephemeral +IP address. -Some cloud providers allow you to specify the `loadBalancerIP`. In those cases, the load-balancer is created -with the user-specified `loadBalancerIP`. If the `loadBalancerIP` field is not specified, -the loadBalancer is set up with an ephemeral IP address. If you specify a `loadBalancerIP` -but your cloud provider does not support the feature, the `loadbalancerIP` field that you -set is ignored. +If you specify a `loadBalancerIP` but your cloud provider does not support the feature, +the value of the `loadbalancerIP` field that you set is ignored. To implement a Service of `type: LoadBalancer`, Kubernetes typically starts off by making the changes that are equivalent to you requesting a Service of -`type: NodePort`. The cloud-controller-manager component then configures the external load balancer to -forward traffic to that assigned node port. +`type: NodePort`. The cloud-controller-manager component then configures the external +load balancer to forward traffic to that assigned node port. You can configure a load balanced Service to [omit](#load-balancer-nodeport-allocation) assigning a node port, provided that the @@ -688,17 +607,15 @@ The feature gate `MixedProtocolLBService` (enabled by default for the kube-apise different protocols for LoadBalancer type of Services, when there is more than one port defined. {{< note >}} - -The set of protocols that can be used for LoadBalancer type of Services is still defined by the cloud provider. If a -cloud provider does not support mixed protocols they will provide only a single protocol. - +The set of protocols that can be used for load balanced Services is defined by your +cloud provider; they may impose restrictions beyond what the Kubernetes API enforces. {{< /note >}} #### Disabling load balancer NodePort allocation {#load-balancer-nodeport-allocation} {{< feature-state for_k8s_version="v1.24" state="stable" >}} -You can optionally disable node port allocation for a Service of `type=LoadBalancer`, by setting +You can optionally disable node port allocation for a Service of `type: LoadBalancer`, by setting the field `spec.allocateLoadBalancerNodePorts` to `false`. This should only be used for load balancer implementations that route traffic directly to pods as opposed to using node ports. By default, `spec.allocateLoadBalancerNodePorts` is `true` and type LoadBalancer Services will continue to allocate node ports. If `spec.allocateLoadBalancerNodePorts` @@ -709,11 +626,15 @@ You must explicitly remove the `nodePorts` entry in every Service port to de-all {{< feature-state for_k8s_version="v1.24" state="stable" >}} -`spec.loadBalancerClass` enables you to use a load balancer implementation other than the cloud provider default. -By default, `spec.loadBalancerClass` is `nil` and a `LoadBalancer` type of Service uses -the cloud provider's default load balancer implementation if the cluster is configured with -a cloud provider using the `--cloud-provider` component flag. -If `spec.loadBalancerClass` is specified, it is assumed that a load balancer +For a Service with `type` set to `LoadBalancer`, the `.spec.loadBalancerClass` field +enables you to use a load balancer implementation other than the cloud provider default. + +By default, `.spec.loadBalancerClass` is not set and a `LoadBalancer` +type of Service uses the cloud provider's default load balancer implementation if the +cluster is configured with a cloud provider using the `--cloud-provider` component +flag. + +If you specify `.spec.loadBalancerClass`, it is assumed that a load balancer implementation that matches the specified class is watching for Services. Any default load balancer implementation (for example, the one provided by the cloud provider) will ignore Services that have this field set. @@ -1108,7 +1029,9 @@ in those modified security groups. Further documentation on annotations for Elastic IPs and other common use-cases may be found in the [AWS Load Balancer Controller documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/). -### Type ExternalName {#externalname} +### `type: ExternalName` {#externalname} + + Services of type ExternalName map a Service to a DNS name, not to a typical selector such as `my-service` or `cassandra`. You specify these Services with the `spec.externalName` parameter. @@ -1128,10 +1051,11 @@ spec: ``` {{< note >}} -ExternalName accepts an IPv4 address string, but as a DNS name comprised of digits, not as an IP address. -ExternalNames that resemble IPv4 addresses are not resolved by CoreDNS or ingress-nginx because ExternalName -is intended to specify a canonical DNS name. To hardcode an IP address, consider using -[headless Services](#headless-services). +A Service of `type: ExternalName` accepts an IPv4 address string, but treats that string as a DNS name comprised of digits, +not as an IP address (the internet does not however allow such names in DNS). Services with external names that resemble IPv4 +addresses are not resolved by DNS servers. + +If you want to map a Service directly to a specific IP address, consider using [headless Services](#headless-services). {{< /note >}} When looking up the host `my-service.prod.svc.cluster.local`, the cluster DNS Service @@ -1142,7 +1066,7 @@ forwarding. Should you later decide to move your database into your cluster, you can start its Pods, add appropriate selectors or endpoints, and change the Service's `type`. -{{< warning >}} +{{< caution >}} You may have trouble using ExternalName for some common protocols, including HTTP and HTTPS. If you use ExternalName then the hostname used by clients inside your cluster is different from the name that the ExternalName references. @@ -1150,22 +1074,151 @@ the name that the ExternalName references. For protocols that use hostnames this difference may lead to errors or unexpected responses. HTTP requests will have a `Host:` header that the origin server does not recognize; TLS servers will not be able to provide a certificate matching the hostname that the client connected to. -{{< /warning >}} +{{< /caution >}} + +## Headless Services + +Sometimes you don't need load-balancing and a single Service IP. In +this case, you can create what are termed _headless Services_, by explicitly +specifying `"None"` for the cluster IP address (`.spec.clusterIP`). + +You can use a headless Service to interface with other service discovery mechanisms, +without being tied to Kubernetes' implementation. + +For headless Services, a cluster IP is not allocated, kube-proxy does not handle +these Services, and there is no load balancing or proxying done by the platform +for them. How DNS is automatically configured depends on whether the Service has +selectors defined: + +### With selectors + +For headless Services that define selectors, the endpoints controller creates +EndpointSlices in the Kubernetes API, and modifies the DNS configuration to return +A or AAAA records (IPv4 or IPv6 addresses) that point directly to the Pods backing the Service. + +### Without selectors + +For headless Services that do not define selectors, the control plane does +not create EndpointSlice objects. However, the DNS system looks for and configures +either: + +* DNS CNAME records for [`type: ExternalName`](#externalname) Services. +* DNS A / AAAA records for all IP addresses of the Service's ready endpoints, + for all Service types other than `ExternalName`. + * For IPv4 endpoints, the DNS system creates A records. + * For IPv6 endpoints, the DNS system creates AAAA records. + +## Discovering services + +For clients running inside your cluster, Kubernetes supports two primary modes of +finding a Service: environment variables and DNS. + +### Environment variables + +When a Pod is run on a Node, the kubelet adds a set of environment variables +for each active Service. It adds `{SVCNAME}_SERVICE_HOST` and `{SVCNAME}_SERVICE_PORT` variables, +where the Service name is upper-cased and dashes are converted to underscores. +It also supports variables (see [makeLinkVariables](https://github.com/kubernetes/kubernetes/blob/dd2d12f6dc0e654c15d5db57a5f9f6ba61192726/pkg/kubelet/envvars/envvars.go#L72)) +that are compatible with Docker Engine's +"_[legacy container links](https://docs.docker.com/network/links/)_" feature. + +For example, the Service `redis-primary` which exposes TCP port 6379 and has been +allocated cluster IP address 10.0.0.11, produces the following environment +variables: + +```shell +REDIS_PRIMARY_SERVICE_HOST=10.0.0.11 +REDIS_PRIMARY_SERVICE_PORT=6379 +REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379 +REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379 +REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcp +REDIS_PRIMARY_PORT_6379_TCP_PORT=6379 +REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11 +``` {{< note >}} -This section is indebted to the [Kubernetes Tips - Part -1](https://akomljen.com/kubernetes-tips-part-1/) blog post from [Alen Komljen](https://akomljen.com/). +When you have a Pod that needs to access a Service, and you are using +the environment variable method to publish the port and cluster IP to the client +Pods, you must create the Service *before* the client Pods come into existence. +Otherwise, those client Pods won't have their environment variables populated. + +If you only use DNS to discover the cluster IP for a Service, you don't need to +worry about this ordering issue. {{< /note >}} -### External IPs +Kubernetes also supports and provides variables that are compatible with Docker +Engine's "_[legacy container links](https://docs.docker.com/network/links/)_" feature. +You can read [`makeLinkVariables`](https://github.com/kubernetes/kubernetes/blob/dd2d12f6dc0e654c15d5db57a5f9f6ba61192726/pkg/kubelet/envvars/envvars.go#L72) +to see how this is implemented in Kubernetes. -If there are external IPs that route to one or more cluster nodes, Kubernetes Services can be exposed on those -`externalIPs`. Traffic that ingresses into the cluster with the external IP (as destination IP), on the Service port, -will be routed to one of the Service endpoints. `externalIPs` are not managed by Kubernetes and are the responsibility -of the cluster administrator. +### DNS -In the Service spec, `externalIPs` can be specified along with any of the `ServiceTypes`. -In the example below, "`my-service`" can be accessed by clients on "`198.51.100.32:80`" (`externalIP:port`) +You can (and almost always should) set up a DNS service for your Kubernetes +cluster using an [add-on](/docs/concepts/cluster-administration/addons/). + +A cluster-aware DNS server, such as CoreDNS, watches the Kubernetes API for new +Services and creates a set of DNS records for each one. If DNS has been enabled +throughout your cluster then all Pods should automatically be able to resolve +Services by their DNS name. + +For example, if you have a Service called `my-service` in a Kubernetes +namespace `my-ns`, the control plane and the DNS Service acting together +create a DNS record for `my-service.my-ns`. Pods in the `my-ns` namespace +should be able to find the service by doing a name lookup for `my-service` +(`my-service.my-ns` would also work). + +Pods in other namespaces must qualify the name as `my-service.my-ns`. These names +will resolve to the cluster IP assigned for the Service. + +Kubernetes also supports DNS SRV (Service) records for named ports. If the +`my-service.my-ns` Service has a port named `http` with the protocol set to +`TCP`, you can do a DNS SRV query for `_http._tcp.my-service.my-ns` to discover +the port number for `http`, as well as the IP address. + +The Kubernetes DNS server is the only way to access `ExternalName` Services. +You can find more information about `ExternalName` resolution in +[DNS for Services and Pods](/docs/concepts/services-networking/dns-pod-service/). + + + + + + + + + + +## Virtual IP addressing mechanism + +Read [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) explains the +mechanism Kubernetes provides to expose a Service with a virtual IP address. + +### Traffic policies + +You can set the `.spec.internalTrafficPolicy` and `.spec.externalTrafficPolicy` fields +to control how Kubernetes routes traffic to healthy (“ready”) backends. + +See [Traffic Policies](/docs/reference/networking/virtual-ips/#traffic-policies) for more details. + +### Session stickiness + +If you want to make sure that connections from a particular client are passed to +the same Pod each time, you can configure session affinity based on the client's +IP address. Read [session affinity](/docs/reference/networking/virtual-ips/#session-affinity) +to learn more. + +## External IPs + +If there are external IPs that route to one or more cluster nodes, Kubernetes Services +can be exposed on those `externalIPs`. When network traffic arrives into the cluster, with +the external IP (as destination IP) and the port matching that Service, rules and routes +that Kubernetes has configured ensure that the traffic is routed to one of the endpoints +for that Service. + +When you define a Service, you can specify `externalIPs` for any +[service type](#publishing-services-service-types). +In the example below, the Service named `"my-service"` can be accessed by clients using TCP, +on `"198.51.100.32:80"` (calculated from `.spec.externalIP` and `.spec.port`). ```yaml apiVersion: v1 @@ -1184,26 +1237,16 @@ spec: - 198.51.100.32 ``` -## Session stickiness - -If you want to make sure that connections from a particular client are passed to -the same Pod each time, you can configure session affinity based on the client's -IP address. Read [session affinity](/docs/reference/networking/virtual-ips/#session-affinity) -to learn more. +{{< note >}} +Kubernetes does not manage allocation of `externalIPs`; these are the responsibility +of the cluster administrator. +{{< /note >}} ## API Object Service is a top-level resource in the Kubernetes REST API. You can find more details about the [Service API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core). - - - -## Virtual IP addressing mechanism - -Read [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) to learn about the -mechanism Kubernetes provides to expose a Service with a virtual IP address. - ## {{% heading "whatsnext" %}} Learn more about Services and how they fit into Kubernetes: