Service

Expose an application running in your cluster behind a single outward-facing endpoint, even when the workload is split across multiple backends.

In Kubernetes, a Service is a method for exposing a network application that is running as one or morePods in your cluster.

A key aim of Services in Kubernetes is that you don't need to modify your existingapplication to use an unfamiliar service discovery mechanism.You can run code in Pods, whether this is a code designed for a cloud-native world, oran older app you've containerized. You use a Service to make that set of Pods availableon the network so that clients can interact with it.

If you use aDeployment to run your app,that Deployment can create and destroy Pods dynamically. From one moment to the next,you don't know how many of those Pods are working and healthy; you might not even knowwhat those healthy Pods are named.KubernetesPods are created and destroyedto match the desired state of your cluster. Pods are ephemeral resources (you should notexpect that an individual Pod is reliable and durable).

Each Pod gets its own IP address (Kubernetes expects network plugins to ensure this).For a given Deployment in your cluster, the set of Pods running in one moment intime could be different from the set of Pods running that application a moment later.

This leads to a problem: if some set of Pods (call them "backends") providesfunctionality to other Pods (call them "frontends") inside your cluster,how do the frontends find out and keep track of which IP address to connectto, so that the frontend can use the backend part of the workload?

EnterServices.

Services in Kubernetes

The Service API, part of Kubernetes, is an abstraction to help you expose groups ofPods over a network. Each Service object defines a logical set of endpoints (usuallythese endpoints are Pods) along with a policy about how to make those pods accessible.

For example, consider a stateless image-processing backend which is running with3 replicas. Those replicas are fungible—frontends do not care which backendthey use. While the actual Pods that compose the backend set may change, thefrontend clients should not need to be aware of that, nor should they need to keeptrack of the set of backends themselves.

The Service abstraction enables this decoupling.

The set of Pods targeted by a Service is usually determinedby aselector that youdefine.To learn about other ways to define Service endpoints,seeServiceswithout selectors.

If your workload speaks HTTP, you might choose to use anIngress to control how web trafficreaches that workload.Ingress is not a Service type, but it acts as the entry point for yourcluster. An Ingress lets you consolidate your routing rules into a single resource, sothat you can expose multiple components of your workload, running separately in yourcluster, behind a single listener.

TheGateway API for Kubernetesprovides extra capabilities beyond Ingress and Service. You can add Gateway to your cluster -it is a family of extension APIs, implemented usingCustomResourceDefinitions -and then use these to configure access to network services that are running in your cluster.

Cloud-native service discovery

If you're able to use Kubernetes APIs for service discovery in your application,you can query theAPI serverfor matching EndpointSlices. Kubernetes updates the EndpointSlices for a Servicewhenever the set of Pods in a Service changes.

For non-native applications, Kubernetes offers ways to place a network port or loadbalancer in between your application and the backend Pods.

Either way, your workload can use theseservice discoverymechanisms to find the target it wants to connect to.

Defining a Service

A Service is anobject(the same way that a Pod or a ConfigMap is an object). You can create,view or modify Service definitions using the Kubernetes API. Usuallyyou use a tool such askubectl to make those API calls for you.

For example, suppose you have a set of Pods that each listen on TCP port 9376and are labelled asapp.kubernetes.io/name=MyApp. You can define a Service topublish that TCP listener:

apiVersion:v1kind:Servicemetadata:name:my-servicespec:selector:app.kubernetes.io/name:MyAppports:-protocol:TCPport:80targetPort:9376

Applying this manifest creates a new Service named "my-service" with the defaultClusterIPservice type. The Servicetargets TCP port 9376 on any Pod with theapp.kubernetes.io/name: MyApp label.

Kubernetes assigns this Service an IP address (thecluster IP),that is used by the virtual IP address mechanism. For more details on that mechanism,readVirtual IPs and Service Proxies.

The controller for that Service continuously scans for Pods thatmatch its selector, and then makes any necessary updates to the set ofEndpointSlices for the Service.

