Linkerd traffic split with Nginx Ingress Controller
tl;dr: The nginx ingress requires a Service
resource to have an Endpoint
resource in order to be considered a valid destination for traffic. The architecture in the repo creates three Service
resources, one of which acts as an apex
and has no Endpoint
resources because it has no selectors, so the nginx ingress won't send traffic to it, and the leaf
services will not get traffic as a result.
The example in the repo follows the SMI Spec by defining a single apex service and two leaf services. The web-apex
service does not have any endpoints, so nginx will not send traffic to it.
According to the SMI Spec services can be self-referential, which means that a service can be both an apex and a leaf service, so to use the nginx ingress with this example, you can modify the TrafficSplit
definition to change the spec.service
value from web-apex
to web-svc
:
apiVersion: split.smi-spec.io/v1alpha1kind: TrafficSplitmetadata: name: web-svc-ts namespace: emojivotospec: # The root service that clients use to connect to the destination application. service: web-svc # Services inside the namespace with their own selectors, endpoints and configuration. backends: - service: web-svc # Identical to resources, 1 = 1000m weight: 500m - service: web-svc-2 weight: 500m
I have raised this question in the Linkerd Slack channel and got this fixed with the wonderful support from the community. Seems Nginx doesn't like the service which doesn't have an endpoint. My configuration was correct and asked to change the service pointed in the traffic split to a service with an endpoint and it fixed the issue.
In a nutshell, my traffic split was configured with web-svc and web-svc-2 services. I have changed the traffic split spec.service to the same web-svc and it worked
Here is the traffic split configuration after the update.
apiVersion: split.smi-spec.io/v1alpha1kind: TrafficSplitmetadata: name: web-svc-ts namespace: emojivotospec: # The root service that clients use to connect to the destination application. service: web-svc # Services inside the namespace with their own selectors, endpoints and configuration. backends: - service: web-svc # Identical to resources, 1 = 1000m weight: 500m - service: web-svc-2 weight: 500m
Kudos to the Linkerd team who supported me to fix this issue. It is working like a charm.