Serviço DNS no Azure Service Fabric

O serviço DNS é um serviço de sistema opcional que pode ativar no cluster para detetar outros serviços com o protocolo DNS.

Muitos serviços, especialmente os serviços em contentores, são endereçáveis através de um URL pré-existente. É desejável poder resolver estes serviços com o protocolo DNS padrão, em vez do protocolo Service Fabric Naming Service. O serviço DNS permite mapear nomes DNS para um nome de serviço e, assim, resolver endereços IP de ponto final. Esta funcionalidade mantém a portabilidade dos serviços em contentores em diferentes plataformas e pode facilitar os cenários de "lift-and-shift", permitindo-lhe utilizar URLs de serviço existentes em vez de reescrever código para utilizar o Serviço de Nomenclatura.

O serviço DNS mapeia nomes DNS para nomes de serviço, que por sua vez são resolvidos pelo Serviço de Nomenclatura para devolver o ponto final de serviço. O nome DNS do serviço é fornecido no momento da criação. O diagrama seguinte mostra como o serviço DNS funciona para serviços sem estado. Por questões de brevidade, os diagramas mostram apenas um ponto final para os serviços, embora cada serviço possa ter vários pontos finais.

Diagrama a mostrar como os nomes DNS são mapeados para nomes de serviço pelo serviço DNS para serviços sem estado.

A partir da versão 6.3 do Service Fabric, o protocolo DNS do Service Fabric foi alargado para incluir um esquema de endereçamento a serviços com estado particionado. Estas extensões permitem resolver endereços IP de partição específicos com uma combinação de nome DNS de serviço com estado e o nome da partição. Os três esquemas de criação de partições são suportados:

  • Criação de partições com nome
  • Criação de partições entre intervalos
  • Criação de partições singleton

O diagrama seguinte mostra como o serviço DNS funciona para serviços com estado particionado.

Diagrama a mostrar como os nomes DNS são mapeados para nomes de serviço pelo serviço DNS para serviços com estado particionado.

Para obter mais informações sobre consultas particionadas, veja a secção abaixo.

Suporte do SO

O serviço DNS é suportado em clusters windows e Linux, embora o suporte para Linux esteja atualmente limitado a serviços em contentores e não possa ser ativado através de portal do Azure. No entanto, o Windows suporta todos os tipos de serviço e modelos de implementação.

Ativar o serviço DNS

Nota

Ativar o serviço DNS substituirá algumas definições de DNS nos nós. Se tiver problemas ao ligar à Internet, verifique as definições de DNS.

Novos clusters

Clusters com modelos do ARM

Para implementar um novo cluster com modelos arm, pode utilizar os modelos de exemplo ou escrever os seus próprios modelos . Se ainda não tiver sido feito, o serviço DNS pode ser ativado nos modelos através das versões mínimas suportadas da API e ao adicionar as definições adequadas. Os detalhes sobre como fazê-lo podem ser vistos abaixo nos pontos 1 e 2 da lista numerada.

Clusters com portal do Azure

Se estiver a criar um cluster padrão no portal, o serviço DNS está ativado por predefinição na opção Incluir serviço DNS na secção Adicionar funcionalidades .

Captura de ecrã a mostrar a ativação do serviço DNS para um cluster padrão através do portal.

Se estiver a criar um cluster gerido no portal, o serviço DNS está ativado por predefinição na opção de serviço DNS na secção Adicionar funcionalidades .

Captura de ecrã a mostrar a ativação do serviço DNS para um cluster gerido através do portal.

Clusters existentes

Se estiver a atualizar um cluster gerido existente para ativar o serviço DNS, pode fazê-lo a partir do portal ao visitar a página Serviços de suplementos a partir da página de recursos do cluster. Caso contrário, pode ativar o serviço DNS com métodos alternativos referenciados abaixo:

  • Utilize o modelo arm que foi utilizado para implementar o cluster, se aplicável.
  • Navegue para o cluster no Explorador de Recursos do Azure e atualize o recurso do cluster, conforme visto nos passos mais abaixo (a partir do passo 2 e posterior).
  • Navegue para o cluster no portal e clique em Exportar Modelo. Para saber mais, veja Exportar o modelo do grupo de recursos.