The name of a Service object must be a validRFC 1035 label name.

Note:

A Service can mapany incomingport to atargetPort. By default andfor convenience, thetargetPort is set to the same value as theportfield.

Relaxed naming requirements for Service objects

FEATURE STATE:Kubernetes v1.34 [alpha](disabled by default)

TheRelaxedServiceNameValidation feature gate allows Service object names to start with a digit. When this feature gate is enabled, Service object names must be validRFC 1123 label names.

Port definitions

Port definitions in Pods have names, and you can reference these names in thetargetPort attribute of a Service. For example, we can bind thetargetPortof the Service to the Pod port in the following way:

apiVersion:v1kind:Servicemetadata:name:nginx-servicespec:selector:app.kubernetes.io/name:proxyports:-name:name-of-service-portprotocol:TCPport:80targetPort:http-web-svc---apiVersion:v1kind:Podmetadata:name:nginxlabels:app.kubernetes.io/name:proxyspec:containers:-name:nginximage:nginx:stableports:-containerPort:80name:http-web-svc

This works even if there is a mixture of Pods in the Service using a singleconfigured name, with the same network protocol available via differentport numbers. This offers a lot of flexibility for deploying and evolvingyour Services. For example, you can change the port numbers that Pods exposein the next version of your backend software, without breaking clients.

The default protocol for Services isTCP; you can alsouse any othersupported protocol.

Because many Services need to expose more than one port, Kubernetes supportsmultiple port definitions for a single Service.Each port definition can have the sameprotocol, or a different one.

Services without selectors

Services most commonly abstract access to Kubernetes Pods thanks to the selector,but when used with a corresponding set ofEndpointSlicesobjects and without a selector, the Service can abstract other kinds of backends,including ones that run outside the cluster.

For example:

  • You want to have an external database cluster in production, but in yourtest environment you use your own databases.
  • You want to point your Service to a Service in a differentNamespace or on another cluster.
  • You are migrating a workload to Kubernetes. While evaluating the approach,you run only a portion of your backends in Kubernetes.

In any of these scenarios you can define a Servicewithout specifying aselector to match Pods. For example:

apiVersion:v1kind:Servicemetadata:name:my-servicespec:ports:-name:httpprotocol:TCPport:80targetPort:9376

Because this Service has no selector, the corresponding EndpointSliceobjects are not created automatically. You can map the Serviceto the network address and port where it's running, by adding an EndpointSliceobject manually. For example:

apiVersion:discovery.k8s.io/v1kind:EndpointSlicemetadata:name:my-service-1# by convention, use the name of the Service# as a prefix for the name of the EndpointSlicelabels:# You should set the "kubernetes.io/service-name" label.# Set its value to match the name of the Servicekubernetes.io/service-name:my-serviceaddressType:IPv4ports:-name:http# should match with the name of the service port defined aboveappProtocol:httpprotocol:TCPport:9376endpoints:-addresses:-"10.4.5.6"-addresses:-"10.1.2.3"

Custom EndpointSlices

When you create anEndpointSlice object for a Service, you canuse any name for the EndpointSlice. Each EndpointSlice in a namespace must have aunique name. You link an EndpointSlice to a Service by setting thekubernetes.io/service-namelabelon that EndpointSlice.

Note:

The endpoint IPsmust not be: loopback (127.0.0.0/8 for IPv4, ::1/128 for IPv6), orlink-local (169.254.0.0/16 and 224.0.0.0/24 for IPv4, fe80::/64 for IPv6).

The endpoint IP addresses cannot be the cluster IPs of other Kubernetes Services,becausekube-proxy doesn't support virtual IPsas a destination.

For an EndpointSlice that you create yourself, or in your own code,you should also pick a value to use for the labelendpointslice.kubernetes.io/managed-by.If you create your own controller code to manage EndpointSlices, consider using avalue similar to"my-domain.example/name-of-controller". If you are using a thirdparty tool, use the name of the tool in all-lowercase and change spaces and otherpunctuation to dashes (-).If people are directly using a tool such askubectl to manage EndpointSlices,use a name that describes this manual management, such as"staff" or"cluster-admins". You shouldavoid using the reserved value"controller", which identifies EndpointSlicesmanaged by Kubernetes' own control plane.

