Appendix A. Creating the DNS Red Hat OpenStack Platform Instance

The installation process for Red Hat OpenShift Container Platform depends on a reliable name service that contains an address record for each of the target instances. When installing Red Hat OpenShift Container Platform in a cloud environment, the IP address of each instance is not known at the beginning. The address record for each instance must be created dynamically by the orchestration system as the instances themselves are created.

Red Hat OpenStack Platform does not have an integrated DNS service, but it is possible to create new records in a DNS service using dynamic updates as defined in RFC2137. This method uses a symmetric key to authenticate and authorize updates to a specific zone.

Installation of Red Hat OpenShift Container Platform on Red Hat OpenStack Platform requires a DNS service capable of accepting DNS update records for the new instances. This section describes a method to create a suitable DNS service within Red Hat OpenStack Platform. The DNS is capable of accepting DNS queries and update requests for the Red Hat OpenStack Platform service. It is suitable for delegation to make the Red Hat OpenShift Container Platform service accessible to users.

The following steps create a DNS Red Hat OpenStack Platform instance and configure it.

  1. Source the RC file for the project

    $ source /path/to/examplerc
  2. Create a security group to allow incoming connections to the DNS service (ports 53 UDP and TCP), ssh to manage the instance and ICMP for debug purposes.

    $ openstack security group create <dns-sg-name>
    $ openstack security group rule create \
        --ingress \
        --protocol icmp \
        <dns-sg-name>
    $ openstack security group rule create \
        --ingress \
        --protocol tcp \
        --dst-port 22 \
        <dns-sg-name>
    $ for PROTO in udp tcp;
    do
      openstack security group rule create \
        --ingress \
        --protocol $PROTO \
        --dst-port 53 \
        <dns-sg-name>;
    done
  3. Create the Red Hat OpenStack Platform instance

    $ netid1=$(openstack network show <internal-network-name> -f value -c id)
    $ openstack server create \
        --nic net-id=$netid1 \
        --security-group=<dns-sg-name> \
        --flavor <flavor-name> \
        --image <image-name> \
        --key-name <keypair-name> <instance-name>
  4. Assign and attach a floating IP to the instance

    $ openstack floating ip create <public-network-name>
    $ openstack server add floating ip <instance-name> <ip>
  5. Log into the Red Hat OpenStack Platform instance that shall become the the DNS server.

    $ ssh -i /path/to/<keypair-name>.pem cloud-user@<IP-of-dns-instance>

A.1. Setting up the DNS Red Hat OpenStack Platform Instance

The following steps configure a DNS server once logged into the instance.

  1. Ensure that PEERDNS=no and DNS1=<forwarder_dns_ip> within the /etc/sysconfig/network_scripts/ifcfg-eth0

    $ cat /etc/sysconfig/network_scripts/ifcfg-eth0
    # Created by cloud-init on instance boot automatically, do not edit.
    #
    BOOTPROTO=dhcp
    DEVICE=eth0
    HWADDR=fa:16:3e:d0:2f:d8
    ONBOOT=yes
    TYPE=Ethernet
    USERCTL=no
    PEERDNS=no
    DNS1=<forwarder_dns_ip>
  2. Subscribe to the following repositories using subscription-manager

    $ sudo subscription-manager register
    $ sudo subscription-manager attach --pool <pool_id>
    $ sudo subscription-manager repos --disable=*
    $ sudo subscription-manager repos \
        --enable=rhel-7-server-rpms \
        --enable=rhel-7-server-extras-rpms
  3. Subscribe to the EPEL repository

    $ sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  4. Install the following packages:

    • firewalld
    • python-firewall
    • bind-utils
    • bind
    $ sudo yum install -y firewalld python-firewall bind-utils bind
  5. Enable the firewalld service and start it

    $ sudo systemctl enable firewalld && sudo systemctl start firewalld
  6. Add the DNS service to the firewalld public zone

    $ sudo firewall-cmd --zone public --add-service dns
    $ sudo firewall-cmd --zone public --add-service dns --permanent
  7. Copy the named.conf prior to modification

    $ sudo cp /etc/named.conf{,.orig}