Depois de ter um modelo, pode ativar o serviço DNS com os seguintes passos:

  1. Para os clusters padrão, verifique se o apiVersion está definido como 2017-07-01-preview ou posterior para o recurso e, caso contrário, atualize-o Microsoft.ServiceFabric/clusters conforme mostrado no exemplo seguinte:

    {
        "apiVersion": "2017-07-01-preview",
        "type": "Microsoft.ServiceFabric/clusters",
        "name": "[parameters('clusterName')]",
        "location": "[parameters('clusterLocation')]",
        ...
    }
    

    Para clusters geridos, verifique se o apiVersion está definido como 2020-01-01-preview ou posterior para o recurso e, caso contrário, atualize-o Microsoft.ServiceFabric/managedClusters conforme mostrado no exemplo seguinte:

    {
        "apiVersion": "2020-01-01-preview",
        "type": "Microsoft.ServiceFabric/managedClusters",
        "name": "[parameters('clusterName')]",
        "location": "[parameters('clusterLocation')]",
        ...
    }
    
  2. Agora, ative o serviço DNS de uma das seguintes formas:

    • Para ativar o serviço DNS com predefinições, adicione-o addonFeatures à secção dentro da properties secção, conforme mostrado no exemplo seguinte:

      "properties": {
        ...
        "addonFeatures": [
          "DnsService"
          ],
        ...
      }
      
    • Para ativar o serviço com outras predefinições, adicione uma DnsService secção à fabricSettings secção dentro da properties secção. Neste caso, não precisa de adicionar o DnsService a addonFeatures. Para saber mais sobre as propriedades que podem ser definidas para o serviço DNS, veja Definições do serviço DNS.

      "properties": {
       ...
       "fabricSettings": [
         ...
         {
           "name": "DnsService",
           "parameters": [
             {
               "name": "IsEnabled",
               "value": "true"
             },
             {
               "name": "<key>",
               "value": "<value>"
             }
           ]
         },
         ...
       ]
      }
      
  3. Depois de atualizar o modelo de cluster com as suas alterações, aplique-as e deixe a atualização ser concluída. Quando a atualização for concluída, o serviço de sistema DNS começa a ser executado no cluster. O nome do serviço é fabric:/System/DnsService, e pode encontrá-lo na secção Serviço de sistema no Explorador do Service Fabric.

Nota

Ao atualizar o DNS de desativado para ativado, Service Fabric Explorer poderá não refletir o novo estado. Para resolver, reinicie os nós ao modificar a política de atualização no modelo.

Definir o nome DNS para o seu serviço

Pode definir nomes DNS para os seus serviços com modelos arm, com serviços predefinidos no ficheiro ApplicationManifest.xml ou com comandos do PowerShell.

O nome DNS do seu serviço é resolvível em todo o cluster, pelo que é importante garantir a exclusividade do nome DNS em todo o cluster.

Recomenda-se vivamente que utilize um esquema de nomenclatura de <ServiceName>.<AppName>; por exemplo, service1.application1. Se uma aplicação for implementada com a composição do Docker, os serviços são automaticamente atribuídos nomes DNS através deste esquema de nomenclatura.

Definir o nome DNS com o modelo do ARM

Se estiver a utilizar modelos do ARM para implementar os seus serviços, pode adicionar a serviceDnsName propriedade à secção adequada e atribuir-lhe um valor. Os exemplos podem ser vistos abaixo:

Clusters padrão

Para os clusters padrão, verifique se o apiVersion está definido como 2019-11-01-preview ou posterior para o recurso e, caso contrário, atualize-o Microsoft.ServiceFabric/clusters/applications/services conforme mostrado no exemplo seguinte:

{
  "apiVersion": "2019-11-01-preview",
  "type": "Microsoft.ServiceFabric/clusters/applications/services",
  "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
  "location": "[variables('clusterLocation')]",
  "dependsOn": [
    "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
  ],
  "properties": {
    "provisioningState": "Default",
    "serviceKind": "Stateless",
    "serviceTypeName": "[parameters('serviceTypeName')]",
    "instanceCount": "-1",
    "partitionDescription": {
      "partitionScheme": "Singleton"
    },
    "correlationScheme": [],
    "serviceLoadMetrics": [],
    "servicePlacementPolicies": [],
    "serviceDnsName": "[parameters('serviceDnsName')]"
  }
}

Clusters geridos

Para clusters geridos, verifique se o apiVersion está definido como 2022-10-01-preview ou posterior para o recurso e, caso contrário, atualize-o Microsoft.ServiceFabric/managedclusters/applications/services conforme mostrado no exemplo seguinte:

{
  "apiVersion": "2022-10-01-preview",
  "type": "Microsoft.ServiceFabric/managedclusters/applications/services",
  "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
  "location": "[variables('clusterLocation')]",
  "dependsOn": [
    "[concat('Microsoft.ServiceFabric/managedclusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
  ],
  "properties": {
    "serviceKind": "Stateless",
    "serviceTypeName": "[parameters('serviceTypeName')]",
    "instanceCount": "-1",
    "partitionDescription": {
      "partitionScheme": "Singleton"
    },
    "correlationScheme": [],
    "serviceLoadMetrics": [],
    "servicePlacementPolicies": [],
    "serviceDnsName": "[parameters('serviceDnsName')]"
  }
}

