Kubernetes Basics
Ingress and Ingress Controllers
Ingress is a Kubernetes API object that manages external access to services, typically HTTP and HTTPS, by providing load balancing and SSL termination. It allows you to consolidate routing rules into a single resource, drastically reducing the complexity of managing individual LoadBalancer services. You should reach for Ingress when you have multiple microservices that need to be exposed on the same public IP address under different paths or hostnames.
The Limitation of Service Type LoadBalancer
To understand Ingress, we must first recognize the constraints of the Service Type 'LoadBalancer'. When you define a Service of this type, the infrastructure provider typically provisions a unique cloud load balancer, which consumes external IP addresses and incurs additional costs. If you have ten microservices, using this approach results in ten distinct external load balancers and ten distinct public IPs, which is operationally inefficient and difficult to manage. Furthermore, these services cannot easily perform host-based or path-based routing. The fundamental problem is that Services operate at the network layer, unaware of the application-level data contained within HTTP requests. Without an Ingress resource, you are forced to choose between manually managing complex proxy configurations or accepting the financial and operational overhead of multiple public-facing endpoints for every single service instance within your cluster.
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: web-server
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer # Creates a cloud-level LB per serviceIngress Resource: The Declaration of Intent
An Ingress resource acts as a configuration manifest that tells the cluster how traffic should be routed, but crucially, it does not do the routing itself. Think of it as a set of rules that defines which incoming HTTP requests go to which backend services. By defining paths like '/api' or '/web', or routing by hostnames such as 'api.example.com' versus 'web.example.com', you centralize your routing logic. This declarative approach allows developers to manage traffic flow without touching actual network hardware or load balancer configurations manually. Since the Ingress resource is just an API object, it acts as a single point of truth. It represents the 'what' of your traffic routing requirements, leaving the 'how' to be implemented by a separate component that monitors these resources and updates the data plane accordingly to ensure that traffic is directed to the correct Service endpoints.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-ingress
spec:
rules:
- host: myapp.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80Ingress Controller: The Data Plane Implementation
While the Ingress resource specifies your desired routing, it remains passive until an Ingress Controller is installed. An Ingress Controller is a specialized Pod—usually running a reverse proxy or load balancer software—that watches the Kubernetes API for new Ingress resources. When a change is detected, the controller dynamically translates your rules into configuration files that the underlying proxy engine understands. The controller is effectively the 'Data Plane', handling the actual connection requests from the outside world. Because it is a cluster-aware process, it can automatically discover the Pod IP addresses associated with your target Services, meaning it keeps your routing table updated even as pods scale or restart. Without a running controller, your Ingress objects are effectively ignored by the cluster, demonstrating that the separation of policy definition from the implementation of traffic management is core to Kubernetes architecture.
# To deploy a common NGINX ingress controller:
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.x/deploy.yaml
# The controller pods start watching for Ingress events after deployment.Path-Based Routing and Host Rules
Once your controller is operational, you can leverage advanced routing patterns that are impossible with basic Service configurations. Path-based routing allows you to host multiple applications behind a single domain name by mapping specific URL paths to different backend services. This is essential for building cohesive websites where different components, such as a frontend SPA and a backend API, appear to live on the same host. Host-based routing takes this further by allowing you to route traffic based on the requested domain name, enabling you to support multi-tenancy or multiple distinct services on a single external IP address. Because the controller parses the HTTP 'Host' header and request path, it can intelligently switch between services based on the incoming request, providing a seamless user experience while reducing infrastructure sprawl. This logic happens at the application layer, providing developers with high granularity and flexibility.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-path-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /shop
pathType: Prefix
backend:
service: {name: shop-svc, port: {number: 80}}
- path: /blog
pathType: Prefix
backend:
service: {name: blog-svc, port: {number: 80}}TLS Termination and Security
A vital feature of Ingress is the ability to handle TLS termination at the edge of your cluster. Instead of forcing each microservice to manage its own certificate and encryption keys, you configure the Ingress controller to hold the TLS certificate. When a secure request arrives, the controller decrypts the traffic and passes the raw request to your service over the internal, isolated network. This simplifies certificate management, as you only need to update the secret in one place rather than patching every individual application Pod. This centralization provides a strong security boundary, as you can easily enforce standard encryption protocols across all incoming connections. By shifting the burden of SSL/TLS processing to the Ingress controller, you minimize the resource requirements for your individual application pods while ensuring that all traffic exposed to the public internet remains encrypted, standardized, and strictly regulated by your cluster policies.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts: ["myapp.com"]
secretName: tls-secret # Contains certs
rules:
- host: myapp.com
http: {paths: [...] }Key points
- Ingress provides HTTP and HTTPS routing based on rules defined in a configuration object.
- A single Ingress controller can manage traffic for many services using one public IP address.
- The Ingress resource is a declarative declaration of traffic rules, not the traffic handler itself.
- The Ingress controller is a Pod that monitors the API and updates proxy configurations accordingly.
- Host-based routing allows multiple domains to be served by the same cluster infrastructure.
- Path-based routing enables different application features to be mapped to specific backend services.
- TLS termination at the Ingress level simplifies certificate management and enhances overall cluster security.
- Using Ingress significantly reduces costs and architectural complexity compared to using one LoadBalancer per service.
Common mistakes
- Mistake: Expecting an Ingress resource to work without an Ingress Controller. Why it's wrong: The Ingress resource is just a set of rules; it does nothing without a controller to implement them. Fix: Deploy an Ingress Controller like NGINX or Traefik in the cluster first.
- Mistake: Misconfiguring the service type for the Ingress Controller. Why it's wrong: Many beginners leave the controller as ClusterIP, making it inaccessible from outside the cluster. Fix: Set the Ingress Controller service type to LoadBalancer or use NodePort/HostPort to expose it.
- Mistake: Forgetting to define a Backend Service in the Ingress manifest. Why it's wrong: The Ingress controller needs an explicit reference to the target service to route traffic correctly. Fix: Ensure the serviceName and servicePort match an existing service in the same namespace.
- Mistake: Assuming Ingress manages traffic by itself without DNS. Why it's wrong: Ingress rules are based on host headers; if the DNS doesn't point to the LoadBalancer IP, the controller won't know which rule to apply. Fix: Always map your domain name to the external IP of your Ingress controller.
- Mistake: Overlapping paths in multiple Ingress resources. Why it's wrong: If multiple Ingress objects define rules for the same host and path, the behavior is often non-deterministic or dictated by the controller's internal priority. Fix: Use a single Ingress resource for a host or verify path specificity to avoid conflicts.
Interview questions
What is an Ingress in Kubernetes and why do we use it instead of just using NodePort or LoadBalancer services?
An Ingress is an API object that manages external access to the services in a cluster, typically HTTP and HTTPS. While NodePort and LoadBalancer services expose applications at the service level, they are inefficient because each requires a unique port or a dedicated cloud load balancer. Ingress acts as a smart layer-7 router, allowing you to expose multiple services under a single IP address using host-based or path-based routing, which significantly reduces cloud infrastructure costs and management overhead.
Can you explain the role of an Ingress Controller and why it is not included by default in a standard Kubernetes cluster?
An Ingress Controller is the actual software implementation, such as NGINX or Traefik, that fulfills the rules defined in an Ingress resource. Kubernetes itself only provides the Ingress API as a specification; it does not come with a built-in controller because different environments have different networking requirements. By decoupling the controller from the cluster, Kubernetes allows users to choose the implementation that best fits their specific traffic needs, load balancing algorithms, and security policies, ensuring a modular and flexible infrastructure design.
How does path-based routing work within an Ingress resource, and what does the configuration look like?
Path-based routing allows you to direct traffic to different backend services based on the URL path requested by the client. For example, requests to 'example.com/api' go to the API service, while '/web' goes to the frontend. In the YAML manifest, you define a list of paths under the 'http' rules section, mapping each path to a 'service' and 'port'. This allows for clean, logical URL structuring for complex microservices applications without needing separate DNS entries for every single service in the cluster.
Compare the use of an Ingress Controller versus using a Service of type LoadBalancer for exposing your Dockerized applications.
A Service of type LoadBalancer provisions a dedicated cloud load balancer for every single service, which quickly becomes expensive and hits cloud provider limits. Conversely, an Ingress Controller sits behind a single LoadBalancer and acts as a reverse proxy, routing traffic to many services based on headers or paths. The Ingress approach is vastly superior for production-grade Kubernetes deployments because it centralizes SSL termination, provides advanced traffic management features, and maintains a much more manageable and cost-effective networking footprint for your containerized workloads.
Explain how SSL/TLS termination is handled when using an Ingress Controller.
SSL termination happens at the Ingress Controller level rather than at the individual pod level. You store your SSL certificate and private key in a Kubernetes Secret, then reference that secret in the 'tls' section of your Ingress resource. The Ingress Controller decrypts the incoming HTTPS traffic and forwards it as plain HTTP to the internal pods. This approach is highly efficient because it offloads the resource-intensive encryption/decryption process from your application pods, allowing them to focus entirely on processing business logic within the cluster.
How would you troubleshoot a scenario where an Ingress resource is created, but the traffic is not reaching your backend pods?
First, I would verify the Ingress status by running 'kubectl describe ingress <name>' to ensure the controller has assigned an IP address to the resource. Next, I would check the logs of the Ingress Controller pod to see if it is reporting any configuration errors or failed reloads. Then, I would verify that the service referenced in the Ingress manifest actually has matching labels with the target pods. Finally, I would check if the service port defined in the Ingress matches the port exposed by the target service definition to ensure traffic flows correctly.
Check yourself
1. If you define an Ingress resource in a namespace, what happens if no Ingress Controller is running in your cluster?
- A.The cluster automatically assigns a default controller.
- B.The Ingress resource remains created, but no traffic routing occurs.
- C.Kubernetes will throw an error and refuse to create the Ingress resource.
- D.Traffic is routed to all services in the cluster by default.
Show answer
B. The Ingress resource remains created, but no traffic routing occurs.
Ingress objects are declarative configuration. Without a controller process to watch the API server and update routing logic (like NGINX config), the Ingress resource is merely stored data. Option 0 and 3 are false as there is no implicit routing, and option 2 is false because the API server accepts valid manifests regardless of available controllers.
2. Which of the following best describes the relationship between an Ingress Controller and an Ingress Resource?
- A.The Ingress Controller is the data, and the Ingress Resource is the application logic.
- B.The Ingress Resource is the physical load balancer hardware.
- C.The Ingress Controller is the implementation, while the Ingress Resource is the configuration.
- D.They are redundant components that perform identical tasks.
Show answer
C. The Ingress Controller is the implementation, while the Ingress Resource is the configuration.
The Ingress resource defines the desired state (routing rules, paths), while the controller acts as the control loop that reconciles that state by configuring a reverse proxy. Option 0 is backwards, option 1 is false because it's software-defined, and option 3 is incorrect because they serve distinct roles.
3. When configuring multiple paths for the same host in an Ingress, why is order sometimes significant?
- A.The Ingress Controller processes rules based on their alphabetical order.
- B.Longer, more specific paths must be evaluated before shorter, prefix-based paths to prevent routing conflicts.
- C.Kubernetes requires path length to be even to avoid parsing errors.
- D.The controller always defaults to the first path defined in the YAML.
Show answer
B. Longer, more specific paths must be evaluated before shorter, prefix-based paths to prevent routing conflicts.
Because many controllers use prefix matching, if you place a generic root path ('/') before a specific path ('/api'), the root path will match everything, effectively shadowing the '/api' rule. The other options describe non-existent behaviors.
4. Why must an Ingress Controller typically have a service type of LoadBalancer or be exposed via NodePort?
- A.To allow the Ingress resource to automatically create a new database connection.
- B.To provide a stable external entry point for traffic to reach the cluster from outside.
- C.To allow the Ingress Controller to communicate with the Kubernetes API server.
- D.To bypass the need for Pod IP addresses in the cluster.
Show answer
B. To provide a stable external entry point for traffic to reach the cluster from outside.
An Ingress Controller resides inside the cluster; to receive requests from the internet, it must be exposed. Options 0, 2, and 3 are unrelated to the primary function of exposing the controller for external ingress.
5. What is the primary purpose of the 'host' field in an Ingress rule?
- A.To specify the physical machine where the service is running.
- B.To implement virtual hosting, allowing one controller to route traffic based on the domain name.
- C.To limit which users can access the service.
- D.To define the port number the container listens on internally.
Show answer
B. To implement virtual hosting, allowing one controller to route traffic based on the domain name.
The host field enables Name-Based Virtual Hosting, allowing you to host multiple websites or services on a single LoadBalancer IP. It does not control physical placement (0), user permissions (2), or internal container ports (3).