📝 Kubernetes

Services and Networking in Kubernetes

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
2 min
👁️
Views
85
🌳
Level
Advanced

Every Pod has an IP address. But pods are mortal: they get recreated, rescheduled onto different nodes, and receive new IPs. How do clients reach them reliably? The answer is a Service.

Why You Need a Service

Imagine you have 3 backend replicas. Each Pod has its own IP. The frontend does not know those IPs in advance, and they change on every restart.

A Service is a stable abstraction over a set of pods. It has a permanent IP (ClusterIP) and a DNS name. Requests to the Service are automatically load-balanced across healthy pods.

Frontend → Service (stable IP: 10.96.45.12)
                ├── Pod 1 (10.244.1.5)
                ├── Pod 2 (10.244.2.8)
                └── Pod 3 (10.244.3.2)

A Service finds its pods by selector (labels). Pods that carry the matching labels are automatically included in the load-balancing pool.

Service Types

ClusterIP (default)

Accessible only inside the cluster. Ideal for internal service-to-service communication.

# service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
    - port: 80          # port on the Service itself
      targetPort: 8000  # port on the container
kubectl apply -f service-clusterip.yaml
kubectl get services
# NAME               TYPE        CLUSTER-IP      PORT(S)   AGE
# backend-service    ClusterIP   10.96.45.12     80/TCP    1m

From any pod in the cluster: curl http://backend-service or curl http://10.96.45.12.

NodePort

Opens a port on every node in the cluster. Accessible from outside via <NodeIP>:<NodePort>.

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 3000
      nodePort: 30080   # range 30000–32767 (optional, can be omitted)
# Access from outside (for example in minikube)
minikube service frontend-service --url
# http://192.168.49.2:30080

Use NodePort for quick debugging and dev environments. Not recommended for production.

LoadBalancer

Provisions an external load balancer through the cloud provider (AWS ELB, GCP Load Balancer). Automatically receives an external IP.

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8080
kubectl get services api-service
# NAME          TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
# api-service   LoadBalancer   10.96.12.34    34.123.45.67     80:31234/TCP   3m

The primary type for production in the cloud. But each LoadBalancer costs money. For many services it is better to use Ingress (one load balancer for all).

ExternalName

An alias for an external DNS name. Useful for migrations or connecting external services.

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

DNS Inside the Cluster

K8s automatically creates DNS records for every Service. Format:

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

Examples of addressing services:

# From the same namespace
curl http://backend-service

# From another namespace
curl http://backend-service.production.svc.cluster.local

# Short form from another namespace
curl http://backend-service.production

DNS is provided by CoreDNS — a Control Plane component. Pods are automatically configured to use the internal DNS.

kubectl expose: Quick Service Creation

# Create a Service for a Deployment
kubectl expose deployment my-app --port=80 --target-port=8000

# Create a NodePort
kubectl expose deployment my-app --type=NodePort --port=80

# Create a LoadBalancer
kubectl expose deployment my-app --type=LoadBalancer --port=80

Comparing Service Types

Type Access When to Use
ClusterIP Inside the cluster only Service-to-service communication
NodePort External, via node IP Dev / testing
LoadBalancer External, via cloud LB Production API in the cloud
ExternalName DNS alias External services

Verifying a Service

# Service details
kubectl describe service backend-service

# Endpoints (live pods behind the Service)
kubectl get endpoints backend-service
# NAME               ENDPOINTS                                    AGE
# backend-service    10.244.1.5:8000,10.244.2.8:8000,...         5m

# Temporary debug pod for network troubleshooting
kubectl run debug --image=busybox -it --rm -- wget -qO- http://backend-service

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Health Checks: Liveness and Readiness in Kubernet…

A container is running — that does not mean the application is working. There might...

📅 30.06.2026 👁️ 93
📝

Resource Limits and Requests in Kubernetes

Without resource constraints a single "greedy" container can consume all the memory on a node...

📅 30.06.2026 👁️ 82
📝

What Is Kubernetes and Why You Need It

Docker packages an application into a container. But what do you do when you have...

📅 30.06.2026 👁️ 85

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!