The following diff command shows the difference between the original named.conf file and newest named.conf file. The - means the line was removed, while the + means the line has been added to the newest named.conf. When modifying the named.conf remove all lines with a - and include all lines with +.

$ diff -u /etc/named.conf.orig /etc/named.conf
--- /etc/named.conf.orig        2016-03-22 14:15:45.000000000 +0000
+++ /etc/named.conf     2017-05-03 16:21:00.579000000 +0000
@@ -6,17 +6,15 @@
 //
 // See /usr/share/doc/bind*/sample/ for example named configuration files.
 //
-// See the BIND Administrator's Reference Manual (ARM) for details about the
-// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

 options {
-   listen-on port 53 { 127.0.0.1; };
-   listen-on-v6 port 53 { ::1; };
+   listen-on port 53 { any ; };
+   // listen-on-v6 port 53 { ::1; };
    directory   "/var/named";
    dump-file   "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    memstatistics-file "/var/named/data/named_mem_stats.txt";
-   allow-query     { localhost; };
+   allow-query     { any ; };

    /*
     - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
@@ -28,18 +26,27 @@
       attacks. Implementing BCP38 within your network would greatly
       reduce such attack surface
    */
-   recursion yes;
+   // recursion yes;
+  forward only;
+  forwarders { <IP of DNS1 forwarder> ; <IP of DNS2 forwarder_if_more_than_1> ; } ;

-   dnssec-enable yes;
-   dnssec-validation yes;
+   // dnssec-enable yes;
+   // dnssec-validation yes;

    /* Path to ISC DLV key */
-   bindkeys-file "/etc/named.iscdlv.key";
+   /* In case you want to use ISC DLV, please uncomment the following line. */
+   //bindkeys-file "/etc/named.iscdlv.key";

    managed-keys-directory "/var/named/dynamic";

    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";
+
+   /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
+  //include "/etc/crypto-policies/back-ends/bind.config";
+
+        /* tickle slaves to pull updates */
+        notify yes ;
 };

 logging {
@@ -54,6 +61,10 @@
    file "named.ca";
 };

+
 include "/etc/named.rfc1912.zones";
 include "/etc/named.root.key";

+include "/etc/named/zones.conf" ;

Once the changes have been made, save the the named.conf file.

Next, create a zones.conf file that provides the zone that is to be used for the RHOCP installation. An example of a zones.conf is shown below.

/etc/named/zones.conf

include "/etc/named/update.key" ;

zone example.com {
  type master ;
  file "/var/named/dynamic/zone.db" ;
  allow-update { key update-key ; } ;
};

In order to update the DNS, the DNS requires a special key string that can be generated by rndc-confgen which is part of the bind RPM. The update.key file should exist within the /etc/named directory.

To create the update.key file run the following command:

$ sudo rndc-confgen -a -c /etc/named/update.key -k update-key -r /dev/urandom
$ sudo chown root.named /etc/named/update.key
$ sudo chmod 640 /etc/named/update.key

Example output:

$ sudo cat /etc/named/update.key
key "update-key" {
    algorithm hmac-md5;
    secret "key string"; # don't use this
};
Warning

The significant part of the key output is the secret field. This should be kept secret as someone may make edits to the DNS entries with the key.

Once the zones.conf file has been created, one must update using nsupdate to contain all the Red Hat OpenShift Container Platform hosts and their IP addresses.

Note

Due to not having any Red Hat OpenStack Platform instances created yet, thus no IP addresses, return to this section for completing the input of IPs required within the zones.db file once Section 2.9, “Creating RHOSP Instances for RHOCP” section is completed.

Once the instances have been created, and IP addresses are obtained, update the DNS entries for zone example.com and zone apps.example.com as follows:

