DNS Service in Azure Service Fabric
The DNS Service is an optional system service that you can enable in your cluster to discover other services using the DNS protocol.
Many services, especially containerized services, are addressable through a pre-existing URL. Being able to resolve these services using the standard DNS protocol, rather than the Service Fabric Naming Service protocol, is desirable. The DNS service enables you to map DNS names to a service name and hence resolve endpoint IP addresses. Such functionality maintains the portability of containerized services across different platforms and can make "lift and shift" scenarios easier, by letting you use existing service URLs rather than having to rewrite code to leverage the Naming Service.
The DNS service maps DNS names to service names, which in turn are resolved by the Naming Service to return the service endpoint. The DNS name for the service is provided at the time of creation. The following diagram shows how the DNS service works for stateless services.
Beginning with Service Fabric version 6.3, the Service Fabric DNS protocol has been extended to include a scheme for addressing partitioned stateful services. These extensions make it possible to resolve specific partition IP addresses using a combination of stateful service DNS name and the partition name. All three partitioning schemes are supported:
- Named partitioning
- Ranged partitioning
- Singleton partitioning
The following diagram shows how the DNS service works for partitioned stateful services.
Dynamic ports are not supported by the DNS service. To resolve services exposed on dynamic ports, use the reverse proxy service.
Enabling the DNS service
Note
DNS service for Service Fabric services is not yet supported on Linux.
When you create a cluster using the portal, the DNS service is enabled by default in the Include DNS service check box on the Cluster configuration menu:
If you're not using the portal to create your cluster or if you're updating an existing cluster, you'll need to enable the DNS service in a template:
- To deploy a new cluster, you can either use the sample templates or create your own Resource Manager template.
- To update an existing cluster, you can navigate to the cluster's resource group on the portal and click Automation Script to work with a template that reflects the current state of the cluster and other resources in the group. To learn more, see Export the template from resource group.
After you have a template, you can enable the DNS service with the following steps:
Check that the
apiversion
is set to2017-07-01-preview
or later for theMicrosoft.ServiceFabric/clusters
resource, and, if not, update it as shown in the following example:{ "apiVersion": "2017-07-01-preview", "type": "Microsoft.ServiceFabric/clusters", "name": "[parameters('clusterName')]", "location": "[parameters('clusterLocation')]", ... }
Now enable the DNS service in one of the following ways:
To enable the DNS service with default settings, add it to the
addonFeatures
section inside theproperties
section as shown in the following example:"properties": { ... "addonFeatures": [ "DnsService" ], ... }
To enable the service with other than default settings, add a
DnsService
section to thefabricSettings
section inside theproperties
section. In this case, you don't need to add the DnsService toaddonFeatures
. To learn more about the properties that can be set for the DNS Service, see DNS Service settings."properties": { ... "fabricSettings": [ ... { "name": "DnsService", "parameters": [ { "name": "IsEnabled", "value": "true" }, { "name": "PartitionSuffix", "value": "--" }, { "name": "PartitionPrefix", "value": "--" } ] }, ... ] }
Once you have updated the cluster template with your changes, apply them and let the upgrade complete. When the upgrade completes, the DNS system service starts running in your cluster. The service name is
fabric:/System/DnsService
, and you can find it under the System service section in Service Fabric explorer.
Note
When upgrading DNS from disabled to enabled, Service Fabric Explorer may not reflect the new state. To solve, restart the nodes by modifying the UpgradePolicy in your Azure Resource Manager template. See the Service Fabric Template Reference for more.
Note
Enabling DNS service when developing on a local machine will override some DNS settings. If you experience issues connecting to the internet, check your DNS settings.
Setting the DNS name for your service
You can set a DNS name for your services either declaratively for default services in the ApplicationManifest.xml file or through PowerShell commands.
The DNS name for your service is resolvable throughout the cluster so it is important to ensure the uniqueness of the DNS name across the cluster.
It is highly recommended that you use a naming scheme of <ServiceDnsName>.<AppInstanceName>
; for example, service1.application1
. If an application is deployed using Docker compose, services are automatically assigned DNS names using this naming scheme.
Setting the DNS name for a default service in the ApplicationManifest.xml
Open your project in Visual Studio, or your favorite editor, and open the ApplicationManifest.xml file. Go to the default services section, and for each service add the ServiceDnsName
attribute. The following example shows how to set the DNS name of the service to service1.application1
<Service Name="Stateless1" ServiceDnsName="service1.application1">
<StatelessService ServiceTypeName="Stateless1Type" InstanceCount="[Stateless1_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
Once the application is deployed, the service instance in the Service Fabric explorer shows the DNS name for this instance, as shown in the following figure:
The following example sets the DNS name for a stateful service to statefulsvc.app
. The service uses a named partitioning scheme. Notice that the partition names are lower-case. This is a requirement for partitions that will be targeted in DNS queries; for more information, see Making DNS queries on a stateful service partition.
<Service Name="Stateful1" ServiceDnsName="statefulsvc.app" />
<StatefulService ServiceTypeName="ProcessingType" TargetReplicaSetSize="2" MinReplicaSetSize="2">
<NamedPartition>
<Partition Name="partition1" />
<Partition Name="partition2" />
</NamedPartition>
</StatefulService>
</Service>
Setting the DNS name for a service using PowerShell
You can set the DNS name for a service when creating it using the New-ServiceFabricService
PowerShell command. The following example creates a new stateless service with the DNS name service1.application1
New-ServiceFabricService `
-Stateless `
-PartitionSchemeSingleton `
-ApplicationName `fabric:/application1 `
-ServiceName fabric:/application1/service1 `
-ServiceTypeName Service1Type `
-InstanceCount 1 `
-ServiceDnsName service1.application1
[Preview] Making DNS queries on a stateful service partition
Beginning with Service Fabric version 6.3, the Service Fabric DNS service supports queries for service partitions.
For partitions that will be used in DNS queries, the following naming restrictions apply:
- Partition names should be DNS-compliant.
- Multi-label partition names (that include dot, '.', in the name) should not be used.
- Partition names should be lower-case.
DNS queries that target a partition are formatted as follows:
<First-Label-Of-Partitioned-Service-DNSName><PartitionPrefix><Target-Partition-Name>< PartitionSuffix>.<Remaining- Partitioned-Service-DNSName>
Where:
- First-Label-Of-Partitioned-Service-DNSName is the first part of your service DNS name.
- PartitionPrefix is a value that can be set in the DnsService section of the cluster manifest or through the cluster's Resource Manager template. The default value is "--". To learn more, see DNS Service settings.
- Target-Partition-Name is the name of the partition.
- PartitionSuffix is a value that can be set in the DnsService section of the cluster manifest or through the cluster's Resource Manager template. The default value is empty string. To learn more, see DNS Service settings.
- Remaining-Partitioned-Service-DNSName is the remaining part of your service DNS name.
The following examples show DNS queries for partitioned services running on a cluster that has default settings for PartitionPrefix
and PartitionSuffix
:
- To resolve partition “0” of a service with DNS name
backendrangedschemesvc.application
that uses a ranged partitioning scheme, usebackendrangedschemesvc-0.application
. - To resolve partition “first” of a service with DNS name
backendnamedschemesvc.application
that uses a named partitioning scheme, usebackendnamedschemesvc-first.application
.
The DNS service returns the IP address of the primary replica of the partition. If no partition is specified, the service returns the IP address of the primary replica of a randomly selected partition.
Using DNS in your services
If you deploy more than one service, you can find the endpoints of other services to communicate with by using a DNS name. The DNS service works for stateless services, and, in Service Fabric version 6.3 and later, for stateful services. For stateful services running on versions of Service Fabric prior to 6.3, you can use the built-in reverse proxy service for http calls to call a particular service partition.
Dynamic ports are not supported by the DNS service. You can use the reverse proxy service to resolve services that use dynamic ports.
The following code shows how to call a stateless service through DNS. It is simply a regular http call where you provide the DNS name, the port, and any optional path as part of the URL.
public class ValuesController : Controller
{
// GET api
[HttpGet]
public async Task<string> Get()
{
string result = "";
try
{
Uri uri = new Uri("http://service1.application1:8080/api/values");
HttpClient client = new HttpClient();
var response = await client.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return result;
}
}
The following code shows a call on a specific partition of a stateful service. In this case, the DNS name contains the partition name (partition1). The call assumes a cluster with default values for PartitionPrefix
and PartitionSuffix
.
public class ValuesController : Controller
{
// GET api
[HttpGet]
public async Task<string> Get()
{
string result = "";
try
{
Uri uri = new Uri("http://service2-partition1.application1:8080/api/values");
HttpClient client = new HttpClient();
var response = await client.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return result;
}
}
Recursive Queries
For DNS names that the DNS service can't resolve on its own (for example, a public DNS name), it will forward the query to pre-existing recursive DNS servers on the nodes.
Prior to Service Fabric 9.0, these servers were queried serially with a fixed timeout period of 5 seconds in between. If a server didn't respond within the timeout period, the next server (if available) would be queried. In the case that these DNS servers were encountering any issues, completion of DNS queries would take longer than 5 seconds, which is not ideal.
Beginning in Service Fabric 9.0, support for parallel recursive queries was added. With parallel queries, all recursive DNS servers can be contacted at once, where the first response wins. This will result in quicker responses in the scenario previously mentioned.
Fine-grained options are also introduced in Service Fabric 9.0 to control the behavior of the recursive queries, including the timeout periods and query attempts. These options can be set in the cluster config, under DnsService:
- RecursiveQuerySerialMaxAttempts - The number of serial queries that will be attempted, at most. If this number is higher than the amount of forwarding DNS servers, querying will stop once all the servers have been attempted exactly once.
- RecursiveQuerySerialTimeout - The timeout value in seconds for each attempted serial query.
- RecursiveQueryParallelMaxAttempts - The number of times parallel queries will be attempted. Parallel queries are executed after the max attempts for serial queries have been exhausted.
- RecursiveQueryParallelTimeout - The timeout value in seconds for each attempted parallel query.
Known Issues
For Service Fabric versions 6.3 and higher, there is a problem with DNS lookups for service names containing a hyphen in the DNS name. For more information on this issue, please track the following GitHub Issue. A fix for this is coming in the next 6.3 update.
DNS service for Service Fabric services is not yet supported on Linux. DNS service is supported for containers on Linux. Manual resolution using Fabric Client/ServicePartitionResolver is the available alternative.
Next steps
Learn more about service communication within the cluster with connect and communicate with services
Feedback
Submit and view feedback for