Ingress: CRD (Custom Resource Definition)

A Ingress CRD is a custom resource created to extend Kubernetes and provide advanced ingress capabilities beyond the standard Ingress resource.

While the default Kubernetes Ingress object handles basic routing (like mapping a URL path to a service), some use cases require more flexibility. For example:

  • Advanced traffic management (e.g., canary releases, A/B testing).

  • Complex routing (e.g., routing based on headers or cookies).

  • Security policies (e.g., JWT authentication, IP whitelisting).

To achieve this, many Ingress controllers (e.g., NGINX, Traefik, Istio) define their own CRDs to enable advanced configurations.

NGINX

The NGINX Ingress Controller for Kubernetes supports an advanced custom resource called VirtualServer and VirtualServerRoute that allows complex routing, traffic splitting, custom load balancing, and fine-grained configuration.This is more flexible than the standard Ingress resource and is useful for advanced scenarios.

VirtualServer and VirtualServerRoute resources are load balancing configurations recommended as an alternative to the Ingress resource.

Installing NGINX CRD is quite advanced and difficult, make sure you read and follow the installation guide in the Official Documentation.

Traffic Splitting

One of scenario that we can use is traffic splitting or canary deployment. You can also use this for A/B testing.

To add traffic splitting in NGINX VirtualServer is relatively easy. We just need to add list upstream (2 or more) and then on the routes.action spec we add split and weight for each upstream.

Create Deployment

Lets create two deployments using nginxdemos/nginx-hello:plain-text image, it will return request and server info so we can differentiate the response.

Create Service

Then lets create service for both of our app using kubectl expose command and check if the service created properly.

Create VirtualServer

Now lets create the VirtualServer definition. Here are example of splitting traffic into 2 different upstream with weight 80 and 20. This means that 80% of the traffic will goes to my-app-v1 and the others goes to my-app-v2.

Apply the yaml file and the you can use kubectl describe to get the details and status. Also because we are using minikube don't forget to start minikube tunnel after applying the VirtualServer.

Test and Validate

Then we can try to make multiple curl request to the custom ingress CRD that we just created like this.

As you can see from 5 consecutive request 4 of them goes to my-app-v1 and only 1 goes to my-app-v2 as expected. This is very useful if you want to do Canary release to make sure that the new version will work as expected before moving all traffic into it.

References

Last updated