How Kubernetes Ingress Routes External Traffic
Kubernetes Ingress provides a single entry point for routing external traffic to cluster services, simplifying load balancing, TLS termination, and path-based routing compared to using multiple LoadBalancer services.
If you’ve ever worked with Kubernetes, you know that getting traffic from the outside world into your cluster can be a bit of a puzzle. Pods come and go, services change, and you can’t just rely on a static IP address for everything. That’s where Ingress comes in. Think of it as the smart doorman for your cluster—it decides who gets in and where they go.
Why Not Just Use a LoadBalancer?
You might wonder, “Why bother with Ingress when I can just use a LoadBalancer service?” That’s a fair question. A LoadBalancer exposes one service to the internet. But what if you have ten services? That means ten separate load balancers, each with its own public IP and cost. If you’re running a small app at PythonSkillset, you probably don’t want that complexity or bill.
Ingress solves this by giving you one entry point. It can route traffic to different services based on rules—like the URL path or domain name. For example, api.pythonskillset.com goes to one service, while app.pythonskillset.com goes to another. All through a single external endpoint.
The Core Components
Ingress Controller vs. Ingress Resource
Here’s where people get confused: an Ingress resource is just a set of rules (a YAML file). The real work happens in the Ingress controller—the software that runs in your cluster and actually enforces those rules.
Think of it this way: the Ingress resource is like a signpost, and the Ingress controller is the traffic cop who reads it and directs cars. Without the controller, the signpost is just decoration.
Popular controllers include NGINX Ingress, Traefik, and HAProxy. Most managed Kubernetes providers also offer their own (like AWS Load Balancer Controller for EKS).
How It Works Step by Step
- Someone types
https://pythonskillset.cominto their browser. - DNS resolves that domain to the IP address of your Ingress controller (which is usually exposed via a LoadBalancer service).
- The request hits the controller.
- The controller checks the Ingress resource rules. For example, it might say “If path is
/blog, send to theblog-service; if path is/api, send to theapi-service.” - The controller forwards the request to the appropriate backend service.
- The service then routes it to one of the pods running your application.
Writing Your First Ingress Rule
Let’s keep it simple. Here’s a basic example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pythonskillset-ingress
spec:
rules:
- host: pythonskillset.com
http:
paths:
- path: /blog
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
This tells the controller: if the request comes for pythonskillset.com/blog, send it to blog-service on port 80. If it’s pythonskillset.com/api, send it to api-service on port 8080.
Path Types Matter
You’ll notice pathType: Prefix in the example. That’s important. Kubernetes supports three path types:
- Prefix: Matches anything starting with that path. So
/blogalso matches/blog/2025. - Exact: Matches only that exact path.
/blogwon’t match/blog/. - ImplementationSpecific: Let’s the controller decide. Use this only if you know what your controller does.
For most real-world apps, Prefix is your friend because users might add trailing slashes or subpaths.
TLS and Certificates
No serious application runs without HTTPS. Ingress makes this easy. You can attach a TLS certificate to your Ingress resource. Here’s how:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pythonskillset-secure
spec:
tls:
- hosts:
- pythonskillset.com
secretName: pythonskillset-tls
rules:
- host: pythonskillset.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: main-app
port:
number: 80
You’d need to create a secret with your certificate and key. Many teams use cert-manager to automate this with Let’s Encrypt.
Common Gotchas
- Watch your namespace: The Ingress resource and the backend services must be in the same namespace unless you use special cross-namespace features (not supported by all controllers).
- Default backends: If no rule matches, the controller sends traffic to a “default backend.” Always define one—even if it’s just a 404 page—so you don’t get unexpected errors.
- Annotations are controller-specific: The core Ingress spec is standard, but many features (like rate limiting or rewriting paths) rely on annotations that only work with your specific controller. Always check the docs.
Real Talk: Do You Even Need Ingress?
For a single-service app on a small cluster? A LoadBalancer might be simpler. But as soon as you have two or more services, or need SSL termination, or want to route by domain—Ingress becomes your best friend.
At PythonSkillset, we’ve seen teams struggle with managing multiple load balancers and DNS records. Ingress simplifies everything into one YAML file and one entry point. It’s one of those tools you don’t realize you need until you start scaling.
Once you get comfortable with the basics, try exploring advanced features like annotations for rewrites, sticky sessions, or integrating with external monitoring. But start simple. Get one rule working. Then add another. Before you know it, you’ll feel like a traffic master.
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.