Accessing services in minikube via DNS
Recently I started working on a Kubernetes operator. For local development, I set up a minikube cluster using the docker driver on my Fedora 36 workstation.
It’s convenient to access Kubernetes services directly from the host.
For example, to run a curl
command or open a web page in the browser.
I was searching for viable methods to do that, and found the following options:
kubectl port-forward
This works well, but you need to start a new (long-running) command for each service. In case two services share the same port number in the cluster, you need to translate one port as you can’t have two services forwarded to the same local port.
NodePort
or LoadBalancer
services
The Accessing apps section from the minikube docs outlines this approach.
In my case, I wanted to access ClusterIP
services with a human-readable name (aka DNS), and without changing the service type of the existing services.
I wasn’t satisfied with either option.
I kept looking and stumbled across the minikube tunnel
command.
This handy command creates a new entry in the routing table to route internal cluster IPs to the minikube cluster.
That got me wondering… can I access the kube-dns DNS server from my local machine?
# start the tunnel (using tmux or in a new terminal)
$ minikube tunnel
# get the IP of the kube-dns service
$ kubectl -n kube-system get svc kube-dns
# query the kube-dns DNS server
$ dig @10.96.0.10 my-kubernetes-service.my-kubernetes-namespace.svc.cluster.local
It works!
Final Solution
Now I just need to resolve DNS queries ending in cluster.local
with the kube-dns DNS resolver.
This can be accomplished by configuring the DNS server and search domain of the minikube bridge network interface:
$ sudo resolvectl dns $(ip r | grep $(minikube ip) | awk '{print $NF}') 10.96.0.10
$ sudo resolvectl domain $(ip r | grep $(minikube ip) | awk '{print $NF}') cluster.local
Note: This command assumes systemd-resolved
is your configured DNS resolver (default on e.g. Fedora 36).
Alternatively, you can also configure NetworkManager
in a similar manner, or set up a local dnsmasq
instance.
With these settings in place, I can access Kubernetes services via DNS.
For example, I can now access the OpenTelemetry collector at http://simplest-collector.default.svc.cluster.local:4318
and its metrics at http://simplest-collector-monitoring.default.svc.cluster.local:8888/metrics