nsupdate -k /etc/named/update.key <<EOF
server <dns-server-ip>
zone example.com
update add bastion.example.com 3600 A <internal-net-ip>
update add app0.example.com 3600 A <internal-net-ip>
update add app1.example.com 3600 A <internal-net-ip>
update add master0.example.com 3600 A <internal-net-ip>
update add master1.example.com 3600 A <internal-net-ip>
update add master2.example.com 3600 A <internal-net-ip>
update add infra0.example.com 3600 A <internal-net-ip>
update add infra1.example.com 3600 A <internal-net-ip>
update add infra2.example.com 3600 A <internal-net-ip>
update add dns.example.com 3600 A <public-ip>
update add haproxy.example.com 3600 A <public-ip>
update add openshift.example.com 3600 A <haproxy-public-ip>
send
quit
EOF
nsupdate -k /etc/named/update.key <<EOF
server <dns-server-ip>
zone apps.example.com
update add * 3600 A <infra0_public_IP>
update add * 3600 A <infra1_public_IP>
update add * 3600 A <infra2_public_IP>
send
quit
EOF

Example of the /var/named/dynamic/zone.db file:

/var/named/dynamic/zone.db

$ORIGIN .
$TTL 300        ; 5 minutes
example.com             IN SOA  dns.example.com. admin.example.com. (
                                16         ; serial
                                28800      ; refresh (8 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      dns.example.com.
$ORIGIN apps.example.com.
*                       A       <infra0_public_IP>
                        A       <infra1_public_IP>
                        A       <infra2_public_IP>
$ORIGIN example.com.
app0              A       <internal-net-IP>
app1              A       <internal-net-IP>
bastion                 A       <internal-net-IP>
dns                     A       <public_IP>
haproxy                 A       <public_IP>
infra0              A       <internal-net-IP>
infra1              A       <internal-net-IP>
infra2              A       <internal-net-IP>
master0                 A       <internal-net-IP>
master1                 A       <internal-net-IP>
master2                 A       <internal-net-IP>
openshift               A       <haproxy-public_IP>

Warning

This file should not be updated manually, please use nsupdate for changes.

Once everything is set, configure named service to start at boot and start it

$ sudo systemctl enable named && sudo systemctl start named

Verification of the entire zone can be done using the dig command. The example below shows the records of the DNS dns.example.com

$ dig @<DNS_IP> example.com axfr
;; Connection to ::1#53(::1) for example.com failed: connection refused.

; <<>> DiG 9.9.4-RedHat-9.9.4-50.el7 <<>> @localhost example.com axfr
; (2 servers found)
;; global options: +cmd
example.com.            300     IN      SOA     dns.example.com. admin.example.com. 16 28800 3600 604800 86400
example.com.            300     IN      NS      dns.example.com.
app0.example.com. 300     IN      A       <internal-net-IP>
app1.example.com. 300     IN      A       <internal-net-IP>
*.apps.example.com.     300     IN      A       <infra0-public-IP>
*.apps.example.com.     300     IN      A       <infra1-public-IP>
*.apps.example.com.     300     IN      A       <infra2-public-IP>
bastion.example.com.    300     IN      A       <internal-net-IP>
dns.example.com.        300     IN      A       <public-IP>
haproxy.example.com.    300     IN      A       <public-IP>
infra0.example.com. 300   IN      A       <internal-net-IP>
infra1.example.com. 300   IN      A       <internal-net-IP>
infra2.example.com. 300   IN      A       <internal-net-IP>
master0.example.com.   300     IN      A       <internal-net-IP>
master1.example.com.   300     IN      A       <internal-net-IP>
master2.example.com.   300     IN      A       <internal-net-IP>
openshift.example.com.  300     IN      A       <haproxy-public-IP>
example.com.            300     IN      SOA     dns.example.com. admin.example.com. 16 28800 3600 604800 86400
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Apr 04 17:44:54 EDT 2018
;; XFR size: 19 records (messages 1, bytes 513)