✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Services and Discovery

Kubernetes Services and Discovery enables consistent communication between containers through abstracted network endpoints and automated service discovery mechanisms.

Kubernetes Services and Discovery is the layer that gives a dynamic, constantly changing set of Pods a stable network identity, and the accompanying mechanisms that let other components locate that identity without hardcoding IP addresses. Because Pods are ephemeral and routinely replaced, an application cannot rely on any individual Pod's address remaining valid; the Service abstraction and its associated discovery mechanisms exist precisely to remove that dependency.


The Service Abstraction

Stable Virtual Identity

A Service defines a stable virtual IP address and DNS name, decoupled from any specific Pod, and a label selector identifying the set of Pods that should receive traffic sent to it. As matching Pods are created, rescheduled, or removed, the set of endpoints behind the Service is updated automatically, while the Service's own address never changes.

apiVersion: v1
kind: Service
metadata:
  name: codartium-api
spec:
  selector:
    app: codartium-api
  ports:
    - port: 80
      targetPort: 8080
endpoints ( t ) = { p pods ( t ) labels ( p ) ⊆ selector }

Endpoints and EndpointSlices

The set of addresses backing a Service is tracked in Endpoints or, in current clusters, the more scalable EndpointSlice objects, continuously updated by a controller watching for Pods matching the Service's selector. kube-proxy on every node watches these objects and programs local packet-forwarding rules accordingly.


Service Types

ClusterIP

The default Service type allocates a virtual IP reachable only from within the cluster, used for internal communication between workloads that do not need to be exposed externally.

NodePort

A NodePort Service additionally opens a static port on every node in the cluster, forwarding traffic received on that port to the Service, providing external reachability without depending on cloud provider load balancing.

LoadBalancer

A LoadBalancer Service requests the provisioning of an external load balancer from the underlying cloud provider, which is configured to forward traffic to the Service, offering externally reachable, provider-managed entry points for cluster workloads.

ExternalName

An ExternalName Service maps a Service name to an external DNS name via a CNAME record, without proxying traffic through the cluster at all, allowing internal workloads to refer to external dependencies through the same discovery mechanism used for internal Services.

apiVersion: v1
kind: Service
metadata:
  name: external-payments
spec:
  type: ExternalName
  externalName: payments.example-provider.com

Headless Services

Setting clusterIP: None creates a headless Service, which does not allocate a virtual IP; instead, DNS queries for the Service return the individual Pod IPs directly, a pattern used by StatefulSets to expose stable, individually addressable identities for each replica.


DNS-Based Discovery

Cluster DNS

Kubernetes clusters run an internal DNS service, typically CoreDNS, which watches Services and Pods and automatically publishes DNS records for them, allowing workloads to discover one another by name rather than by IP address.

<service-name>.<namespace>.svc.cluster.local

Search Domains

Pods are configured with DNS search domains that allow shorter, unqualified names to resolve correctly within the same namespace, so that a Pod in the codartium-team namespace can reach codartium-api directly, while other namespaces must use a more qualified name.

kubectl exec -it debug-pod -- nslookup codartium-api
kubectl exec -it debug-pod -- nslookup codartium-api.codartium-team.svc.cluster.local

Ingress and Layer 7 Routing

Ingress Resource

While Services operate primarily at the transport layer, an Ingress resource describes HTTP and HTTPS routing rules, host-based and path-based, mapping external requests to the appropriate backend Service, along with optional TLS termination.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: codartium-ingress
spec:
  rules:
    - host: api.codartium.example
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: codartium-api
                port:
                  number: 80

Ingress Controllers

An Ingress resource by itself declares intent only; it requires an Ingress controller running in the cluster to actually implement the described routing, commonly by configuring a reverse proxy such as NGINX or a cloud provider's native load balancer.


Service Discovery Beyond DNS

Environment Variables

For each Service that existed at the time a Pod was created, the kubelet injects a set of environment variables describing that Service's address and port into the Pod, an older discovery mechanism largely superseded by DNS but still available for compatibility.

Programmatic Discovery via the API

Because Services, Endpoints, and Pods are all ordinary API objects, any client with appropriate permissions can query the API server directly to discover the current state of a Service's backing Pods, a pattern used by service meshes and custom load-balancing clients that require more control than DNS or kube-proxy alone provide.