Intermediate · Kubernetes fundamentals · topic 22 of 53 · 30 min
Services, Ingress and the Gateway API
Explanation
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.
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 onThe 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
| Type | Reachable from | Typical use |
|---|---|---|
| ClusterIP (default) | Inside the cluster only | Service-to-service calls, databases |
| NodePort | Any node's IP on a port from 30000 to 32767 by default | Labs, or as a building block for an external load balancer |
| LoadBalancer | The internet or your network, through a load balancer the cloud creates | Exposing one service directly |
| ExternalName | Inside the cluster, as a DNS alias (CNAME) to an outside name | Pointing to a managed database host |
| Headless (clusterIP: None) | DNS returns the pod IPs directly, with no virtual IP | StatefulSets 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.
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: 80How 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.
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: 10Ingress 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.
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
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.
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=ordersPractice (0/3 done)
What is the default port range for a NodePort Service?
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.
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Namespaces, ConfigMaps, Secrets, resources and probesKubernetes fundamentals · same module
- FirewallsCyber Security: from zero to SOC analyst · Identity and network defence
- Network basics: IP addresses, routes, DNS and the ip commandLinux and Red Hat (RHCSA to RHCE) · Software and networking
- Kubernetes securityDevSecOps
- VPC basics: CIDR, subnets and gatewaysCloud Computing (AWS, Azure, Google Cloud) · Networking and databases: VPC and RDS
- Clients, servers, IP addresses and URLsBackend Development · How the web and backends work
Questions people ask about this
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.
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
- 2 more topics in “Kubernetes fundamentals” before its exam: Namespaces, ConfigMaps, Secrets, resources and probes, Helm and Kustomize.
- Module 5 exam: Kubernetes fundamentals · 13 questions · 20 min, without help. 5 topics of this module still to finish first.
- Then the next module, CI/CD pipelines. 53 topics left in the course before the final exam.