At this moment, we're using our own repository, branch 4.3.0-globodns: https://github.com/globocom/cloudstack/tree/4.3.0-globodns. However, we hope to commit these changes to branch 4.5 in Cloudstack repository.
When deploying Advanced Networks, Virtual Routers are used to isolate networks and provide DNS service for all machines inside each network. While this approach is better for keeping networks more secure and self-contained, it imposes a challenge when machines need to translate names that belong to machines from another network, i.e. machine in network A needs to find the IP address of a machine in network B.
A common solution for this problem is to make sure the Virtual Router from network B has its name translated from network A, but this does not scale to a corporate network, where you need to translate domain names of every machine from every network.
We tackled this problem by using a centralized DNS server, which is external to all networks in Cloudstack. That way, every machine is registered in that server and every other machine can translate its name by accessing that server as well. This server can run any known enterprise DNS server, such as Bind, and provide its services through an external API.
This proposal includes both GloboDNS (an API to manage DNS zones and domains) to be run in a DNS server and a plugin designed for integrating virtual machines and virtual networks in Cloudstack with GloboDNS.
Allow Cloudstack to manage DNS domains and records in Bind DNS, through GloboDNS (https://github.com/globocom/GloboDNS).
1.0 - Initial version
Bind DNS: an implementation of DNS server specification. It's the reference implementation.
DNS Domain: called DNS zone by DNS servers, but in this document we use DNS domain to avoid conflict with Cloudstack zones. Same concept as network domain.
DNS Record: each DNS domain has an entry called DNS record, which is composed by a tuple of name, type and value. For example, a regular name/IP is a tuple of name=hostname, type=A and value=IP of the virtual machine.
Create a network provider of DNS, called GloboDNS, so users can choose to register records in a centralized DNS server or keep using Virtual Router in others networks.
Administrators can choose which domains will be visible to other networks. By using a network offering with Virtual Router as DNS provider, names from this network will not be visible to other networks, but will be able to translate names from networks that use GloboDNS as DNS provider. This is guaranteed if the DNS server managed by GloboDNS is the same as the internal DNS of a zone.
GloboDNS only manage names of virtual machines of types User, Console Proxy and Domain Router.
It is necessary to activate GloboDNS in each zone you want to use it.
Networks with GloboDNS as DNS provider will not use Virtual Router as DNS service, but that does not prevent Virtual Router from being used for other services, such as DHCP.
DNS records use machine hostname as name
Plugin handles reverse domains and reverse records as well.
It is expected to work with any hypervisor, but tests were conducted only with XenServer 6.2.
Networks using GloboDNS as DNS provider need to have access to Bind servers. The plugin does not control network ACLs.
Open Issues:
Hostnames with upper case characters are not supported, since Bind is not case sensitive. It is necessary to set the configuration "instance.name" to lower-case letters.
Test Scenarios
There are many test scenarios implement in GloboDnsResourceTest.java and GloboDnsElementTest.java
Features
All GloboDNS logging is done with "com.globo.globodns" namespace
There are no special events triggered
When a name already exists in GloboDns, it can be overridden or not, depending of global option globodns.override.entries. Bellow there is a table with all possible cenarios.
Call | Override (globodns.override.entries) | Domain exists? | Record exists? | Action | Test |
Create domain | Yes | Yes | -- | INFO | |
Create domain | Yes | No | -- | Create domain | OK |
Create domain | No | Yes | -- | INFO | OK |
Create domain | No | No | -- | Create domain | |
Create record | Yes | Yes | Yes | Override record | OK |
Create record | Yes | Yes | No | Create record | OK |
Create record | Yes | No | -- | Create domain & record | OK |
Create record | Yes | No | -- | Create domain & record | |
Create record | No | Yes | Yes | ERROR | OK |
Create record | No | Yes | No | Create record | |
Create record | No | No | -- | Create domain & record | OK |
Create record | No | No | -- | Create domain & record | |
Remove record | Yes | Yes | Yes | Remove record | OK |
Remove record | Yes | Yes | No | INFO | |
Remove record | Yes | No | -- | INFO | |
Remove record | Yes | No | -- | INFO | |
Remove record | No | Yes | Yes | If record is exactly same, remove record Otherwise, INFO | OK |
Remove record | No | Yes | No | INFO | |
Remove record | No | No | -- | INFO | |
Remove record | No | No | -- | INFO | |
Remove domain | Yes | Yes | -- | Remove domain | OK |
Remove domain | Yes | No | -- | INFO | |
Remove domain | No | Yes | -- | If no more records, remove domain Otherwise, WARN | OK |
Remove domain | No | No | -- | INFO |
Changes in code:
Administrator must access provider configuration in Infrastructure → Zone → Physical Network → Network Service Providers → GloboDNS.
Click "Add" button (GloboDNS Configuration), and type the e-mail, password and endpoint of GloboDNS and click OK. A new entry in host/host_details table is created to store this configuration.
Click "Enable Provider" button and wait for plugin to be enabled.
Administrator must access provider configuration in Infrastructure → Zone → Physical Network → Network Service Providers → GloboDNS.
Click "Disable Provider" button and wait for plugin to be disabled. Host/Host_details entries are marked as removed.
Administrator must create a new network offering.
In supported Services, check DNS, and in DNS Provider choose GloboDNS.
Network offering creation must be enabled before using it.
GloboDNS is called to implement network.
Network provider calls GloboDNS to create network domain and reverse domain.
GloboDNS is called to destroy network.
Network provider calls GloboDNS to remove network domain and reverse domain.
GloboDNS provider is called to prepare virtual machine.
GloboDNS provider checks if virtual machine type is User, Virtual Router or Console Proxy. Otherwise, it does nothing.
If virtual machine type is User, check if there is uppercase character in hostname.
GloboDNS is called to create a new record.
GloboDNS is called to create a new reverse record.
IDs of DNS records and reverse record are store in database.
GloboDNS provider is called to release virtual machine.
Network provider checks if virtual machine type is User, Virtual Router or Console Proxy. Otherwise, it does nothing.
GloboDNS is called to remove DNS record and reverse record.
Remove record and reverse record IDs from database.
All calls to GloboDNS are in DNSAPIResource. This approach avoids confusion, since GloboDNS Client code is isolated from Cloudstack core code.
GloboDnsResource type is L2Networking for lack of a better option.
GloboDNS generates Bind configuration files and exports to DNS server using rsync calls over SSH. Then, DNS server is reloaded. Bind servers are synced using IXFR (Incremental Zone Transfers, RFC 1995)
addGloboDnsHost: configure GloboDNS credentials and endpoint in Zone. Needs to be called before plugin is enabled in zone.
The only change in UI is to ask user about credentials and endpoint of API in Network Provider configuration for a Zone.
There is a video showing how the plugin works: https://www.youtube.com/watch?v=fAB53T_NZMI