14.04.2025

What is Kubernetes services?

In the previous article Step-by-Step Guide to Deploy and Manage Kubernetes, we covered the fundamentals of Kubernetes: its architecture, key components (such as Pods, Deployments, and Services), and general principles for cluster deployment and management. Now, we’ll dive deeper into working with Pods—the smallest executable units in Kubernetes. To effectively manage their communication and availability, Kubernetes uses Services, whose general purpose was mentioned earlier.

In this article, we’ll explore the functionality of Services through practical examples: their types (ClusterIP, NodePort, LoadBalancer), YAML manifest configurations, and use cases for ensuring stable communication between application components.

Kubernetes Services Revisited

First, let’s recall what Kubernetes Services are. In short, they are objects that provide stable access to applications in a cluster, even when Pods change dynamically. More comprehensively, Kubernetes Services are a critical mechanism for ensuring stable network communication between application components in a dynamically changing cluster environment. Simply put, Services act as “stable entry points” to a group of Pods, even if the Pods themselves are recreated, scaled, or moved between nodes. Below is an illustration of the main types of Services in K8s:

Image 1 - K8s services

Problems Addressed by Kubernetes Services:

Since Pods in Kubernetes are ephemeral—their IP addresses change during restarts, scaling, or updates—this creates challenges for application components (e.g., frontend and backend) that require a stable communication method.

Kubernetes Services solve these issues through the following actions:
- Fixed Identifiers: Services assign a stable IP address (ClusterIP), DNS name, or external IP, independent of the Pods’ lifecycle.
- Load Balancing: Traffic is automatically distributed across Pods selected via labels (e.g., `app: backend`).
- Auto-Updating: Services dynamically track changes in the set of Pods via EndpointSlices, updating the list of available instances.

Core Kubernetes Service Types with Examples

ClusterIP: For Internal Access to Pods Within the Cluster

Example configuration:

simple-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376

Command to create the Service:

kubectl apply -f simple-service.yaml

Сhecking:

kubectl get services # Viewing ClusterIP
kubectl describe service/my-service # Details Service and Endpoints

LoadBalancer is designed for public access through a cloud load balancer.

Example configuration:

# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376
nodePort: 30007 # Optional (default: random port in range)

Command to create the Service:

kubectl apply -f nodeport-service.yaml

Access:

curl http://:30007 # replace with node IP

ExternalName is designed to link to an external resource via DNS CNAME.

Example configuration:

# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376

Command to create the Service:

kubectl apply -f loadbalancer-service.yaml

Checking the external IP :

kubectl get service/my-loadbalancer -o wide # Viewing EXTERNAL-IP

Headless Service (without ClusterIP) is designed for direct access to Pods without load balancing.

Example configuration:

# externalname-service.yaml
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: my.database.example.com

Command to create the Service:

kubectl apply -f externalname-service.yaml

Usage:
Other Pods can access `external-db` as a DNS name

Headless Service (without ClusterIP) is designed for direct access to Pods without load balancing.

Configuration exmaple:

# headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-headless
spec:
clusterIP: None
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376

Command to create the Service:

kubectl apply -f headless-service.yaml

DNS checking:

nslookup my-headless.default.svc.cluster.local # Returns the IPs of all Pods

Additional examples:

Multi-port Service configuration is designed to simplify setup for applications requiring multiple ports.

Configuration:

# multi-port-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-multi-port
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: metrics
protocol: TCP
port: 9090
targetPort: 9090

Command:

kubectl apply -f multi-port-service.yaml

Service configuration without a selector (manual EndpointSlices) is used to integrate with resources outside Kubernetes

Service configuration:

# service-without-selector.yaml
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376

EndpointSlice configuration is designed for flexible management of endpoints (including external systems):

Configuration:

# endpointslice.yaml
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: my-service-1
labels:
kubernetes.io/service-name: my-external-service
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 9376
endpoints:
- addresses: ["10.4.5.6"]
- addresses: ["10.1.2.3"]

Commands:

kubectl apply -f service-without-selector.yaml
kubectl apply -f endpointslice.yaml

Useful commands:

Viewing all Services is used to display a list of all Services in the current namespace:

kubectl get services

Viewing Endpoints is intended to display a list of Endpoints — the IP addresses and ports of Pods associated with the Service:

kubectl get endpoints

DNS verification for a Service is intended to check the DNS resolution of the Service name within a Pod:

kubectl exec -it -- nslookup

Deletion of a Service is intended to remove the Service from the cluster:

kubectl delete service/