diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index 94d24258c6d83..dbef974751260 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -413,105 +413,6 @@ The IP address that you choose must be a valid IPv4 or IPv6 address from within 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. - -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/). - -## 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 (`.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 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. - -### 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. - ## Publishing Services (ServiceTypes) {#publishing-services-service-types} For some parts of your application (for example, frontends) you may want to expose a @@ -1178,12 +1079,96 @@ HTTP requests will have a `Host:` header that the origin server does not recogni TLS servers will not be able to provide a certificate matching the hostname that the client connected to. {{< /warning >}} -{{< 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/). -{{< /note >}} +## 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 +``` + + +### 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. + +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/). -### External IPs +## External IPs 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,