Kubernetes 101: Ingress

8grams
9 min readJul 18, 2023

Introduction

Ingress in Kubernetes is a robust API object that manages external access to the services within a cluster. More than just a technical tool, Ingress serves as a bridge, connecting users’ requests to the corresponding services in a Kubernetes ecosystem. Unlike other networking strategies such as NodePort or LoadBalancer, Ingress gives you fine-grained control over HTTP and HTTPS routing to services within the cluster based on various factors like host or path.

The Role and Functionality of Ingress

The primary roles of Ingress include load balancing, SSL termination, and domain-based virtual hosting. It provides a consolidated and unified set of rules governing inbound connections, enhancing the overall network efficiency. In essence, Ingress acts as a “door” to the cluster, efficiently managing external access to the services.

Source: https://www.armosec.io/

Load Balancing

Load balancing refers to the process of distributing network traffic across multiple servers or pods to ensure no single server bears too much demand. This role is crucial in maintaining the responsiveness and availability of applications. In the context of Kubernetes Ingress, load balancing is primarily concerned with efficiently distributing inbound network traffic to suitable backend services based on the Ingress rules.

Load balancing performed by Ingress in Kubernetes comes with some advanced capabilities:

  • Session Affinity: This refers to the ability of the load balancer to send all requests from a client to the same pod, once a connection has been established. This is crucial for stateful applications.
  • Custom Load Balancing Algorithms: Some Ingress Controllers allow the use of custom algorithms for load balancing beyond the standard round-robin or least-connections methods.
  • Health Checks and Failovers: If a pod is not healthy, the load balancer will automatically stop sending traffic to it, and redirect traffic to other healthy pods.

SSL Termination

SSL Termination. Source: Digital Ocean

SSL (Secure Sockets Layer) and its successor, TLS (Transport Layer Security), are cryptographic protocols designed to provide communications security over a computer network. When traffic is encrypted using SSL/TLS, the information is unreadable to anyone except for the server you are sending the information to.

In the context of Kubernetes Ingress, SSL Termination refers to the process where the Ingress Controller is responsible for decrypting SSL/TLS requests. This implies that SSL/TLS is ‘terminated’ at the load balancer, relieving the backend servers from the computational burden of decrypting and encrypting SSL/TLS traffic.

By centralizing this computational process at the Ingress Controller, you can more easily manage and update your SSL/TLS certificates, leading to a more secure system. It also frees up resources on your backend servers to focus on running your applications.

Domain-based Virtual Hosting

Domain-based virtual hosting is a feature that allows one IP address to host multiple domains or hostnames. Each domain can then be routed to a different service within the cluster. This is done by using the Host HTTP header to distinguish between different domains.

For example, you could have an Ingress configuration that routes all traffic from service1.example.com to a service named service1 in your cluster and all traffic from service2.example.com to a service named service2.

This ability to route traffic based on domain names is a powerful feature when running multiple microservices, as it allows you to expose multiple services under the same IP address, using a different domain for each service. The domain-based routing feature of Kubernetes Ingress makes it an excellent choice for such microservice architectures.

The Working Principle of Ingress

Ingress operates as a reverse proxy. It accepts incoming connections and forwards them to the appropriate services in the cluster. To understand its workings, it’s essential to grasp the role of Ingress controllers and Ingress rules.

Ingress Controllers: These are essentially pods within the cluster that read and implement the rules defined in Ingress Resources. These controllers could be any reverse proxy server, and their role is to manage inbound access routes.

Ingress Rules: These are specific instructions that guide the routing of traffic. When a user sends a request, the Ingress Controller checks the Ingress rules and forwards the request to the appropriate service.

For instance, you might have an Ingress rule that routes traffic sent to serviceA.yourdomain.com to serviceA within your cluster and serviceB.yourdomain.com to serviceB. You could also have rules based on URL paths, e.g., yourdomain.com/serviceA might be routed to serviceA and yourdomain.com/serviceB to serviceB.

SSL/TLS encryption for secure communication is also managed in this layer, with Ingress Controllers using the provided secrets to decrypt traffic and pass it on to the appropriate services.

Ingress in Relation to Services and Endpoint Resources

Ingress, Services, and Endpoint Resources are interconnected components within a Kubernetes ecosystem.

Source: https://avinetworks.com/

Services in Kubernetes are an abstract way to expose an application running on a set of Pods. They provide a static endpoint that other applications can use to access the functions offered by your application.

Endpoint Resources are Kubernetes objects that store the IP addresses and ports of Pods that a service can direct traffic to.

The Ingress routes incoming traffic to services, which then route to their endpoint pods. The service and endpoint resources abstract the changing nature of pods, allowing the Ingress to route traffic to stable addresses despite the dynamic nature of the pods.

Ingress Software

Source: https://medium.com/devopsturkiye/

Choosing the right Ingress Controller is crucial. Your choice depends on several factors such as the specific use-case, complexity of your system, and the nature of the traffic you expect. Here are a few options:

Nginx: A popular option due to its high performance and stability, Nginx offers extensive configuration options. It’s excellent for handling a variety of workloads and has a vibrant community for support.

Traefik: Known for its simplicity and automatic configuration, Traefik is a good choice if you require seamless, hassle-free management. It also supports modern protocols such as gRPC and WebSockets.

