Docs issue: TCP load balancing description
Bug Report
What is the issue?
The docs regarding TCP load balancing appear to be incorrect.
The docs in question are here: https://linkerd.io/2/features/load-balancing/, and seem to say that Linkerd does TCP load balancing (For TCP connections, Linkerd will balance connections). However, that is rather misleading.
As I understand it, if you are issuing TCP connections to a remote entity using some binary protocol (such as HTTPS encrypted by the client, but any binary protocol works here), Linkerd cannot do anything to figure out the destination. Hence it just proxies the request without doing load balancing. For some protocols that linkerd2 can understand, I think Linkerd does do connection level TCP load balancing (HTTP/1.0, but maybe others).
The docs should be corrected to make the behaviour clear.
Note that Istio has different behaviour here - it looks up the IP that the connection is going to, and uses that to pick the Kubernetes service with that cluster IP to let it do load balancing. This difference is confusing unless precisely documented because people may be familiar with the Istio behaviour (which has pros and cons - not arguing for a change to behaviour in this issue).
Note also relevant docs here: https://linkerd.io/2/features/protocol-detection/
These are about metrics, not load balancing, but I think the description here of when Linkerd gets involved are pretty clear and probably the same in both cases.
Thanks for opening this, @plwhite. I'm going to move this issue to the linkerd/website repo so that it doesn't get lost.
Thanks.
I've mulled this over, and concluded that the underlying issue is that there is no logic description, something that says "When it gets a packet Linkerd does X". I'd like to see a simple flow chart explaining the Linkerd2 logic, something that says something like the following:
- For a new outbound connection from the pod, just wait until some traffic appears (unless this is a server speaks first protocol, based on the port in use, in which case just create connection and forward packets from now on). When some traffic appears, look at it to do protocol detection.
- If not HTTP (including gRPC), then give up. Just proxy all traffic through blindly to destination.
- If HTTP, then get the destination from the Host/authority header. Create connections and send requests doing load balancing, mTLS, and enhanced metrics. This includes load balancing on a per-request not per-connection basis.
For inbound traffic, I am less sure but think that it is:
- Accept connection
- If server speaks first protocol, just connect and proxy all traffic; otherwise do protocol detection.
- If protocol detection says TLS and this is mTLS inside service mesh, then do TLS decryption before proxying traffic.
@plwhite thanks for filing this. We're a bit heads down with the 2.4 release but we'll get back to you soon!