Minor nit: in the diagram labeled "the flow of a DNS query in Kubernetes," it says a DNS query is a syscall. That is incorrect: DNS lookups happen in userspace, not the kernel.
>"That is incorrect: DNS lookups happen in userspace, not the kernel."
That's not even a nit, it's just plain wrong. While getaddrinfo is a library function it will invoke a torrent of system calls - socket, connect, sendto, recvmesg, open, close, fstat etc. Unless a host is found in a local cache or in a file specified in nsswitch.conf, it invariably involves sending and receiving packets over the network. These network round trips are all a part of the "the query" and you can't have those without system calls. The query is a query to a distributed database.
"By default the pure Go resolver is used, because a blocked DNS request consumes only a goroutine, while a blocked C call consumes an operating system thread. When cgo is available, the cgo-based resolver is used instead under a variety of conditions: on systems that do not let programs make direct DNS requests (OS X) ..." [1]. There is also a litany of other conditions that will cause it to use getaddrinfo instead. So it's really OS dependent.
Windows also used the libc resolver until Go 1.18.
>"When a pod performs a DNS lookup, the query is first sent to the local DNS resolver in the pod. This resolver uses the resolv.conf configuration file. In this file, the nodelocaldns server is set up as the default recursive DNS resolver, which acts as a cache."
and then:
>"Here's the TLDR. When a pod performs a DNS lookup, the query is first sent to the DNS cache on the node where the pod is running. If the cache does not contain the IP address for the requested hostname, the query is forwarded to the cluster DNS server."
It's somewhat bizarre to include an optional add-on component such a node-local DNS as part of a discussion about the default name resolution flow in Kubernetes. It is only towards the end of the post that the author mentions that node-local DNS is not actually a default component in Kubernetes.
This is usually by calling a library function in libc, but sometimes not. For example, most programs written in Go (such as Kubernetes itself) use their own resolver instead of https://www.man7.org/linux/man-pages/man3/getaddrinfo.3.html (or its predecessor, https://www.man7.org/linux/man-pages/man3/gethostbyname.3.ht...). This can lead to "fun" issues where the behavior between resolvers diverges, such as https://github.com/golang/go/issues/15419.