When I played around with DNS load balancing in a Docker Compose environment, I initially thought that the Docker DNS server (
127.0.0.11) performed round robin load balancing by shuffling the list of IP addresses when it resolves a host. I assumed that the client (i.e. NGINX in that example) would always select the first IP address from the resolved shuffled IP addresses. This approach means that the client wouldn't need to handle shuffling, caching, and iterating through the host's IP addresses, which achieves a form of "poor man's load balancing".
I shared my assumption with my manager and he offered a different view. He shared Daniel Stenberg's (creator of cURL) article on DNS round robin, which challenged my assumption and led me down a rabbit hole of digging through RFCs and source code. I gleaned the following learnings from Daniel's article:
getaddressinfo()is newer and supports IPv6, which
getaddressinfo()might sort the list of IP addresses returned by the DNS server. 🤔
getaddressinfo()was written before RFC 3484 was published.
getaddrinfo()implementations should prefer destination addresses with the longest matching prefix as the source destination. A simplified example would look like this:
getaddressinfo()returns returns IP addresses in random order, which can be used for poor man's round-robin load balancing.
getaddressinfo()returns IP addresses in a fixed order (based on RFC 6724 rules?). Round-robin load balancing (where the client selects the first IP address always) no longer works.