I recently needed to setup a Kubernetes cluster without an external DNS and without Internet access. In the old days, static IPs could be mapped to FQDNs by creating entries in the hosts
file, but that won’t work with Kubernetes. With Internet access, the typical solution would be to use a wildcard DNS like xip.io or nip.io. Instead, the workaround is by hardcoding the mapping in the CoreDNS configuration.
This post is much more technical than my usual - assumes you have a running Kubernetes 1.10.x cluster with CoreDNS, which in this example is in the kube-system
namespace. Don’t trust what I say below, I’m a total novice.
First, we will need to edit the default CoreDNS ConfigMap
.
- Either edit it directly with
kubectl -n kube-system edit cm coredns
, or - Export the config map
kubectl -n kube-system get cm/coredns --export -o yaml > coredns.yaml
, edit the yaml, and then replace it withkubectl -n kube-system replace -f coredns.yaml
If you’d rather test the change temporarily, then don’t use kubectl replace
but instead just kubectl apply
so the change won’t stick.
The ConfigMap looks something like this, you’ll need to edit the .:53
section and add the lines dummy.example.com:53
onwards:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log
health
kubernetes cluster.local 127.17.0.0/16
prometheus
proxy . /etc/resolv.conf
}
dummy.example.com:53 {
file /etc/coredns/dummy.example.com
errors
log . {
class denial
class sucess
}
}
dummy.example.com: |
$ORIGIN dummy.example.com.
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
2017042745 ; serial
7200 ; refresh (2 hours)
3600 ; retry (1 hour)
1209600 ; expire (2 weeks)
3600 ; minimum (1 hour)
)
3600 IN NS a.iana-servers.net.
3600 IN NS b.iana-servers.net.
www IN A 10.10.10.90
mail IN A 10.10.10.90
10.10.10.90.in-addr.arpa. IN PTR dummy.example.com.
This will configure CoreDNS such that:
- CoreDNS will not lookup a real DNS - by removing
fallback
from the.:53
section. - CoreDNS will instead lookup a matching static file for
dummy.example.com
. - And, the static file’s contents (below the line
dummy.example.com: |
) will be the result of the DNS lookup. o Here, the FQDN iswww.dummy.example.com
ormail.dummy.example.com
, o And a reverse lookup (PTR) by IP address should return dummy.example.com`.
Now that’s done, we need to edit the CoreDNS deployment to add the static file volume. One way is to edit the deployment live, kubectl -n kube-system edit deployment coredns
which then opens the file in vim
. Once the file is edited and saved, CoreDNS will restart.
It’s a large file, but look for the volumes:
section with the name coredns
. The key and path to Corefile
will already exist, so just below that add the same for dummy.example.com
:
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
- key: dummy.example.com
path: dummy.example.com
name: coredns
name: config-volume
Follow the indents in your file, what I show here will not match yours.
Finally, test it by running a dig
(if you have it) in running container - run kubectl exec -it [pod] -- /bin/sh
and in the shell:
- Run
dig www.dummy.example.com
- if the returned ANSWER is the specified IP address, then all is good. - Then do a reverse lookup with
dig -x 10.10.10.90
- if you get your FQDN, then well done.
To add more FQDNs - for every hostname, repeat all steps above. As far as I know, each one will be a separate file.