Accessing a Service without a selector

Accessing a Service without a selector works the same as if it had a selector.In theexample for a Service without a selector,traffic is routed to one of the two endpoints defined inthe EndpointSlice manifest: a TCP connection to 10.1.2.3 or 10.4.5.6, on port 9376.

Note:

The Kubernetes API server does not allow proxying to endpoints that are not mapped topods. Actions such askubectl port-forward service/<service-name> forwardedPort:servicePort where the service has noselector will fail due to this constraint. This prevents the Kubernetes API serverfrom being used as a proxy to endpoints the caller may not be authorized to access.

AnExternalName Service is a special case of Service that does not haveselectors and uses DNS names instead. For more information, see theExternalName section.

EndpointSlices

FEATURE STATE:Kubernetes v1.21 [stable]

EndpointSlices are objects thatrepresent a subset (aslice) of the backing network endpoints for a Service.

Your Kubernetes cluster tracks how many endpoints each EndpointSlice represents.If there are so many endpoints for a Service that a threshold is reached, thenKubernetes adds another empty EndpointSlice and stores new endpoint informationthere.By default, Kubernetes makes a new EndpointSlice once the existing EndpointSlicesall contain at least 100 endpoints. Kubernetes does not make the new EndpointSliceuntil an extra endpoint needs to be added.

SeeEndpointSlices for moreinformation about this API.

Endpoints (deprecated)

FEATURE STATE:Kubernetes v1.33 [deprecated]

The EndpointSlice API is the evolution of the olderEndpointsAPI. The deprecated Endpoints API has several problems relative toEndpointSlice:

  • It does not support dual-stack clusters.
  • It does not contain information needed to support newer features, such astrafficDistribution.
  • It will truncate the list of endpoints if it is too long to fit in a single object.

Because of this, it is recommended that all clients use theEndpointSlice API rather than Endpoints.

Over-capacity endpoints

Kubernetes limits the number of endpoints that can fit in a single Endpointsobject. When there are over 1000 backing endpoints for a Service, Kubernetestruncates the data in the Endpoints object. Because a Service can be linkedwith more than one EndpointSlice, the 1000 backing endpoint limit onlyaffects the legacy Endpoints API.

In that case, Kubernetes selects at most 1000 possible backend endpoints to storeinto the Endpoints object, and sets anannotation on the Endpoints:endpoints.kubernetes.io/over-capacity: truncated.The control plane also removes that annotation if the number of backend Pods drops below 1000.

Traffic is still sent to backends, but any load balancing mechanism that relies on thelegacy Endpoints API only sends traffic to at most 1000 of the available backing endpoints.

The same API limit means that you cannot manually update an Endpoints to have more than 1000 endpoints.

Application protocol

FEATURE STATE:Kubernetes v1.20 [stable]

TheappProtocol field provides a way to specify an application protocol foreach Service port. This is used as a hint for implementations to offerricher behavior for protocols that they understand.The value of this field is mirrored by the correspondingEndpoints and EndpointSlice objects.

This field follows standard Kubernetes label syntax. Valid values are one of:

  • IANA standard service names.

  • Implementation-defined prefixed names such asmycompany.com/my-custom-protocol.

  • Kubernetes-defined prefixed names:

ProtocolDescription
kubernetes.io/h2cHTTP/2 over cleartext as described inRFC 7540
kubernetes.io/wsWebSocket over cleartext as described inRFC 6455
kubernetes.io/wssWebSocket over TLS as described inRFC 6455

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.When using multiple ports for a Service, you must give all of your ports namesso that these are unambiguous.For example:

apiVersion:v1kind:Servicemetadata:name:my-servicespec:selector:app.kubernetes.io/name:MyAppports:-name:httpprotocol:TCPport:80targetPort:9376-name:httpsprotocol:TCPport:443targetPort:9377

Note:

As with Kubernetesnames in general, names for portsmust only contain lowercase alphanumeric characters and-. Port names mustalso start and end with an alphanumeric character.

For example, the names123-abc andweb are valid, but123_abc and-web are not.

Service type

For some parts of your application (for example, frontends) you may want to expose aService onto an external IP address, one that's accessible from outside of yourcluster.

Kubernetes Service types allow you to specify what kind of Service you want.

The availabletype values and their behaviors are:

ClusterIP
Exposes the Service on a cluster-internal IP. Choosing this valuemakes the Service only reachable from within the cluster. This is thedefault that is used if you don't explicitly specify atype for a Service.You can expose the Service to the public internet using anIngress or aGateway.
NodePort
Exposes the Service on each Node's IP at a static port (theNodePort).To make the node port available, Kubernetes sets up a cluster IP address,the same as if you had requested a Service oftype: ClusterIP.
LoadBalancer
Exposes the Service externally using an external load balancer. Kubernetesdoes not directly offer a load balancing component; you must provide one, oryou can integrate your Kubernetes cluster with a cloud provider.
ExternalName
Maps the Service to the contents of theexternalName field (for example,to the hostnameapi.foo.bar.example). The mapping configures your cluster'sDNS server to return aCNAME record with that external hostname value.No proxying of any kind is set up.

Thetype field in the Service API is designed as nested functionality - each leveladds to the previous. However there is an exception to this nested design. You candefine aLoadBalancer Service bydisabling the load balancerNodePort allocation.

type: ClusterIP

This default Service type assigns an IP address from a pool of IP addresses thatyour cluster has reserved for that purpose.

Several of the other types for Service build on theClusterIP type as afoundation.

If you define a Service that has the.spec.clusterIP set to"None" thenKubernetes does not assign an IP address. Seeheadless Servicesfor more information.

Choosing your own IP address

You can specify your own cluster IP address as part of aService creationrequest. To do this, set the.spec.clusterIP field. For example, if youalready have an existing DNS entry that you wish to reuse, or legacy systemsthat 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 theservice-cluster-ip-range CIDR range that is configured for the API server.If you try to create a Service with an invalidclusterIP address value, the APIserver will return a 422 HTTP status code to indicate that there's a problem.

Readavoiding collisionsto learn how Kubernetes helps reduce the risk and impact of two different Servicesboth trying to use the same IP address.

type: NodePort

If you set thetype field toNodePort, the Kubernetes control planeallocates a port from a range specified by--service-node-port-range flag (default: 30000-32767).Each node proxies that port (the same port number on every Node) into your Service.Your Service reports the allocated port in its.spec.ports[*].nodePort field.

Using a NodePort gives you the freedom to set up your own load balancing solution,to configure environments that are not fully supported by Kubernetes, or evento expose one or more nodes' IP addresses directly.

For a node port Service, Kubernetes additionally allocates a port (TCP, UDP orSCTP to match the protocol of the Service). Every node in the cluster configuresitself to listen on that assigned port and to forward traffic to one of the readyendpoints associated with that Service. You'll be able to contact thetype: NodePortService, from outside the cluster, by connecting to any node using the appropriateprotocol (for example: TCP), and the appropriate port (as assigned to that Service).

Choosing your own port

If you want a specific port number, you can specify a value in thenodePortfield. The control plane will either allocate you that port or report thatthe API transaction failed.This means that you need to take care of possible port collisions yourself.You also have to use a valid port number, one that's inside the range configuredfor NodePort use.

Here is an example manifest for a Service oftype: NodePort that specifiesa NodePort value (30007, in this example):

apiVersion:v1kind:Servicemetadata:name:my-servicespec:type:NodePortselector:app.kubernetes.io/name:MyAppports:-port:80# By default and for convenience, the `targetPort` is set to# the same value as the `port` field.targetPort:80# Optional field# By default and for convenience, the Kubernetes control plane# will allocate a port from a range (default: 30000-32767)nodePort:30007