Definir o nome DNS para um serviço predefinido no ApplicationManifest.xml

Abra o seu projeto no Visual Studio ou no seu editor favorito e abra o ficheiro ApplicationManifest.xml. Aceda à secção serviços predefinidos e, para cada serviço, adicione o ServiceDnsName atributo. O exemplo seguinte mostra como definir o nome DNS do serviço como stateless1.application1

<Service Name="Stateless1" ServiceDnsName="stateless1.application1">
  <StatelessService ServiceTypeName="Stateless1Type" InstanceCount="[Stateless1_InstanceCount]">
    <SingletonPartition />
  </StatelessService>
</Service>

O exemplo seguinte define o nome DNS de um serviço com estado como stateful1.application1. O serviço utiliza um esquema de criação de partições com nome. Repare que os nomes das partições são minúsculas. Este é um requisito para partições que serão direcionadas em consultas DNS; Para obter mais informações, veja Fazer consultas DNS numa partição de serviço com estado.

<Service Name="Stateful1" ServiceDnsName="stateful1.application1" />
  <StatefulService ServiceTypeName="Stateful1Type" TargetReplicaSetSize="2" MinReplicaSetSize="2">
    <NamedPartition>
      <Partition Name="partition1" />
      <Partition Name="partition2" />
    </NamedPartition>
  </StatefulService>
</Service>

Definir o nome DNS para um serviço com o PowerShell

Pode definir o nome DNS para um serviço ao criá-lo com o comando do New-ServiceFabricService PowerShell. O exemplo seguinte cria um novo serviço sem estado com o nome stateless1.application1DNS:

New-ServiceFabricService `
    -Stateless `
    -PartitionSchemeSingleton `
    -ApplicationName fabric:/application1 `
    -ServiceName fabric:/application1/stateless1 `
    -ServiceTypeName Stateless1Type `
    -InstanceCount 1 `
    -ServiceDnsName stateless1.application1

Também pode atualizar um serviço existente com o comando do Update-ServiceFabricService PowerShell. O exemplo seguinte atualiza um serviço sem estado existente para adicionar o nome stateless1.application1DNS:

Update-ServiceFabricService `
    -Stateless `
    -ServiceName fabric:/application1/stateless1 `
    -ServiceDnsName stateless1.application1

Verifique se um nome DNS está definido no Service Fabric Explorer

Assim que o serviço for implementado com o nome DNS, Service Fabric Explorer mostrará o nome DNS do serviço, conforme mostrado na seguinte figura:

Captura de ecrã a mostrar o nome DNS no Service Fabric Explorer.

Nota

Esta vista pode ser diferente consoante a versão do Service Fabric Explorer utilizada, no entanto, o campo de nome DNS deve estar visível de alguma forma na página de serviço.

Fazer consultas DNS numa partição de serviço com estado

A partir da versão 6.3 do Service Fabric, o serviço DNS suporta consultas para partições de serviço. Para ativar o suporte para consultas de serviço particionadas, as definições do serviço DNS têm de ser atualizadas para definir a opção EnablePartitionedQuery como true.

Para partições que serão utilizadas em consultas DNS, aplicam-se as seguintes restrições de nomenclatura:

  • Os nomes de partições devem ser compatíveis com DNS.
  • Não devem ser utilizados nomes de partições com várias etiquetas, incluindo ponto ou "".
  • Os nomes das partições devem ser minúsculas.

As consultas DNS que visam uma partição são formatadas da seguinte forma:

    <First-Label-Of-Partitioned-Service-DNSName><PartitionPrefix><Target-Partition-Name><PartitionSuffix>.<Remaining-Partitioned-Service-DNSName>

Em que:

  • First-Label-Of-Partitioned-Service-DNSName é a primeira parte do nome DNS do serviço.
  • PartitionPrefix é um valor que pode ser definido na secção DnsService do manifesto do cluster ou através do modelo arm do cluster. O valor predefinido é "--". Para saber mais, veja Definições do serviço DNS.
  • Target-Partition-Name é o nome da partição.
  • PartitionSuffix é um valor que pode ser definido na secção DnsService do manifesto do cluster ou através do modelo arm do cluster. O valor predefinido é cadeia vazia. Para saber mais, veja Definições do serviço DNS.
  • Remaining-Partitioned-Service-DNSName é a parte restante do nome DNS do serviço.

