Skip to content

Intermediate · Kubernetes fundamentals · topic 22 of 53 · 30 min

Services, Ingress and the Gateway API

Explanation

Pods come and go and their IP addresses change, so a Service gives a group of pods one stable name and IP and spreads traffic across them. Service types decide who can reach it: ClusterIP inside the cluster, NodePort on every node, LoadBalancer through a cloud load balancer. Ingress, and its newer successor the Gateway API, route outside HTTP traffic to Services by host name and path.

Why Services exist

Your frontend needs to call payments-api. But payments-api is 4 pods whose IPs change every time a pod is replaced. A Service is a stable front for a group of pods: it gets a fixed virtual IP address and a DNS name, and it load-balances requests across the matching pods that are ready.

yaml
apiVersion: v1
kind: Service
metadata:
  name: payments-api
  namespace: payments
spec:
  type: ClusterIP            # the default; can be left out
  selector:
    app: payments-api        # send traffic to pods with this label
  ports:
    - port: 80               # the port clients call on the Service
      targetPort: 8080       # the port the container listens on
Clients call payments-api on port 80; Kubernetes forwards to port 8080 of a ready pod.

The selector is the link. Kubernetes keeps a list of the IPs of pods that match the selector and pass their readiness probe. These lists are stored in EndpointSlice objects (the older Endpoints object did the same job). If the list is empty, the Service has nowhere to send traffic.

Service types

TypeReachable fromTypical use
ClusterIP (default)Inside the cluster onlyService-to-service calls, databases
NodePortAny node's IP on a port from 30000 to 32767 by defaultLabs, or as a building block for an external load balancer
LoadBalancerThe internet or your network, through a load balancer the cloud createsExposing one service directly
ExternalNameInside the cluster, as a DNS alias (CNAME) to an outside namePointing to a managed database host
Headless (clusterIP: None)DNS returns the pod IPs directly, with no virtual IPStatefulSets such as database clusters

DNS names

The cluster DNS server (usually CoreDNS) gives every Service a name of the form <service>.<namespace>.svc.cluster.local, where cluster.local is the default cluster domain. Pods in the same namespace can simply call http://payments-api. From another namespace, use payments-api.payments, or the full name payments-api.payments.svc.cluster.local.

Ingress: one entrance for many services

Giving every service its own cloud load balancer is costly. Ingress is an object that describes HTTP and HTTPS routing rules: requests for shop.example.com/api go to the api Service, everything else to the web Service. One load balancer, many services.

An Ingress object is only a set of rules. Something must read those rules and route the traffic: an ingress controller, which you install in the cluster (for example a controller from your cloud provider, Traefik, HAProxy or an NGINX-based one). Without a controller, an Ingress does nothing at all.

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop
  namespace: shop
spec:
  ingressClassName: example-controller   # which controller should handle this
  tls:
    - hosts: [shop.example.com]
      secretName: shop-tls                 # a Secret holding the certificate and key
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80
Requests to /api and below go to api; everything else on this host goes to web. TLS ends at the controller.

How paths are matched

  • Exact: the request path must be exactly the same, so /api matches only /api.
  • Prefix: matches by path parts split on /. /api matches /api, /api/ and /api/orders, but NOT /apix.
  • When several rules match, the longest path wins. If two are equally long, Exact beats Prefix.

The Gateway API: the newer way

The Gateway API is the newer, more expressive successor to Ingress. It splits the job into roles: a GatewayClass (which implementation), a Gateway (the entry point, owned by the platform team) and routes such as HTTPRoute (owned by app teams). It supports things Ingress needed vendor-specific annotations for, like header matching and splitting traffic by weight between two versions.

yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-api
  namespace: shop
spec:
  parentRefs:
    - name: public-gateway
  hostnames: ["shop.example.com"]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api
          port: 80
          weight: 90
        - name: api-v2
          port: 80
          weight: 10
An HTTPRoute that sends 90% of /api traffic to api and 10% to api-v2.

Ingress is still supported, but it is frozen: it gets no new features. The widely used community ingress-nginx controller has been retired, so for a new cluster, check the current Kubernetes docs and your provider before choosing between an Ingress controller and a Gateway API implementation.

Careful: Common mistakes. (1) A typo in the Service selector: the EndpointSlice is empty and callers get errors or timeouts. Compare kubectl get pods --show-labels with the selector. (2) targetPort not matching the port the app listens on. (3) No ingress controller installed, or the wrong ingressClassName, so the Ingress is ignored. (4) Using NodePort for production traffic instead of a load balancer or Ingress. (5) Pods failing their readiness probe: they are removed from the Service, so it looks like the Service is broken.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Services, Ingress and the Gateway API · 1/8