Reserve Nodeport ranges to avoid collisions

The policy for assigning ports to NodePort services applies to both the auto-assignment andthe manual assignment scenarios. When a user wants to create a NodePort service thatuses a specific port, the target port may conflict with another port that has already been assigned.

To avoid this problem, the port range for NodePort services is divided into two bands.Dynamic port assignment uses the upper band by default, and it may use the lower band once theupper band has been exhausted. Users can then allocate from the lower band with a lower risk of port collision.

When using the default NodePort range 30000-32767, the bands are partitioned as follows:

  • Static band: 30000-30085
  • Dynamic band: 30086-32767

SeeAvoid Collisions Assigning Ports to NodePort Servicesfor more details on how the static and dynamic bands are calculated.

Custom IP address configuration fortype: NodePort Services

You can set up nodes in your cluster to use a particular IP address for serving node portservices. You might want to do this if each node is connected to multiple networks (for example:one network for application traffic, and another network for traffic between nodes and thecontrol plane).

If you want to specify particular IP address(es) to proxy the port, you can set the--nodeport-addresses flag for kube-proxy or the equivalentnodePortAddressesfield of thekube-proxy configuration fileto particular IP block(s).

This flag takes a comma-delimited list of IP blocks (e.g.10.0.0.0/8,192.0.2.0/25)to specify IP address ranges that kube-proxy should consider as local to this node.

