Add guideline on DNS-based service discovery

Change-Id: Ia7e136318a9b41b9492a9ee31ff56ddea80732fc
This commit is contained in:
Dmitry Tantsur 2019-04-09 14:43:41 +02:00 committed by Monty Taylor
parent 2ef2b12a82
commit a5a353ced4
1 changed files with 130 additions and 0 deletions

130
guidelines/dns-sd.rst Normal file
View File

@ -0,0 +1,130 @@
DNS-based Service Discovery
===========================
The normal way to discover OpenStack services is via the :doc:`service catalog
<consuming-catalog>`. However, in some edge cases it may be convenient to use
DNS-based discovery, for example:
#. Initial discovery of the Identity service endpoint via DNS.
#. Discovery of a service on the local network, especially in standalone case.
.. warning::
This guideline does not endorse any services to implement any DNS-based
discovery, but rather serves as guidance for services and deployments
that need it.
This guideline is heavily based on two IETF documents:
* `RFC 6763`_ defines DNS service discovery.
* `RFC 6762`_ defines the Multicast DNS protocol (or mDNS).
Service Type
------------
`RFC 6763`_ section 7 defines a fully qualified domain name for a service in
the following format::
<instance>.<servicename>._tcp.<domain>.
where:
``domain``
is a parent domain that the service belong to. It must be ``local`` for
multicast DNS.
``servicename``
is a service-specific protocol name, which in case of OpenStack API
discovery MUST be ``_openstack``.
``instance``
is an instance of a service, which in case of OpenStack API discovery MUST
be an OpenStack service type, such as ``compute``, ``identity`` or
``baremetal``. Project code names, such as ``nova``, MUST NOT be used.
Service Information
-------------------
The DNS ``SRV`` record will provide a host and port number for the service.
DNS ``TXT`` records SHOULD be used to communicate the remaining parts required
to access a service. `RFC 6763`_ defines the format of these records to be
key-value pairs separated by ``=``. This guideline defines the following keys:
``path``
SHOULD be used to specify the path part of the endpoint. If missing, ``/``
MUST be assumed.
.. note::
It's tempting to prefix the keys defined here with something like
``os_``, but ``path`` is used in the examples in `RFC 6763`_ in exactly
the same role, so it may be familiar enough to potential consumers
and tools.
``protocol``
SHOULD be used to specify whether to use HTTP or HTTPS. If present, it MUST
be ``http`` or ``https``. If absent, a consumer SHOULD use the port to
decide which protocol to use:
* if port is 80, use HTTP,
* if port is 443, use HTTPS,
If port is not one of 443 and 80, a consumer SHOULD try HTTPS and MAY fall
back to HTTP if it fails.
``txtvers``
SHOULD be used as defined in `RFC 6763`_ to designate the version of the
format. If present, its value MUST be ``1``.
Examples
--------
Identity discovery for a provider
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As a new user of OpenStack provider ``mystack.example.com``, I would like to
discover the ``auth_url`` to use.
I issue a DNS request to retrieve ``SRV`` and ``TXT`` records::
$ nslookup -query=any "identity._openstack._tcp.mystack.example.com" master
identity._openstack._tcp.mystack.example.com service = 0 0 443 os.mystack.example.com
identity._openstack._tcp.mystack.example.com text = "txtvers=1" "path=/"
Now I know that I have to connect to ``os.mystack.example.com``, port 443.
From the ``TXT`` records I know that I should use the root path. The protocol
is not specified, so from port 443 I derive using HTTPS.
Result: ``auth_url`` is ``https://os.mystack.example.com/``.
Local discovery of ironic
~~~~~~~~~~~~~~~~~~~~~~~~~
The ironic service ramdisk needs to discover baremetal (ironic) and baremetal
introspection (ironic-inspector) API endpoints after start up. The service
catalog is not available to it.
The ramdisk issues a multicast DNS request to list OpenStack services. An
equivalent Avahi_ (FOSS mDNS and DNS-SD implementation) command would be::
$ avahi-browse -rt _openstack._tcp
+ eth1 IPv4 baremetal _openstack._tcp local
+ eth1 IPv4 baremetal-introspection _openstack._tcp local
= eth1 IPv4 baremetal _openstack._tcp local
hostname = [baremetal._openstack._tcp.local]
address = [192.168.42.17]
port = [80]
txt = ["proto=http" "path=/baremetal"]
= eth1 IPv4 baremetal-introspection _openstack._tcp local
hostname = [baremetal-introspection._openstack._tcp.local]
address = [192.168.42.17]
port = [5050]
txt = ["proto=http"]
Here we do a multicast search for all services matching service type
``_openstack._tcp`` defined in `Service Type`_. We receive two results for
the expected services, each containing an IP address, a TCP port and ``proto``
and ``path`` variables as part of its ``TXT`` section.
Result:
* The baremetal endpoint is ``http://192.168.42.17/baremetal``.
* The baremetal introspection endpoint is ``http://192.168.42.17:5050``.
.. _RFC 6763: https://www.ietf.org/rfc/rfc6763.txt
.. _RFC 6762: https://www.ietf.org/rfc/rfc6762.txt
.. _Avahi: https://avahi.org/