Service vs Ingress (Kubernetes Networking)¶
Mental model¶
Service = internal phone extension (L4, TCP/UDP). Ingress = the reception desk routing calls by name (L7, HTTP).
What it looks like¶
"How do I expose my app?" has three different answers depending on context, and it is not obvious which one to use.
What it really is¶
Service: a stable network identity for a set of pods. Gets a virtual cluster IP that load-balances across matching pod IPs. Operates at L4 (TCP/UDP). Selects pods via label selectors. kube-proxy maintains iptables or IPVS rules to implement it.
Service types: - ClusterIP: internal only (default). - NodePort: opens a port on every node. - LoadBalancer: provisions a cloud load balancer.
Ingress: HTTP/HTTPS routing rules. Maps hostnames and URL paths to backend Services. Operates at L7 (HTTP). Requires an Ingress Controller (nginx, traefik, etc.) to function. Without a controller, Ingress resources are inert specs.
Why it seems confusing¶
Service and Ingress both "expose" things, but at different layers. A LoadBalancer Service and an Ingress can both give you an external IP, but they solve different problems.
What actually matters¶
- Service = L4 load balancing to pods.
- Ingress = L7 HTTP routing to services.
- You need a Service even if you use Ingress. Ingress routes to Services, not directly to pods.
- Ingress Controller must be installed separately. It is not built into Kubernetes.
Common mistakes¶
- Creating an Ingress without installing an Ingress Controller. Nothing happens.
- Using LoadBalancer Services for every app instead of one Ingress routing to many services (costs more cloud LBs).
- Forgetting that NodePort exposes on ALL nodes, not just the one running your pod.
Small examples¶
# ClusterIP Service for internal communication
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 8080
# Ingress routing two domains to two services
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: routes
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
One-line summary¶
A Service gives pods a stable L4 endpoint; an Ingress adds L7 HTTP routing rules on top, directing traffic to Services.