I installed Linkerd in a fresh GKE cluster using the following Helm Chart: “linkerd-control-plane:1.15.0”
Everything works as expected apart to “session affinity” with nginx which used to work for me before starting using Linkerd.
I want to clarify that Nginx ingress works as expected for everything else, it routes traffic as expected and is part of the mesh as expected.
I even removed the ‘nginx.ingress.kubernetes.io/service-upstream: “true”’ annotation from the ingress itself since I have been told that the ingress needs to communicate with the endpoints directly for the session affinity to work.
Unfortunately, this is more of a NGINX configuration question than a Linkerd one.
One thing you can do on the Linkerd side would be to look at the linkerd proxy logs to see what ip address NGINX is connecting to and verifying that NGINX is connecting to the service cluster IP instead of to an endpoint IP.
Couldn’t find any issue with NGINX, without Linkerd everything works perfectly. Unfortunately I had to move to a k8s headless service to force direct endpoint discovery for services I want to use with session affinity and Linkerd
NGINX helm chart 4.8.3 (up to date)
With the following extra values for Linkerd
podAnnotations:
linkerd.io/inject: enabled
# This annotation is important as it doesn't route traffic through the proxy which enables ip preservation
config.linkerd.io/skip-inbound-ports: 80,443 # the workaround
Hey @Flynn and @arielzadino isn’t this stopping nginx from sending traffic to the injected linkerd proxy for ports 80 and 443? In theory this sounds a workaround if you don’t allow unmeshed traffic with authorization policy this should be an issue!
I think if there is a way the mtls cert from the NGINX ingress to be generated by cert manager if it is used by Linkerd to be a better workaround as this way nginx will authenticate to backend pods. Only metric collections could be impacted but Nginx Plus should handle this.
The behavior here will be slightly different depending on if nginx is connecting to the service cluster IP or to the service endpoints directly.
If nginx connects to the service cluster IP then it will only see one IP address and Linkerd will handle load balancing. This means that nginx sticky sessions will not work.
On the other hand, if nginx connects to the service endpoints directly then it is managing its own connections and load balancing and can perform sticky sessions. However, this means that any Linkerd policy which is configured on the Service resource (such as outbound HTTPRoutes or ServiceProfiles) will not apply.
In either case, the connection will be fully mTLS. Does this answer your question?
(I’ll take @Alex‘s answer a bit further: if you want sticky sessions you must configure your ingress controller to use endpoint IPs, which means that you must also have your ingress controller manage retries, timeouts, etc., because Linkerd can’t do it. This is true irrespective of which ingress controller you’re using. )