Services and Ingress

In this lesson you will learn how traffic reaches your pods: Services, Ingress and the Gateway API.

Prefer a video by a teacher? Find free videos on “kubernetes services clusterip nodeport loadbalancer ingress explained” on YouTube ↗

In real life: An online grocery in Pune with one entrance

An online grocery runs three services: the web shop, the orders API and a delivery-tracking API. Instead of three cloud load balancers, the team uses one: an Ingress for grocer.example.in sends /api/orders to the orders Service, /api/track to the tracking Service and everything else to the web Service. Inside the cluster, the orders API calls the payments service at http://payments.payments, its Service DNS name, never a pod IP. When the team later tries a new tracking version, they use a Gateway API HTTPRoute to send 10% of tracking traffic to it.

bash
kubectl get svc -n shop
# NAME     TYPE        CLUSTER-IP     PORT(S)
# web      ClusterIP   10.96.12.40    80/TCP
# orders   ClusterIP   10.96.88.17    80/TCP
kubectl get endpointslices -n shop -l kubernetes.io/service-name=orders
Checking the Services and the pod IPs behind one of them.

Practice (0/3 done)

Task 1 · Question

What is the default port range for a NodePort Service?

Task 2 · Code · Python

Write route(host, path, rules) that picks a backend Service the way a simple Ingress does. Each rule is a dict with "host" ("" means any host), "path", "type" ("Exact" or "Prefix") and "service". Exact matches only the same path. Prefix matches by path parts split on "/": "/api" matches "/api" and "/api/orders" but not "/apix", and "/" matches everything. Among matching rules, the longest path wins; if two are equally long, Exact wins. Return the service name, or None if nothing matches.

Task 3 · Practice

Write a ClusterIP Service and an Ingress for a hospital appointments app. Pods have label app: appointments and listen on port 5000. The Service should listen on port 80. The Ingress should serve appointments.cityhospital.example with TLS (certificate in Secret appointments-tls) and send every path to the Service.

Quick quiz

Question 1

1.Which Service type is the default?

Question 2

2.A pod in namespace web calls Service "orders" in namespace shop. Which name works?

Question 3

3.You created an Ingress, but nothing happens and no address appears. What is the most likely cause?

Question 4

4.With pathType Prefix and path /api, which request path does NOT match?

Question 5

5.What is true of the Gateway API compared with Ingress?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which Service type is the default?

Answer: ClusterIP

If you leave out type, you get a ClusterIP Service, reachable only inside the cluster.

A pod in namespace web calls Service "orders" in namespace shop. Which name works?

Answer: orders.shop

The pattern is service.namespace, with .svc.cluster.local optional at the end.

You created an Ingress, but nothing happens and no address appears. What is the most likely cause?

Answer: No ingress controller is installed, or the ingressClassName is wrong

An Ingress is only rules. A controller must be running to act on them.

With pathType Prefix and path /api, which request path does NOT match?

Answer: /apiv2

Prefix matches whole path parts. /apiv2 is a different part, not /api followed by more parts.

What is true of the Gateway API compared with Ingress?

Answer: It is a newer, more expressive successor with role-based objects such as Gateway and HTTPRoute

The Gateway API separates infrastructure and routes and supports features like weighted traffic splitting natively.

A cloud rule allows port 3389 from 0.0.0.0/0. What is the risk?Related

Answer: Remote Desktop is open to the whole internet

0.0.0.0/0 is every IPv4 address; exposed RDP is a top ransomware entry point.

From Firewalls

Which component decides which node a new pod should run on?Related

Answer: kube-scheduler

The scheduler watches for pods with no node assigned and picks a node based on resources and rules.

From Why Kubernetes, and how a cluster works

Which command shows the default gateway?Related

Answer: ip route

The "default via" line in ip route is the gateway.

From Network basics: IP addresses, routes, DNS and the ip command

You create a default deny NetworkPolicy, but pods can still reach each other. What is the most likely reason?Related

Answer: The cluster's network plugin (CNI) does not enforce NetworkPolicies

NetworkPolicies are enforced by the CNI, such as Calico or Cilium. With a CNI that ignores them, nothing changes.

From Kubernetes security

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Kubernetes fundamentals” before its exam: Namespaces, ConfigMaps, Secrets, resources and probes, Helm and Kustomize.
  2. Module 5 exam: Kubernetes fundamentals · 13 questions · 20 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, CI/CD pipelines. 53 topics left in the course before the final exam.

← Previous: Pods, ReplicaSets and Deployments