Services & Networking
BeginnerA Kubernetes Service provides a stable DNS name and IP for a set of pods. ClusterIP for internal, NodePort for development, LoadBalancer for production external traffic, and Ingress for HTTP routing.
Overview
Pods are ephemeral — they come and go, and their IPs change. A Service is a stable abstraction that sits in front of a set of pods (selected by label) and provides a fixed ClusterIP and DNS name. Inside the cluster, any pod can reach another pod's service using its DNS name (my-service.namespace.svc.cluster.local). For external traffic, LoadBalancer Services provision a cloud load balancer, and Ingress controllers route HTTP/HTTPS traffic based on host and path rules — letting you host multiple services behind a single external IP.
Service Types
Kubernetes has four service types. ClusterIP is the default and most common — it creates an internal cluster DNS name. LoadBalancer is the standard for production external access. NodePort is for development or on-prem without cloud load balancers.
# ClusterIP (default) — internal only
apiVersion: v1
kind: Service
metadata:
name: my-api
spec:
type: ClusterIP # accessible only within the cluster
selector:
app: my-api # routes to pods with label app=my-api
ports:
- port: 80 # service port (what clients connect to)
targetPort: 8080 # pod's containerPort
# DNS: my-api.default.svc.cluster.local:80
# Or within same namespace: my-api:80
---
# LoadBalancer — provisions cloud load balancer (GKE, EKS, AKS)
apiVersion: v1
kind: Service
metadata:
name: my-api-external
spec:
type: LoadBalancer
selector:
app: my-api
ports:
- port: 80
targetPort: 8080
# After creation:
# kubectl get svc my-api-external
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# my-api-external LoadBalancer 10.96.24.51 34.102.145.100 80:32045/TCP
# ↑ cloud LB IP (may take ~1 min)
---
# NodePort — exposes on each node's IP at a static port (30000-32767)
spec:
type: NodePort
selector:
app: my-api
ports:
- port: 80
targetPort: 8080
nodePort: 31000 # access via: NodeIP:31000Ingress — HTTP Routing
An Ingress resource defines HTTP routing rules. An Ingress Controller (nginx-ingress, Traefik, AWS ALB) reads these rules and configures the actual load balancer/proxy. One external IP can route to dozens of services.
# Install an ingress controller first (example: nginx-ingress)
# helm install ingress-nginx ingress-nginx/ingress-nginx
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod # auto TLS
spec:
ingressClassName: nginx
tls:
- hosts:
- api.mycompany.com
- app.mycompany.com
secretName: mycompany-tls # TLS cert secret
rules:
- host: api.mycompany.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: backend-api
port: { number: 80 }
- host: app.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port: { number: 80 }
# Traffic flow:
# Internet → Cloud LB (nginx-ingress Service: LoadBalancer)
# → nginx Ingress Controller Pod
# → Routes by host/path → backend-api Service → backend pods
# → frontend Service → frontend podsService Discovery & DNS
CoreDNS runs in every Kubernetes cluster and provides automatic DNS for every Service. Pods discover services by name without any configuration.
# Every Service gets a DNS record automatically:
# <service-name>.<namespace>.svc.cluster.local
# From any pod in the same namespace:
curl http://my-api/health # short form
curl http://my-api.default/health # with namespace
curl http://my-api.default.svc.cluster.local/health # full form
# From a different namespace:
curl http://my-api.production.svc.cluster.local/health
# DNS resolution inside a pod:
kubectl exec -it my-pod -- nslookup my-api
# Server: 10.96.0.10 ↠CoreDNS ClusterIP
# Address: 10.96.0.10:53
# Name: my-api.default.svc.cluster.local
# Address: 10.96.24.51 ↠Service's ClusterIP
# kube-proxy on each node manages iptables/ipvs rules
# that load-balance traffic across pod IPs for each service
# Headless service (for StatefulSets — direct pod DNS)
spec:
clusterIP: None # no ClusterIP, DNS returns pod IPs directly
# DNS: pod-0.my-service.default.svc.cluster.local → Pod-0's IP directlyKey Points to Remember
- 1Services provide stable DNS names for ephemeral pods — ClusterIP for internal, LoadBalancer for external.
- 2Service selector labels must exactly match pod labels — mismatched labels = no traffic.
- 3Ingress routes HTTP/HTTPS traffic by host and path — one external IP for multiple services.
- 4CoreDNS auto-creates DNS records: service-name.namespace.svc.cluster.local.
- 5kube-proxy maintains iptables/IPVS rules on each node to load-balance service traffic across pod IPs.
- 6Headless services (clusterIP: None) return pod IPs directly via DNS — used by StatefulSets.
Interview Questions
Sign in to ask AriaHow does service discovery work in Kubernetes?
What is the difference between a Service and an Ingress?
Ask Aria about Services & Networking
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.