OPENSHIFT , DNS

CoreDNS Custom DNS Running on OpenShift

#rhel , #coredns , #core , #zone

CoreDNS Custom DNS Running on OpenShift

This example provides the bare requirements for deploying a custom DNS server on OpenShift using the default restricted SCC profile, which means that the pod is run without privileges as a nonroot user. This should work fine on both OpenShift 3.11 and 4.x.

You can edit this dns-config ConfigMap as necessary to modify the DNS zone records as you need.

$ echo 'apiVersion: v1
data:
  Corefile: |
    example.com:8053 {
        log stdout
        file /etc/coredns/example.com
    }
  example.com: |
    $TTL    1800
    $ORIGIN example.com.

    @ IN SOA dns domains (
        2020031101   ; serial
        300          ; refresh
        1800         ; retry
        14400        ; expire
        300 )        ; minimum

    infra        IN  A  192.168.1.5
kind: ConfigMap
metadata:
  name: dns-config' | oc create -f -

Deploy from the OpenShift CoreDNS base image, overriding the config file location to point to your configmap and passing the correct parameters to the startup command.

$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
  name: dns
  labels:
    app: dns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dns
      deployment: dns
  template:
    metadata:
      labels:
        app: dns
        deployment: dns
    spec:
      containers:
      - name: coredns-openshift
        image: quay.io/openshift/origin-coredns:4.5
        command: ["/usr/bin/coredns"]
        args: ["-dns.port","8053","-conf","/etc/coredns/Corefile"]
        volumeMounts:
        - mountPath: /etc/coredns
          name: dns-config
      volumes:
      - configMap:
          defaultMode: 420
          name: dns-config
        name: dns-config' | oc create -f -

You can create and test the service URL doing the following, assuming you are somewhere within your kubernetes cluster (you could run a tool-box, see below):

$ echo 'apiVersion: v1
kind: Service
metadata:
  labels:
    app: dns
  name: dns
spec:
  ports:
  - name: 8053-tcp
    port: 8053
    protocol: TCP
    targetPort: 8053
  - name: 8053-udp
    port: 8053
    protocol: UDP
    targetPort: 8053
  selector:
    app: dns
    deployment: dns' | oc create -f -

Test from somewhere accessible to this service URL, replacing the PROJECT_NAME with your equivalent.

$ dig @dns.PROJECT_NAME.svc.cluster.local -p 8053 infra.example.com

You can test the DNS externally from you cluster with a NodePort, assuming you know a hostname or IP of one of your nodes. Here I am testing from a minishift server.

$ echo 'apiVersion: v1
kind: Service
metadata:
  name: dns-np
  labels:
    name: dns-np
spec:
  type: NodePort
  ports:
    - port: 8053
      nodePort: 30053
      name: dns
      protocol: TCP
    - port: 8053
      nodePort: 30053
      name: dns-udp
      protocol: UDP
  selector:
    app: dns
    deployment: dns' | oc create -f -
$ oc get nodes -o wide
NAME        STATUS    ROLES     AGE       VERSION           INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                                      KERNEL-VERSION               CONTAINER-RUNTIME
localhost   Ready     <none>    13d       v1.11.0+d4cacc0   192.168.122.37   <none>        Red Hat Enterprise Linux Server 7.6 (Maipo)   3.10.0-957.21.3.el7.x86_64   docker://1.13.1

$ dig @192.168.122.37 -p 30053 infra.example.com

; <<>> DiG 9.11.14-RedHat-9.11.14-2.fc30 <<>> @192.168.122.37 -p 30053 infra.example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58385
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 2bd314a819029d1f (echoed)
;; QUESTION SECTION:
;infra.example.com.		IN	A

;; ANSWER SECTION:
infra.example.com.	1800	IN	A	192.168.1.5

;; Query time: 8 msec
;; SERVER: 192.168.122.37#30053(192.168.122.37)
;; WHEN: Wed Mar 11 11:10:06 EDT 2020
;; MSG SIZE  rcvd: 91

Should you want to test changes to your configmap, you need to restart the container to pickup changes.

$ kubectl rollout restart deployment/dns

Deploy a DNS toolbox test pod

You can build this container from your own host or within OpenShift. It is an extension of the redhat-cop tool-box at https://quay.io/repository/redhat-cop/tool-box and https://github.com/redhat-cop/containers-quickstarts/tree/master/tool-box

This example was built from v1.16 for a 3.11 cluster. If you build from your own host, you will need to push to a registry that OpenShift can pull from.

$ mkdir dns-tools && cd dns-tools
$ echo 'FROM quay.io/redhat-cop/tool-box:v1.16

USER 0

RUN dnf install bind-utils -y

USER 1001' > Dockerfile
$ oc new-build . --name dns-tools
$ oc start-build dns-tools --from-dir=.
$ oc get is | grep dns-tools
dns-tools   172.30.1.1:5000/myproject/dns-tools   latest    15 minutes ago
$ oc run -i -t dns-tools-test --image=172.30.1.1:5000/myproject/dns-tools --rm bash

This should be run within the same namespace/project. If you are using the network-policy plugin with default configuration, you will not need to create any special rules for accessing the service URL.