Service vs. Ingress: When Should You Use Each?

intermediate|servicesdevopssrebackend developerCKACKAD
TL;DR

Services provide L4 (TCP/UDP) load balancing within the cluster, while Ingress provides L7 (HTTP/HTTPS) routing with host and path-based rules. Use Services for internal communication and Ingress for external HTTP traffic that needs routing logic.

Detailed Answer

Services and Ingress solve different networking problems. Choosing the right one depends on whether you need L4 or L7 functionality, whether the traffic is internal or external, and whether you need HTTP-specific features like path-based routing.

Quick Comparison

| Feature | Service (ClusterIP/NodePort/LB) | Ingress | |---------|-------------------------------|---------| | OSI Layer | L4 (TCP/UDP) | L7 (HTTP/HTTPS) | | Protocol support | TCP, UDP, SCTP | HTTP, HTTPS | | Routing | IP + Port only | Host, path, headers | | TLS termination | At the application | At the Ingress controller | | Cost (cloud) | One LB per Service | One LB for many Services | | Internal/External | Both | External (typically) |

When to Use Services

ClusterIP (Internal Communication)

apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  type: ClusterIP
  selector:
    app: user-service
  ports:
    - port: 8080
      targetPort: 8080

Use for: Pod-to-Pod communication, microservice backends, databases, caches.

LoadBalancer (External Non-HTTP)

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  type: LoadBalancer
  selector:
    app: postgres
  ports:
    - port: 5432
      targetPort: 5432

Use for: Databases, gRPC services (without HTTP), MQTT brokers, game servers — anything that is not HTTP.

NodePort (Development/On-Premises)

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080

Use for: Development clusters, on-premises without cloud load balancers, quick testing.

When to Use Ingress

Use Ingress when you need HTTP-specific routing — multiple services behind a single load balancer, path-based routing, TLS termination, or rate limiting:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
        - api.example.com
      secretName: tls-secret
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-v1
                port:
                  number: 8080
          - path: /v2
            pathType: Prefix
            backend:
              service:
                name: api-v2
                port:
                  number: 8080

This single Ingress routes traffic to three different Services based on hostname and path, behind one load balancer.

Cost Comparison

In cloud environments, each LoadBalancer Service provisions a cloud load balancer:

Without Ingress:
  3 Services × $18/month (AWS NLB) = $54/month

With Ingress:
  1 Ingress Controller LB + 3 ClusterIP Services = $18/month

For clusters with many externally-exposed services, Ingress dramatically reduces costs.

The Gateway API Alternative

Gateway API is the evolution of Ingress, providing richer functionality:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-routes
spec:
  parentRefs:
    - name: main-gateway
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1
      backendRefs:
        - name: api-v1
          port: 8080
          weight: 90
        - name: api-v2
          port: 8080
          weight: 10

Gateway API adds traffic splitting, header-based routing, and support for TCP/UDP routes — features that Ingress lacks natively.

Decision Flowchart

Is the traffic internal (Pod-to-Pod)?
├── Yes → ClusterIP Service
└── No → Is it HTTP/HTTPS?
    ├── Yes → Do you need routing (host/path)?
    │   ├── Yes → Ingress (or Gateway API)
    │   └── No → LoadBalancer Service or Ingress
    └── No → LoadBalancer Service (TCP/UDP)

Common Mistakes

  1. Creating a LoadBalancer Service per microservice: Expensive and unnecessary. Use Ingress to consolidate.
  2. Using Ingress for gRPC without HTTP/2: Ensure your Ingress controller supports HTTP/2 and gRPC (Nginx Ingress does with nginx.ingress.kubernetes.io/backend-protocol: GRPC).
  3. Forgetting to install an Ingress controller: Ingress resources have no effect without a controller. Common options are Nginx Ingress, Traefik, HAProxy, and cloud-native controllers.
  4. Using NodePort in production: NodePort exposes fixed ports on all nodes and lacks health checking. Use Ingress or LoadBalancer instead.

Why Interviewers Ask This

This is a fundamental architecture question that tests your ability to choose the right networking primitive for different scenarios. Incorrect choices lead to unnecessary costs or missing functionality.

Common Follow-Up Questions

Can you expose non-HTTP services through Ingress?
Standard Ingress only supports HTTP/HTTPS. For TCP/UDP, use a LoadBalancer Service directly or Ingress controller-specific annotations (e.g., Nginx TCP/UDP ConfigMaps).
What is Gateway API and how does it compare to Ingress?
Gateway API is the successor to Ingress, offering richer routing, traffic splitting, and role-based configuration. It supports TCP, UDP, gRPC, and HTTP natively.
Can you use Ingress without a LoadBalancer Service?
The Ingress controller itself typically runs behind a LoadBalancer Service, but you can use NodePort or hostNetwork for on-premises clusters.

Key Takeaways

  • Use ClusterIP Services for internal Pod-to-Pod communication.
  • Use Ingress for external HTTP traffic that needs host/path routing, TLS termination, or rate limiting.
  • Use LoadBalancer Services for non-HTTP external traffic (databases, gRPC without HTTP).

Related Questions

You Might Also Like