In Kubernetes, applications run inside short-lived units called Pods. These Pods can appear and disappear as the cluster scales or heals itself. But if your app relies on talking to other Pods — like a frontend needing a backend — how can it reliably connect when Pod IPs keep changing? That’s where Kubernetes Services come in. But it doesn’t stop there. Services also distribute traffic across healthy Pods, ensuring load balancing and high availability by default.
Kubernetes Services are abstractions that connect network traffic to the Pods in your cluster. You must define a Service whenever you want to expose a group of Pods across the network, whether internally within your cluster or to the outside world.
Kubernetes Services are API objects that allow for network exposure of one or more cluster Pods. Services are part of the Kubernetes networking model and expose significant abstractions of underlying lower-level components, which may act differently across different clouds.
Services are required due to the distributed nature of Kubernetes clusters. Applications are deployed as regular Pods that would have thousands of replicas, spread across hundreds of physical compute Nodes. When your app is used by a user, their request must be directed to one of the replicas available, wherever it may be deployed.
Services sit in front of your Pods to achieve this behavior. All network traffic flows into the Service before being redirected to one of the available Pods. Your other apps can then communicate with the service’s IP address or DNS name to reliably access the Pods you’ve exposed.
All Kubernetes Services eventually direct network traffic to the Pods they serve. Kubernetes offers five basic categories of services, each directing traffic to pods differently, and the selection based on visibility and routing needs:
ClusterIP – Standard, inward-facing-only within cluster
NodePort – Exposes service on every node’s IP at a static port
LoadBalancer – Sets up external load balancer for public access (cloud only)
ExternalName – Maps service to an external DNS name, no proxying
Headless – No cluster IP, exposes individual pod IPs
Here’s how the five currently available options compare:
ClusterIP Services
ClusterIP Services assign an IP address that can be used to reach the Service from within your cluster. This type doesn’t expose the Service externally. ClusterIP is the default service type if you don’t use an alternate option. It’s the most frequently used type of service you’ll encounter because it allows simple internal networking for your workloads.
NodePort Services
NodePort Services are made available externally through a known static port binding on all of your Nodes. Therefore, you can access the Service by communicating with the port on any of your cluster’s Nodes. NodePort Services are also provided a cluster IP address that can be utilized in order to access them from inside the cluster, similar to ClusterIP Services.
The use of NodePort Services is usually not recommended. They are limited in their functionality and result in security problems:
Everybody who has access to the port on your Nodes can access the Service.
One port number may be utilized by a single NodePort Service at a time to avoid conflicts.
Each Node in your cluster must listen to the port by default, even though they may not be hosting a Pod that’s part of the Service.
No load-balancing by default: clients get serviced by the Node they connect to.
When a NodePort Service is utilized, it’s usually to make it easier to use your own load-balancing solution that directs traffic from outside the cluster. NodePorts are also handy for temporary debugging, development, and troubleshooting situations in which you want to quickly test various configurations.
LoadBalancer Services
LoadBalancer Services are made available outside your cluster through the use of an external load balancer resource. This will need to have a connection to a provider of load balancers, generally done by integrating your cluster with your cloud environment. Defining a LoadBalancer service will provision a new load balancer infrastructure component in your cloud account automatically. This feature is set up automatically if you’re using a managed Kubernetes service like Amazon EKS or Google GKE.
Once you have established a LoadBalancer service, you can route your public DNS records to the IP address of the provisioned load balancer. This will then route traffic into your Kubernetes Service. LoadBalancers are thus the Service type you should typically use when you want an app made available outside of Kubernetes.
ExternalName Services
ExternalName Services enable you to easily reach external resources from within your Kubernetes cluster. In contrast to the other Service types, they don’t forward traffic to your Pods.
When you define an ExternalName Service, you must populate the spec.externalName field in the manifest to the external address you wish to route to (e.g., example.com). Kubernetes will add a CNAME DNS record to your cluster that maps the Service’s internal address (e.g., my-external-service.app-namespace.svc.cluster.local) to the external address (example.com). This makes it easy to modify the external address later on, without updating the workloads that reference it.
Headless Services
Headless services are a special kind of Service that do not offer load balancing or a cluster IP address. They’re “headless” because Kubernetes will not automatically proxy any traffic through them. This lets you use DNS lookups to find the individual IP addresses of any Pods chosen by the Service.
A headless service comes in handy when you prefer to communicate with other service discovery systems while not having kube-proxy in the way. You can establish a headless one by explicitly setting a Service’s spec.clusterIP field to the None value.