# Setting up ExternalDNS for CoreDNS with minikube This tutorial describes how to setup ExternalDNS for usage within a [minikube](https://github.com/kubernetes/minikube) cluster that makes use of [CoreDNS](https://github.com/coredns/coredns) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx). You need to: * install CoreDNS with [etcd](https://github.com/etcd-io/etcd) enabled * install external-dns with coredns as a provider * enable ingress controller for the minikube cluster ## Creating a cluster ``` minikube start ``` ## Installing CoreDNS with etcd enabled Helm chart is used to install etcd and CoreDNS. ### Initializing helm chart ``` helm init ``` ### Installing etcd [etcd operator](https://github.com/coreos/etcd-operator) is used to manage etcd clusters. ``` helm install stable/etcd-operator --name my-etcd-op ``` etcd cluster is installed with example yaml from etcd operator website. ``` kubectl apply -f https://raw.githubusercontent.com/coreos/etcd-operator/HEAD/example/example-etcd-cluster.yaml ``` ### Installing CoreDNS In order to make CoreDNS work with etcd backend, values.yaml of the chart should be changed with corresponding configurations. ``` wget https://raw.githubusercontent.com/helm/charts/HEAD/stable/coredns/values.yaml ``` You need to edit/patch the file with below diff ``` diff --git a/values.yaml b/values.yaml index 964e72b..e2fa934 100644 --- a/values.yaml +++ b/values.yaml @@ -27,12 +27,12 @@ service: rbac: # If true, create & use RBAC resources - create: false + create: true # Ignored if rbac.create is true serviceAccountName: default # isClusterService specifies whether chart should be deployed as cluster-service or normal k8s app. -isClusterService: true +isClusterService: false servers: - zones: @@ -51,6 +51,12 @@ servers: parameters: 0.0.0.0:9153 - name: proxy parameters: . /etc/resolv.conf + - name: etcd + parameters: example.org + configBlock: |- + stubzones + path /skydns + endpoint http://10.105.68.165:2379 # Complete example with all the options: # - zones: # the `zones` block can be left out entirely, defaults to "." ``` **Note**: * IP address of etcd's endpoint should be get from etcd client service. It should be "example-etcd-cluster-client" in this example. This IP address is used through this document for etcd endpoint configuration. ``` $ kubectl get svc example-etcd-cluster-client NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-etcd-cluster-client ClusterIP 10.105.68.165 <none> 2379/TCP 16m ``` * Parameters should configure your own domain. "example.org" is used in this example. After configuration done in values.yaml, you can install coredns chart. ``` helm install --name my-coredns --values values.yaml stable/coredns ``` ## Installing ExternalDNS ### Install external ExternalDNS ETCD_URLS is configured to etcd client service address. #### Manifest (for clusters without RBAC enabled) ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: kube-system spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.7.3 args: - --source=ingress - --provider=coredns - --log-level=debug # debug only env: - name: ETCD_URLS value: http://10.105.68.165:2379 ``` #### Manifest (for clusters with RBAC enabled) ```yaml --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","endpoints","pods"] verbs: ["get","watch","list"] - apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] verbs: ["list"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: external-dns-viewer roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dns subjects: - kind: ServiceAccount name: external-dns namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: external-dns namespace: kube-system --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: kube-system spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.7.3 args: - --source=ingress - --provider=coredns - --log-level=debug # debug only env: - name: ETCD_URLS value: http://10.105.68.165:2379 ``` ## Enable the ingress controller You can use the ingress controller in minikube cluster. It needs to enable ingress addon in the cluster. ``` minikube addons enable ingress ``` ## Testing ingress example ``` $ cat ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: nginx.example.org http: paths: - backend: serviceName: nginx servicePort: 80 $ kubectl apply -f ingress.yaml ingress.extensions "nginx" created ``` Wait a moment until DNS has the ingress IP. The DNS service IP is from CoreDNS service. It is "my-coredns-coredns" in this example. ``` $ kubectl get svc my-coredns-coredns NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-coredns-coredns ClusterIP 10.100.4.143 <none> 53/UDP 12m $ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE nginx nginx.example.org 10.0.2.15 80 2m $ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools If you don't see a command prompt, try pressing enter. dnstools# dig @10.100.4.143 nginx.example.org +short 10.0.2.15 dnstools# ```