How Does External Traffic Reach Your Pods? Kubernetes Ingress Explained
Your application works perfectly inside Kubernetes. Its Service is healthy, and the Pods are running.
But when someone opens your website from the internet, how does that request find the correct application?
Kubernetes Ingress provides the routing rules—but an Ingress controller makes them work.
Let's follow an external HTTP/HTTPS request into a Kubernetes cluster, explore how traffic reaches the backend Pods, and troubleshoot the path when something goes wrong.
1. Where Does Ingress Fit?
Imagine hosting two applications in the same cluster:
-
shop.example.com— an online store. -
api.example.com— a backend API.
Each application has its own Kubernetes Service. Ingress lets you define rules that route requests to the appropriate Service based on hostnames and URL paths.
External Client | v External Entry Point | v Ingress Controller / \ v v Shop Service API Service | | v v Shop Pods API Pods Each component has a distinct responsibility:
- Ingress resource: Defines HTTP/HTTPS routing rules.
- Ingress controller: Implements those rules using a proxy, load balancer, or another supported datapath.
- Service: Provides a stable way to reach backend Pods.
- Pods: Run the application.
An Ingress resource alone does not expose an application. You need a compatible controller and a working external traffic path.
2. Define the Routing Rules
Suppose you want requests to shop.example.com to reach your online store and requests to api.example.com to reach your API.
You can define both rules in one Ingress resource:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: application-ingress spec: # Must match an IngressClass supported by your controller. ingressClassName: example-controller rules: # Route requests for the shop hostname. - host: shop.example.com http: paths: - path: / pathType: Prefix backend: service: name: shop-service port: number: 80 # Route requests for the API hostname. - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80 Replace example-controller with the IngressClass name available in your cluster. Both backend Services must exist, and the specified ports must match their Service configurations.
Notice that Ingress references Services, not individual Pod IP addresses. The routing rules can therefore remain stable while Kubernetes replaces backend Pods.
3. Follow an External Request
Let's trace a request to:
https://shop.example.com/products Step 1: DNS finds the external entry point
The browser resolves shop.example.com to an IP address associated with the external entry point, typically a load balancer or another network endpoint in front of the Ingress controller.
DNS helps the client locate the entry point. It does not decide which Kubernetes Service should receive the request.
Step 2: The request reaches the Ingress controller
The browser establishes an HTTPS connection to the external endpoint.
Depending on the deployment, traffic might pass through a cloud load balancer, a network appliance, or another entry point before reaching the controller.
The controller implements the routing rules defined in the Ingress resource.
Step 3: The controller matches the request
The request contains information such as:
Host: shop.example.com Path: /products The controller evaluates the hostname and path, then selects the matching backend:
shop.example.com/products | v shop-service A request to api.example.com would match the API rule instead.
This is a key difference from basic Layer 4 forwarding: Ingress routing can use HTTP hostnames and URL paths to select an application.
Step 4: Traffic reaches the backend
The controller forwards the request towards the selected backend.
The exact implementation depends on the controller. Some send traffic to the Service's ClusterIP; others can route directly to backend endpoint addresses.
Therefore, not every Ingress request must pass through the ClusterIP or kube-proxy.
The selected backend Pod processes the request and returns a response through the networking path established by the controller and surrounding infrastructure.
The logical flow looks like this:
Browser | v External Entry Point | v Ingress Controller | | Match hostname and path v Selected Backend | v Application Pod The exact packet path varies by controller and cluster configuration, but the routing responsibility remains the same.
4. Where Does TLS Termination Happen?
When a user opens https://shop.example.com, the connection uses TLS to protect traffic between the client and the endpoint terminating that connection.
In a common configuration, TLS terminates at the Ingress controller. The controller decrypts the request before forwarding it to the backend.
An Ingress resource can reference a Kubernetes TLS Secret:
spec: tls: - hosts: - shop.example.com secretName: shop-tls-secret The Secret must exist in the appropriate namespace and contain a certificate and private key suitable for the hostname. The controller must support this TLS configuration.
Important: TLS termination at the Ingress controller does not automatically encrypt traffic between the controller and the backend. If that connection also needs encryption, configure it separately.
5. What Happens When a Pod Is Replaced?
Suppose your Service has three backend Pods:
shop-service | +-- Pod A: 10.244.1.5 +-- Pod B: 10.244.2.8 +-- Pod C: 10.244.3.12 Pod B is deleted, and Kubernetes creates a replacement with a different IP.
shop-service | +-- Pod A: 10.244.1.5 +-- Pod C: 10.244.3.12 +-- Pod D: 10.244.2.15 Kubernetes updates the eligible endpoints. The Ingress controller then updates or uses its backend information according to its implementation.
The external hostname remains the same:
https://shop.example.com Clients do not need to track the replacement Pod's IP address.
However, replacing a Pod does not guarantee that every active request or connection survives. An existing connection can fail if its selected backend disappears.
6. Ingress vs. Service
These components work together, but they solve different problems.
| Feature | Service | Ingress |
|---|---|---|
| Main purpose | Provides a stable way to reach backend Pods | Defines HTTP/HTTPS routing rules |
| Routing information | Service ports, selectors or endpoints | Hostnames, URL paths and backend references |
| Typical role | Provides internal access or supported external exposure | Routes web requests to Services |
| Requires an Ingress controller | No | Yes, to implement Ingress rules |
| HTTP hostname/path routing | Not provided by a basic ClusterIP Service | Supported through controller rules |
A Service does not automatically provide hostname-based HTTP routing. Ingress adds that routing layer through a controller.
Ingress is designed for HTTP and HTTPS; it is not a general-purpose mechanism for every TCP or UDP protocol.
7. Troubleshoot Ingress Traffic
When an application is unreachable, check the request path layer by layer.
Step 1: Check the Ingress resource
kubectl get ingress kubectl describe ingress application-ingress Check the hostname rules, backend Services, ports, address, and warning events.
Step 2: Check the IngressClass
kubectl get ingressclass Confirm that the configured class matches an installed and supported controller.
Step 3: Check the controller
Find the controller's namespace and Pod names:
kubectl get pods -A Then inspect its logs. For example, if it runs in the ingress-system namespace:
kubectl logs -n ingress-system <controller-pod-name> Replace the example namespace and Pod name with your actual values. Look for configuration errors or backend-discovery problems.
Step 4: Check the backend Service and endpoints
kubectl get svc shop-service kubectl get endpointslices \ -l kubernetes.io/service-name=shop-service Verify that the Service exists, the port is correct, and eligible endpoints are available.
If endpoints are missing, investigate the Service selector, Pod labels, readiness, and endpoint conditions.
Step 5: Check DNS, connectivity, and TLS
Confirm that shop.example.com resolves to the intended external entry point.
Then verify that the load balancer, firewall, and controller accept traffic on the required ports. For HTTPS, also check certificate validity, hostname matching, and TLS configuration.
Troubleshooting principle: Follow the request from the external entry point to the controller, then to the backend. This helps isolate the failing layer instead of treating the entire path as one component.
8. What's Next: Gateway API?
Ingress remains a stable Kubernetes API, but its feature development is frozen. Kubernetes recommends Gateway API for new functionality.
Gateway API introduces resources such as GatewayClass, Gateway, and HTTPRoute, providing a more flexible model for managing infrastructure and application routing.
Ingress is still important to understand because existing clusters widely use it. Gateway API is the natural next step for exploring modern Kubernetes traffic management.
Final Thoughts
Kubernetes Ingress defines how external HTTP/HTTPS requests should reach applications inside a cluster.
The essential flow is:
- DNS directs the client to an external entry point.
- The request reaches the Ingress controller.
- The controller matches the hostname and path.
- Traffic is forwarded to the selected backend.
- The application processes the request and returns a response.
The Ingress resource defines the routing intent, but the controller and surrounding infrastructure make it work.
Understanding this distinction helps explain why applying an Ingress YAML file alone is not enough—and gives you a practical approach to troubleshooting external traffic.
Next in the series: Kubernetes Gateway API Explained — How Modern Traffic Routing Goes Beyond Ingress.