Os exemplos seguintes mostram consultas DNS para serviços particionados em execução num cluster com predefinições para PartitionPrefix e PartitionSuffix:

  • Para resolver a partição "0" de um serviço com o nome backendrangedschemesvc.application DNS que utiliza um esquema de criação de partições num intervalo, utilize backendrangedschemesvc--0.application.
  • Para resolver a partição "first" de um serviço com o nome backendnamedschemesvc.application DNS que utiliza um esquema de criação de partições com nome, utilize backendnamedschemesvc--first.application.

O serviço DNS devolve o endereço IP do ponto final associado à réplica primária da partição. Se não for especificada nenhuma partição, o serviço DNS irá selecionar aleatoriamente uma partição.

Utilizar nomes DNS nos seus serviços

Se implementar serviços com nomes DNS, pode encontrar o endereço IP dos pontos finais expostos ao referenciar o nome DNS. O serviço DNS funciona para serviços sem estado e, na versão 6.3 e posterior do Service Fabric, para serviços com estado. Para serviços com estado em execução em versões do Service Fabric antes da versão 6.3, pode utilizar o serviço proxy inverso incorporado para chamadas HTTP para chamar uma partição de serviço específica.

As portas dinâmicas não são suportadas pelo serviço DNS. Pode utilizar o serviço proxy inverso para resolver serviços que utilizam portas dinâmicas.

O código seguinte mostra como chamar um serviço sem estado através de DNS. É simplesmente uma chamada HTTP normal onde fornece o nome DNS, a porta e qualquer caminho opcional como parte do URL.

public class ValuesController : Controller
{
    // GET api
    [HttpGet]
    public async Task<string> Get()
    {
        string result = "";
        try
        {
            Uri uri = new Uri("http://stateless1.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;
    }
}

O código seguinte mostra uma chamada numa partição específica de um serviço com estado. Neste caso, o nome DNS contém o nome da partição (partição1). A chamada pressupõe um cluster com valores predefinidos para PartitionPrefix e PartitionSuffix.

public class ValuesController : Controller
{
    // GET api
    [HttpGet]
    public async Task<string> Get()
    {
        string result = "";
        try
        {
            Uri uri = new Uri("http://stateful1--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;
    }
}

Consultas recursivas

Para nomes DNS que o serviço DNS não consegue resolver por si só (por exemplo, um nome DNS público), irá reencaminhar a consulta para servidores DNS recursivos pré-existentes nos nós.

Diagrama que mostra como as consultas DNS para nomes públicos são resolvidas.

Antes do Service Fabric 9.0, estes servidores eram consultados em série até ser recebida uma resposta, com um período de tempo limite fixo de 5 segundos no meio. Se um servidor não respondesse dentro do período de tempo limite, o servidor seguinte (se disponível) seria consultado. No caso de estes servidores DNS se depararem com problemas, a conclusão de consultas DNS demoraria mais de 5 segundos, o que não é o ideal.

A partir do Service Fabric 9.0, foi adicionado suporte para consultas recursivas paralelas. Com consultas paralelas, todos os servidores DNS recursivos podem ser contactados de uma só vez, onde a primeira resposta é ganha. Isto resulta em respostas mais rápidas no cenário mencionado anteriormente. Esta opção não está ativada por predefinição.

Também são introduzidas opções detalhadas no Service Fabric 9.0 para controlar o comportamento das consultas recursivas, incluindo os períodos de tempo limite e as tentativas de consulta. Estas opções podem ser definidas nas definições do serviço DNS:

  • RecursiveQuerySerialMaxAttempts – o número de consultas de série que serão tentadas, no máximo. Se este número for superior ao número de servidores DNS reencaminhados, a consulta irá parar quando todos os servidores tiverem sido tentados exatamente uma vez.
  • RecursiveQuerySerialTimeout – o valor de tempo limite em segundos para cada consulta em série tentada.
  • RecursiveQueryParallelMaxAttempts – o número de vezes que serão tentadas consultas paralelas. As consultas paralelas são executadas depois de esgotadas as tentativas máximas de consultas em série.
  • RecursiveQueryParallelTimeout - o valor de tempo limite em segundos para cada consulta paralela tentada.

Problemas e limitações conhecidos

  • As portas dinâmicas não são suportadas pelo serviço DNS. Para resolver os serviços expostos em portas dinâmicas, utilize o serviço proxy inverso.
  • O suporte para Linux está atualmente limitado a serviços em contentores. Atualmente, os serviços baseados em processos no Linux não podem utilizar o serviço DNS.
  • O serviço DNS para clusters linux não pode ser ativado através de portal do Azure.
  • Se um nome DNS for alterado para um serviço, as atualizações de nome poderão não ser imediatamente visíveis em alguns cenários. Para resolver o problema, as instâncias de serviço DNS devem ser reiniciadas em todo o cluster.

Passos seguintes

Saiba mais sobre a comunicação de serviços no cluster com a ligação e a comunicação com os serviços