HAProxy or Ambassador: If you require advanced traffic management, these Ingress Controllers are worth considering. They provide rich features for traffic control, including advanced rate limiting and fine-grained circuit breakers.

Each controller has its strengths and weaknesses, and your selection should align with your cluster’s specific needs.

Ingress Configurations

Ingress in Kubernetes offers a plethora of configurations for managing traffic, including path and host-based routing, as well as advanced SSL/TLS configurations.

Path and Host-Based Routing: This configuration routes traffic based on the URL path and hostname. For example, you might route ‘myapp.com/users’ to the ‘user-service’ and ‘myapp.com/payments’ to the ‘payment-service’.

SSL/TLS Configurations: Ingress allows for various types of SSL/TLS configurations. It’s possible to have a single wildcard certificate for multiple subdomains or specific certificates for each service. It also supports newer protocols like HTTP/2 and gRPC, which require special configurations.

Let’s break this down:

  • apiVersion: This is the version of the Kubernetes API that you're using to create this object.
  • kind: This specifies the type of Kubernetes resource you want to create. In this case, it is an Ingress.
  • metadata: This includes data about the Ingress, such as its name and annotations. In our case, the Ingress resource is named "example-ingress", and it includes an annotation that will rewrite all incoming requests to the root (/) of the targeted service.
  • spec: This is where the behavior of the Ingress is defined.
  • tls: This section is used to specify the TLS certificates for the domains specified. In this example, we use a secret named myapp-certificate that contains the TLS certificate for the domain myapp.example.com.
  • rules: This section includes a list of host rules for HTTP traffic.
  • rules.host: For the host myapp.example.com, we specify the following rules:
  • rules.http.paths: This section contains all the path-based rules and their corresponding backend services.
  • rules.http.paths.pathType: This defines how the incoming request paths should be matched with the path value. Prefix means any path which starts with the value should be directed to the specified backend service.
  • rules.http.paths.path: Any traffic that comes to myapp.example.com/users or myapp.example.com/payments will be routed to the respective backend services.
  • rules.http.paths.backend: This is where we specify the backend service where the traffic will be routed to. We've defined two services: user-service and payment-service that will listen on port 8080.

So, with this Ingress configuration, a client request to myapp.example.com/users would be routed to the user-service service in the Kubernetes cluster, and a request to myapp.example.com/payments would be routed to the payment-service. All of these routing decisions would be made at the Ingress level, before the traffic reaches the application services themselves.

PathType

In Kubernetes Ingress, the pathType field is used to specify how the Ingress Controller should match the incoming requests with the path value defined in your Ingress manifest. As of the networking.k8s.io/v1 API version, there are three valid values: Exact, Prefix, and ImplementationSpecific.

  • Exact: The incoming request path must exactly match the path specified in the Ingress rule. For instance, if your rule has path: "/foo" and pathType: Exact, the rule will only apply to requests where the path is precisely /foo. A request to /foo/bar or /foo/ would not match.
  • Prefix: This path type matches based on a URL path prefix split by a /. Matching is done on a path element by element basis. For instance, if your rule has path: "/foo" and pathType: Prefix, it will match any requests that start with /foo, such as /foo, /foo/, /foo/bar, and so on.
  • ImplementationSpecific: This is the default path type used if none is specified. It leaves the interpretation of the matching rules up to the Ingress Controller. The implementation behavior can be similar to Prefix or Exact, or it could be a custom behavior defined by the controller. It's recommended to explicitly specify the path type to avoid potential ambiguity.

Remember, the way paths are interpreted and whether requests are redirected or not (301 or 302 HTTP responses) depend on the specific Ingress Controller implementation, and the chosen path type can affect this.

Ingress Annotation

Annotations in Kubernetes allow you to attach arbitrary non-identifying metadata to objects. In the case of Ingress, annotations can be used to customize the behavior of the Ingress controller.

The effect of an annotation depends on the Ingress controller you use. Here are some examples using the commonly adopted NGINX Ingress Controller:

nginx.ingress.kubernetes.io/rewrite-target: This is used when you want to rewrite the URL path before forwarding the traffic to the backend service. For example:

nginx.ingress.kubernetes.io/rewrite-target: /$2

This configuration would strip the matched part of the path and replace with the value in the rewrite-target. This is especially useful when the backend service expects the traffic under a different endpoint.

nginx.ingress.kubernetes.io/ssl-redirect: This forces SSL redirection, irrespective of the protocol used for the original call. For example:

nginx.ingress.kubernetes.io/ssl-redirect: "true"

This configuration would redirect all HTTP traffic to HTTPS, forcing a secure connection.

nginx.ingress.kubernetes.io/affinity: This enables session affinity, which helps to bind a user's session to a specific instance of a service. For example:

nginx.ingress.kubernetes.io/affinity: "cookie"

This configuration would use a cookie to enable session affinity.

nginx.ingress.kubernetes.io/cors-allow-headers : This allows you to control which headers are allowed for cross-origin requests. For example:

nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"

This configuration would allow only the specified headers in cross-origin requests.

About 8grams

We are a small DevOps Consulting Firm that has a mission to empower businesses with modern DevOps practices and technologies, enabling them to achieve digital transformation, improve efficiency, and drive growth.

Ready to transform your IT Operations and Software Development processes? Let’s join forces and create innovative solutions that drive your business forward.

--

--

8grams

We are a DevOps Consulting Firm with a mission to empower businesses with modern DevOps practices and technologies