|
| 1 | +# Minikube Ingress DNS |
| 2 | + |
| 3 | + |
| 4 | +DNS service for ingress controllers running on your minikube server |
| 5 | + |
| 6 | +## Overview |
| 7 | + |
| 8 | +### Problem |
| 9 | +When running minikube locally you are highly likely to want to run your services on an ingress controller so that you |
| 10 | +don't have to use minikube tunnel or NodePorts to access your services. While NodePort might be ok in a lot of |
| 11 | +circumstances in order to test some features an ingress is necessary. Ingress controllers are great because you can |
| 12 | +define your entire architecture in something like a helm chart and all your services will be available. There is only |
| 13 | +1 problem. That is that your ingress controller works basically off of dns and while running minikube that means that |
| 14 | +your local dns names like `myservice.test` will have to resolve to `$(minikube ip)` not really a big deal except the |
| 15 | +only real way to do this is to add an entry for every service in your `/etc/hosts` file. This gets messy for obvious |
| 16 | +reasons. If you have a lot of services running that each have their own dns entry then you have to set those up |
| 17 | +manually. Even if you automate it you then need to rely on the host operating system storing configurations instead of |
| 18 | +storing them in your cluster. To make it worse it has to be constantly maintained and updated as services are added, |
| 19 | +remove, and renamed. I call it the `/ets/hosts` pollution problem. |
| 20 | + |
| 21 | +### Solution |
| 22 | +What if you could just access your local services magically without having to edit your `/etc/hosts` file? Well now you |
| 23 | +can. This project acts as a DNS service that runs inside your kubernetes cluster. All you have to do is install the |
| 24 | +service and add the `$(minikube ip)` as a DNS server on your host machine. Each time the dns service is queried an |
| 25 | +API call is made to the kubernetes master service for a list of all the ingresses. If a match is found for the name a |
| 26 | +response is given with an IP address as the `$(minikube ip)` which was provided when the helm chart was installed. So |
| 27 | +for example lets say my minikube ip address is `192.168.99.106` and I have an ingress controller with the name of |
| 28 | +`myservice.test` then I would get a result like so: |
| 29 | + |
| 30 | +```text |
| 31 | +#bash:~$ nslookup myservice.test $(minikube ip) |
| 32 | +Server: 192.168.99.169 |
| 33 | +Address: 192.168.99.169#53 |
| 34 | +
|
| 35 | +Non-authoritative answer: |
| 36 | +Name: myservice.test $(minikube ip) |
| 37 | +Address: 192.168.99.169 |
| 38 | +``` |
| 39 | + |
| 40 | +## Installation |
| 41 | + |
| 42 | +### Start minikube |
| 43 | +``` |
| 44 | +minikube start |
| 45 | +``` |
| 46 | + |
| 47 | +### Install the kubernetes resources |
| 48 | +```bash |
| 49 | +minikube addons enable ingress-dns |
| 50 | +``` |
| 51 | + |
| 52 | +### Add the minikube ip as a dns server |
| 53 | + |
| 54 | +#### Mac OS |
| 55 | +Create a file in /etc/resolver/minikube-profilename-test |
| 56 | +``` |
| 57 | +domain test |
| 58 | +nameserver 192.168.99.169 |
| 59 | +search_order 1 |
| 60 | +timeout 5 |
| 61 | +``` |
| 62 | +Replace `192.168.99.169` with your minikube ip and `profilename` is the name of the minikube profile for the |
| 63 | +corresponding ip address |
| 64 | + |
| 65 | +See https://www.unix.com/man-page/opendarwin/5/resolver/ |
| 66 | +Note that even though the `port` feature is documented. It does not actually work. |
| 67 | + |
| 68 | +#### Linux |
| 69 | + |
| 70 | +``` |
| 71 | +domain test |
| 72 | +nameserver 192.168.99.169 |
| 73 | +search_order 1 |
| 74 | +timeout 5 |
| 75 | +``` |
| 76 | +Replace `192.168.99.169` with your minikube ip and `profilename` is the name of the minikube profile for the |
| 77 | +corresponding ip address |
| 78 | + |
| 79 | +See https://linux.die.net/man/5/resolver |
| 80 | + |
| 81 | +#### Windows |
| 82 | + |
| 83 | +TODO |
| 84 | + |
| 85 | +## Testing |
| 86 | + |
| 87 | +### Add the test ingress |
| 88 | +```bash |
| 89 | +kubectl apply -f https://github.com/kubernetes/minikube/blob/master/deploy/addons/ingress-dns/example/example.yaml |
| 90 | +``` |
| 91 | +Note: Minimum Kubernetes version for example ingress is 1.14.7 |
| 92 | + |
| 93 | +### Validate DNS queries are returning A records |
| 94 | +```bash |
| 95 | +nslookup hello-john.test $(minikube ip) |
| 96 | +nslookup hello-jane.test $(minikube ip) |
| 97 | +``` |
| 98 | + |
| 99 | +### Validate domain names are resolving on host OS |
| 100 | +```bash |
| 101 | +ping hello-john.test |
| 102 | +``` |
| 103 | +Expected results: |
| 104 | +```text |
| 105 | +PING hello-john.test (192.168.99.169): 56 data bytes |
| 106 | +64 bytes from 192.168.99.169: icmp_seq=0 ttl=64 time=0.361 ms |
| 107 | +``` |
| 108 | +```bash |
| 109 | +ping hello-jane.test |
| 110 | +``` |
| 111 | +```text |
| 112 | +PING hello-jane.test (192.168.99.169): 56 data bytes |
| 113 | +64 bytes from 192.168.99.169: icmp_seq=0 ttl=64 time=0.262 ms |
| 114 | +``` |
| 115 | + |
| 116 | +### Curl the example server |
| 117 | +```bash |
| 118 | +curl http://hello-john.test |
| 119 | +``` |
| 120 | +Expected result: |
| 121 | +```text |
| 122 | +Hello, world! |
| 123 | +Version: 1.0.0 |
| 124 | +Hostname: hello-world-app-557ff7dbd8-64mtv |
| 125 | +``` |
| 126 | +```bash |
| 127 | +curl http://hello-jane.test |
| 128 | +``` |
| 129 | +Expected result: |
| 130 | +```text |
| 131 | +Hello, world! |
| 132 | +Version: 1.0.0 |
| 133 | +Hostname: hello-world-app-557ff7dbd8-64mtv |
| 134 | +``` |
| 135 | + |
| 136 | +## Known issues |
| 137 | + |
| 138 | +### .localhost domains will not resolve on chromium |
| 139 | +.localhost domains will not correctly resolve on chromium since it is used as a loopback address. Instead use .test, .example, or .invalid |
| 140 | + |
| 141 | +### .local is a reserved TLD |
| 142 | +Do not use .local as this is a reserved TLD for mDNS and bind9 DNS servers |
| 143 | + |
| 144 | +### Mac OS |
| 145 | + |
| 146 | +#### mDNS reloading |
| 147 | +Each time a file is created or a change is made to a file in `/etc/resolver` you may need to run the following to reload Mac OS mDNS resolver. |
| 148 | +```bash |
| 149 | +sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist |
| 150 | +sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist |
| 151 | +``` |
| 152 | + |
| 153 | +## TODO |
| 154 | +- Add a service that runs on the host OS which will update the files in `/etc/resolver` automatically |
| 155 | +- Start this service when running `minikube addons enable ingress-dns` and stop the service when running |
| 156 | +`minikube addons disable ingress-dns` |
| 157 | + |
| 158 | +## Contributors |
| 159 | +- [Josh Woodcock](https://github.com/woodcockjosh) |
0 commit comments