For example, if you start kube-proxy with the--nodeport-addresses=127.0.0.0/8 flag,kube-proxy only selects the loopback interface for NodePort Services.The default for--nodeport-addresses is an empty list.This means that kube-proxy should consider all available network interfaces for NodePort.(That's also compatible with earlier Kubernetes releases.)

Note:

This Service is visible as<NodeIP>:spec.ports[*].nodePort and.spec.clusterIP:spec.ports[*].port.If the--nodeport-addresses flag for kube-proxy or the equivalent fieldin the kube-proxy configuration file is set,<NodeIP> would be a filterednode IP address (or possibly IP addresses).

type: LoadBalancer

On cloud providers which support external load balancers, setting thetypefield toLoadBalancer provisions a load balancer for your Service.The actual creation of the load balancer happens asynchronously, andinformation about the provisioned balancer is published in the Service's.status.loadBalancer field.For example:

apiVersion:v1kind:Servicemetadata:name:my-servicespec:selector:app.kubernetes.io/name:MyAppports:-protocol:TCPport:80targetPort:9376clusterIP:10.0.171.239type:LoadBalancerstatus:loadBalancer:ingress:-ip:192.0.2.127

Traffic from the external load balancer is directed at the backend Pods. The cloudprovider decides how it is load balanced.

To implement a Service oftype: LoadBalancer, Kubernetes typically starts offby making the changes that are equivalent to you requesting a Service oftype: NodePort. The cloud-controller-manager component then configures the externalload balancer to forward traffic to that assigned node port.

You can configure a load balanced Service toomit assigning a node port, provided that thecloud provider implementation supports this.

Some cloud providers allow you to specify theloadBalancerIP. In those cases, the load-balancer is createdwith the user-specifiedloadBalancerIP. If theloadBalancerIP field is not specified,the load balancer is set up with an ephemeral IP address. If you specify aloadBalancerIPbut your cloud provider does not support the feature, theloadbalancerIP field that youset is ignored.

Note:

The.spec.loadBalancerIP field for a Service was deprecated in Kubernetes v1.24.

This field was under-specified and its meaning varies across implementations.It also cannot support dual-stack networking. This field may be removed in a future API version.

If you're integrating with a provider that supports specifying the load balancer IP address(es)for a Service via a (provider specific) annotation, you should switch to doing that.

If you are writing code for a load balancer integration with Kubernetes, avoid using this field.You can integrate withGateway rather than Service, or youcan define your own (provider specific) annotations on the Service that specify the equivalent detail.

Node liveness impact on load balancer traffic

Load balancer health checks are critical to modern applications. They are used todetermine which server (virtual machine, or IP address) the load balancer shoulddispatch traffic to. The Kubernetes APIs do not define how health checks have to beimplemented for Kubernetes managed load balancers, instead it's the cloud providers(and the people implementing integration code) who decide on the behavior. Loadbalancer health checks are extensively used within the context of supporting theexternalTrafficPolicy field for Services.

Load balancers with mixed protocol types

FEATURE STATE:Kubernetes v1.26 [stable](enabled by default)

By default, for LoadBalancer type of Services, when there is more than one port defined, allports must have the same protocol, and the protocol must be one which is supportedby the cloud provider.

The feature gateMixedProtocolLBService (enabled by default for the kube-apiserver as of v1.24) allows the use ofdifferent protocols for LoadBalancer type of Services, when there is more than one port defined.

Note:

The set of protocols that can be used for load balanced Services is defined by yourcloud provider; they may impose restrictions beyond what the Kubernetes API enforces.

Disabling load balancer NodePort allocation

FEATURE STATE:Kubernetes v1.24 [stable]

You can optionally disable node port allocation for a Service oftype: LoadBalancer, by settingthe fieldspec.allocateLoadBalancerNodePorts tofalse. This should only be used for load balancer implementationsthat route traffic directly to pods as opposed to using node ports. By default,spec.allocateLoadBalancerNodePortsistrue and type LoadBalancer Services will continue to allocate node ports. Ifspec.allocateLoadBalancerNodePortsis set tofalse on an existing Service with allocated node ports, those node ports willnot be de-allocated automatically.You must explicitly remove thenodePorts entry in every Service port to de-allocate those node ports.

Specifying class of load balancer implementation

FEATURE STATE:Kubernetes v1.24 [stable]

For a Service withtype set toLoadBalancer, the.spec.loadBalancerClass fieldenables you to use a load balancer implementation other than the cloud provider default.

By default,.spec.loadBalancerClass is not set and aLoadBalancertype of Service uses the cloud provider's default load balancer implementation if thecluster is configured with a cloud provider using the--cloud-provider componentflag.

If you specify.spec.loadBalancerClass, it is assumed that a load balancerimplementation that matches the specified class is watching for Services.Any default load balancer implementation (for example, the one provided bythe cloud provider) will ignore Services that have this field set.spec.loadBalancerClass can be set on a Service of typeLoadBalancer only.Once set, it cannot be changed.The value ofspec.loadBalancerClass must be a label-style identifier,with an optional prefix such as "internal-vip" or "example.com/internal-vip".Unprefixed names are reserved for end-users.

Load balancer IP address mode

For a Service oftype: LoadBalancer, a controller can set.status.loadBalancer.ingress.ipMode.The.status.loadBalancer.ingress.ipMode specifies how the load-balancer IP behaves.It may be specified only when the.status.loadBalancer.ingress.ip field is also specified.

There are two possible values for.status.loadBalancer.ingress.ipMode: "VIP" and "Proxy".The default value is "VIP" meaning that traffic is delivered to the nodewith the destination set to the load-balancer's IP and port.There are two cases when setting this to "Proxy", depending on how the load-balancerfrom the cloud provider delivers the traffics:

  • If the traffic is delivered to the node then DNATed to the pod, the destination would be set to the node's IP and node port;
  • If the traffic is delivered directly to the pod, the destination would be set to the pod's IP and port.

Service implementations may use this information to adjust traffic routing.

Internal load balancer

In a mixed environment it is sometimes necessary to route traffic from Services inside the same(virtual) network address block.

In a split-horizon DNS environment you would need two Services to be able to route both externaland internal traffic to your endpoints.

To set an internal load balancer, add one of the following annotations to your Servicedepending on the cloud service provider you're using:

Select one of the tabs.

metadata:name:my-serviceannotations:networking.gke.io/load-balancer-type:"Internal"

metadata:name:my-serviceannotations:service.beta.kubernetes.io/aws-load-balancer-scheme:"internal"

metadata:name:my-serviceannotations:service.beta.kubernetes.io/azure-load-balancer-internal:"true"

metadata:name:my-serviceannotations:service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type:"private"

metadata:name:my-serviceannotations:service.beta.kubernetes.io/openstack-internal-load-balancer:"true"

metadata:name:my-serviceannotations:service.beta.kubernetes.io/cce-load-balancer-internal-vpc:"true"

metadata:annotations:service.kubernetes.io/qcloud-loadbalancer-internal-subnetid:subnet-xxxxx

metadata:annotations:service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type:"intranet"

metadata:name:my-serviceannotations:service.beta.kubernetes.io/oci-load-balancer-internal:true

type: ExternalName

Services of type ExternalName map a Service to a DNS name, not to a typical selector such asmy-service orcassandra. You specify these Services with thespec.externalName parameter.

This Service definition, for example, mapsthemy-service Service in theprod namespace tomy.database.example.com:

apiVersion:v1kind:Servicemetadata:name:my-servicenamespace:prodspec:type:ExternalNameexternalName:my.database.example.com

Note:

A Service oftype: 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 IPv4addresses are not resolved by DNS servers.

If you want to map a Service directly to a specific IP address, consider usingheadless Services.

When looking up the hostmy-service.prod.svc.cluster.local, the cluster DNS Servicereturns aCNAME record with the valuemy.database.example.com. Accessingmy-service works in the same way as other Services but with the crucialdifference that redirection happens at the DNS level rather than via proxying orforwarding. Should you later decide to move your database into your cluster, youcan start its Pods, add appropriate selectors or endpoints, and change theService'stype.

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 fromthe name that the ExternalName references.

For protocols that use hostnames this difference may lead to errors or unexpected responses.HTTP requests will have aHost: 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.

Headless Services

Sometimes you don't need load-balancing and a single Service IP. Inthis case, you can create what are termedheadless Services, by explicitlyspecifying"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 handlethese Services, and there is no load balancing or proxying done by the platform for them.

A headless Service allows a client to connect to whichever Pod it prefers, directly. Services that are headless don'tconfigure routes and packet forwarding usingvirtual IP addresses and proxies; instead, headless Services report theendpoint IP addresses of the individual pods via internal DNS records, served through the cluster'sDNS service.To define a headless Service, you make a Service with.spec.type set to ClusterIP (which is also the default fortype),and you additionally set.spec.clusterIP to None.

The string value None is a special case and is not the same as leaving the.spec.clusterIP field unset.

How DNS is automatically configured depends on whether the Service has selectors defined:

With selectors

For headless Services that define selectors, the endpoints controller createsEndpointSlices in the Kubernetes API, and modifies the DNS configuration to returnA 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 doesnot create EndpointSlice objects. However, the DNS system looks for and configureseither:

  • DNS CNAME records fortype: ExternalName Services.
  • DNS A / AAAA records for all IP addresses of the Service's ready endpoints,for all Service types other thanExternalName.
    • For IPv4 endpoints, the DNS system creates A records.
    • For IPv6 endpoints, the DNS system creates AAAA records.

When you define a headless Service without a selector, theport mustmatch thetargetPort.

Discovering services

For clients running inside your cluster, Kubernetes supports two primary modes offinding a Service: environment variables and DNS.

Environment variables

When a Pod is run on a Node, the kubelet adds a set of environment variablesfor 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.

For example, the Serviceredis-primary which exposes TCP port 6379 and has beenallocated cluster IP address 10.0.0.11, produces the following environmentvariables:

REDIS_PRIMARY_SERVICE_HOST=10.0.0.11REDIS_PRIMARY_SERVICE_PORT=6379REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcpREDIS_PRIMARY_PORT_6379_TCP_PORT=6379REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11

Note:

When you have a Pod that needs to access a Service, and you are usingthe environment variable method to publish the port and cluster IP to the clientPods, you must create the Servicebefore 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 toworry about this ordering issue.

Kubernetes also supports and provides variables that are compatible with DockerEngine's "legacy container links" feature.You can readmakeLinkVariablesto see how this is implemented in Kubernetes.

DNS

You can (and almost always should) set up a DNS service for your Kubernetescluster using anadd-on.

A cluster-aware DNS server, such as CoreDNS, watches the Kubernetes API for newServices and creates a set of DNS records for each one. If DNS has been enabledthroughout your cluster then all Pods should automatically be able to resolveServices by their DNS name.

For example, if you have a Service calledmy-service in a Kubernetesnamespacemy-ns, the control plane and the DNS Service acting togethercreate a DNS record formy-service.my-ns. Pods in themy-ns namespaceshould be able to find the service by doing a name lookup formy-service(my-service.my-ns would also work).

Pods in other namespaces must qualify the name asmy-service.my-ns. These nameswill resolve to the cluster IP assigned for the Service.

Kubernetes also supports DNS SRV (Service) records for named ports. If themy-service.my-ns Service has a port namedhttp with the protocol set toTCP, you can do a DNS SRV query for_http._tcp.my-service.my-ns to discoverthe port number forhttp, as well as the IP address.

The Kubernetes DNS server is the only way to accessExternalName Services.You can find more information aboutExternalName resolution inDNS for Services and Pods.

Virtual IP addressing mechanism

ReadVirtual IPs and Service Proxies explains themechanism Kubernetes provides to expose a Service with a virtual IP address.

Traffic policies

You can set the.spec.internalTrafficPolicy and.spec.externalTrafficPolicy fieldsto control how Kubernetes routes traffic to healthy (“ready”) backends.

SeeTraffic Policies for more details.

Traffic distribution control

The.spec.trafficDistribution field provides another way to influence trafficrouting within a Kubernetes Service. While traffic policies focus on strictsemantic guarantees, traffic distribution allows you to expresspreferences(such as routing to topologically closer endpoints). This can help optimize forperformance, cost, or reliability. In Kubernetes 1.35, thefollowing values are supported:

PreferSameZone
Indicates a preference for routing traffic to endpoints that are in the samezone as the client.
PreferSameNode
Indicates a preference for routing traffic to endpoints that are on the samenode as the client.
PreferClose (deprecated)
This is an older alias forPreferSameZone that is less clear aboutthe semantics.

If the field is not set, the implementation will apply its default routing strategy.

SeeTrafficDistribution formore details

Session stickiness

If you want to make sure that connections from a particular client are passed tothe same Pod each time, you can configure session affinity based on the client'sIP address. Readsession affinityto learn more.

External IPs

If there are external IPs that route to one or more cluster nodes, Kubernetes Servicescan be exposed on thoseexternalIPs. When network traffic arrives into the cluster, withthe external IP (as destination IP) and the port matching that Service, rules and routesthat Kubernetes has configured ensure that the traffic is routed to one of the endpointsfor that Service.

When you define a Service, you can specifyexternalIPs for anyservice type.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.externalIPs[] and.spec.ports[].port).

apiVersion:v1kind:Servicemetadata:name:my-servicespec:selector:app.kubernetes.io/name:MyAppports:-name:httpprotocol:TCPport:80targetPort:49152externalIPs:-198.51.100.32

Note:

Kubernetes does not manage allocation ofexternalIPs; these are the responsibilityof the cluster administrator.

API Object

Service is a top-level resource in the Kubernetes REST API. You can find more detailsabout theService API object.

What's next

Learn more about Services and how they fit into Kubernetes:

  • Follow theConnecting Applications with Servicestutorial.
  • Read aboutIngress, whichexposes HTTP and HTTPS routes from outside the cluster to Services withinyour cluster.
  • Read aboutGateway, an extension toKubernetes that provides more flexibility than Ingress.

For more context, read the following: