Proxy inverso no Azure Service Fabric

O proxy inverso incorporado no Azure Service Fabric ajuda os microsserviços em execução num cluster do Service Fabric a detetar e comunicar com outros serviços que têm pontos finais http.

Modelo de comunicação de microsserviços

Os microsserviços no Service Fabric são executados num subconjunto de nós no cluster e podem migrar entre os nós por vários motivos. Como resultado, os pontos finais dos microsserviços podem mudar dinamicamente. Para detetar e comunicar com outros serviços no cluster, o microsserviço tem de seguir os seguintes passos:

  1. Resolva a localização do serviço através do serviço de nomenclatura.
  2. Ligue-se ao serviço.
  3. Encapsular os passos anteriores num ciclo que implementa a resolução de serviços e políticas de repetição para aplicar em falhas de ligação

Para obter mais informações, veja Ligar e comunicar com serviços.

Comunicar com o proxy inverso

O proxy inverso é um serviço que é executado em todos os nós e processa a resolução de pontos finais, a repetição automática e outras falhas de ligação em nome dos serviços de cliente. O proxy inverso pode ser configurado para aplicar várias políticas, uma vez que processa pedidos de serviços de cliente. A utilização de um proxy inverso permite ao serviço de cliente utilizar quaisquer bibliotecas de comunicação HTTP do lado do cliente e não requer resolução especial e lógica de repetição no serviço.

O proxy inverso expõe um ou mais pontos finais no nó local para os serviços cliente utilizarem para enviar pedidos para outros serviços.

Comunicação interna

Nota

Plataformas Suportadas

Atualmente, o proxy inverso no Service Fabric suporta as seguintes plataformas

  • Cluster do Windows: Windows 8 e posterior ou Windows Server 2012 e posterior
  • Cluster do Linux: o Proxy Inverso não está atualmente disponível para clusters do Linux

Alcançar microsserviços fora do cluster

O modelo de comunicação externa predefinido para microsserviços é um modelo de opt-in em que cada serviço não pode ser acedido diretamente a partir de clientes externos. Balanceador de Carga do Azure, que é um limite de rede entre microsserviços e clientes externos, efetua a tradução de endereços de rede e reencaminha pedidos externos para pontos finais internos IP:porta. Para tornar o ponto final de um microsserviço diretamente acessível para clientes externos, primeiro tem de configurar Balanceador de Carga para reencaminhar o tráfego para cada porta que o serviço utiliza no cluster. No entanto, a maioria dos microsserviços, especialmente os microsserviços com estado, não residem em todos os nós do cluster. Os microsserviços podem mover-se entre nós na ativação pós-falha. Nestes casos, Balanceador de Carga não consegue determinar eficazmente a localização do nó de destino das réplicas para as quais deve reencaminhar o tráfego.

Alcançar microsserviços através do proxy inverso de fora do cluster

Em vez de configurar a porta de um serviço individual no Balanceador de Carga, pode configurar apenas a porta do proxy inverso no Balanceador de Carga. Esta configuração permite que os clientes fora do cluster alcancem os serviços dentro do cluster através do proxy inverso sem configuração adicional.

Comunicação externa

Aviso

Quando configurar a porta do proxy inverso no Balanceador de Carga, todos os microsserviços no cluster que expõem um ponto final HTTP são endereçáveis fora do cluster. Isto significa que os microsserviços destinados a serem internos podem ser detetáveis por um determinado utilizador malicioso. Isto apresenta potencialmente vulnerabilidades graves que podem ser exploradas; por exemplo:

  • Um utilizador malicioso pode iniciar um ataque denial of service ao chamar repetidamente um serviço interno que não tem uma superfície de ataque suficientemente endurecida.
  • Um utilizador mal intencionado pode fornecer pacotes com formato incorreto a um serviço interno, o que resulta num comportamento inesperado.
  • Um serviço destinado a ser interno pode devolver informações privadas ou confidenciais que não se destinam a ser expostas a serviços fora do cluster, expondo assim estas informações confidenciais a um utilizador malicioso.

Certifique-se de que compreende e mitiga totalmente as potenciais ramificações de segurança do cluster e das aplicações em execução no mesmo, antes de tornar pública a porta de proxy inverso.

Formato URI para endereçar serviços com o proxy inverso

O proxy inverso utiliza um formato de identificador de recurso uniforme (URI) específico para identificar a partição do serviço para a qual o pedido recebido deve ser reencaminhado:

http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&ListenerName=<listenerName>&TargetReplicaSelector=<targetReplicaSelector>&Timeout=<timeout_in_seconds>
  • http(s): O proxy inverso pode ser configurado para aceitar tráfego HTTP ou HTTPS. Para reencaminhamento HTTPS, consulte Ligar a um serviço seguro com o proxy inverso assim que tiver a configuração do proxy inverso para escutar https.

  • Nome de domínio completamente qualificado (FQDN) do cluster | IP interno: Para clientes externos, pode configurar o proxy inverso para que seja acessível através do domínio do cluster, como mycluster.eastus.cloudapp.azure.com. Por predefinição, o proxy inverso é executado em cada nó. Para tráfego interno, o proxy inverso pode ser alcançado no localhost ou em qualquer IP de nó interno, como 10.0.0.1.

  • Porta: Esta é a porta, como 19081, que foi especificada para o proxy inverso.

  • ServiceInstanceName: Este é o nome completamente qualificado da instância de serviço implementada que está a tentar alcançar sem os "recursos de infraestrutura:/" esquema. Por exemplo, para aceder ao serviço fabric:/myapp/myservice/ , utilizaria myapp/myservice.

    O nome da instância de serviço é sensível a maiúsculas e minúsculas. Utilizar uma caixa diferente para o nome da instância de serviço no URL faz com que os pedidos falhem com 404 (Não Encontrado).

  • Caminho do sufixo: Este é o caminho de URL real, como myapi/values/add/3, para o serviço ao qual pretende ligar.

  • PartitionKey: Para um serviço particionado, esta é a chave de partição calculada da partição que pretende alcançar. Tenha em atenção que este não é o GUID do ID de partição. Este parâmetro não é necessário para serviços que utilizam o esquema de partição singleton.

  • PartitionKind: Este é o esquema de partição de serviço. Pode ser "Int64Range" ou "Named". Este parâmetro não é necessário para serviços que utilizam o esquema de partição singleton.

  • ListenerName Os pontos finais do serviço são do formulário {"Pontos Finais":{"Serviço de Escuta1":"Ponto Final1","Serviço de Escuta2":"Ponto Final2" ...}}. Quando o serviço expõe vários pontos finais, este identifica o ponto final para o qual o pedido de cliente deve ser reencaminhado. Isto pode ser omitido se o serviço tiver apenas um serviço de escuta.

  • TargetReplicaSelector Isto especifica a forma como a réplica de destino ou a instância devem ser selecionadas.

    • Quando o serviço de destino tem estado, o TargetReplicaSelector pode ser um dos seguintes: "PrimaryReplica", "RandomSecondaryReplica" ou "RandomReplica". Quando este parâmetro não é especificado, a predefinição é "PrimaryReplica".
    • Quando o serviço de destino está sem estado, o proxy inverso escolhe uma instância aleatória da partição do serviço para onde reencaminhar o pedido.
  • Tempo limite: Isto especifica o tempo limite para o pedido HTTP criado pelo proxy inverso para o serviço em nome do pedido de cliente. O valor predefinido é 120 segundos. Este é um parâmetro opcional.

Utilização de exemplo

Por exemplo, vamos utilizar o serviço fabric:/MyApp/MyService que abre um serviço de escuta HTTP no seguinte URL:

http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/

Seguem-se os recursos para o serviço:

  • /index.html
  • /api/users/<userId>

Se o serviço utilizar o esquema de criação de partições singleton, os parâmetros da cadeia de consulta PartitionKey e PartitionKind não são necessários e o serviço pode ser alcançado utilizando o gateway como:

  • Externamente: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService
  • Internamente: http://localhost:19081/MyApp/MyService

Se o serviço utilizar o esquema de criação de partições Uniform Int64, os parâmetros da cadeia de consulta PartitionKey e PartitionKind têm de ser utilizados para alcançar uma partição do serviço:

  • Externamente: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range
  • Internamente: http://localhost:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range

Para aceder aos recursos que o serviço expõe, basta colocar o caminho do recurso a seguir ao nome do serviço no URL:

  • Externamente: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService/index.html?PartitionKey=3&PartitionKind=Int64Range
  • Internamente: http://localhost:19081/MyApp/MyService/api/users/6?PartitionKey=3&PartitionKind=Int64Range

Em seguida, o gateway reencaminhará estes pedidos para o URL do serviço:

  • http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/index.html
  • http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/api/users/6

Processamento especial para serviços de partilha de portas

O proxy inverso do Service Fabric tenta resolver novamente um endereço de serviço e repetir o pedido quando não é possível aceder a um serviço. Geralmente, quando não é possível aceder a um serviço, a instância ou réplica do serviço foi movida para um nó diferente como parte do ciclo de vida normal. Quando isto acontece, o proxy inverso pode receber um erro de ligação de rede que indica que um ponto final já não está aberto no endereço originalmente resolvido.

No entanto, as réplicas ou instâncias de serviço podem partilhar um processo de anfitrião e também podem partilhar uma porta quando alojadas por um servidor Web baseado em http.sys, incluindo:

Nesta situação, é provável que o servidor Web esteja disponível no processo de anfitrião e a responder a pedidos, mas a réplica ou instância de serviço resolvida já não está disponível no anfitrião. Neste caso, o gateway receberá uma resposta HTTP 404 do servidor Web. Assim, uma resposta HTTP 404 pode ter dois significados distintos:

  • Caso n.º 1: o endereço do serviço está correto, mas o recurso que o utilizador pediu não existe.
  • Caso n.º 2: o endereço do serviço está incorreto e o recurso que o utilizador pediu pode existir num nó diferente.

O primeiro caso é um HTTP 404 normal, que é considerado um erro de utilizador. No entanto, no segundo caso, o utilizador solicitou um recurso que existe. O proxy inverso não conseguiu localizá-lo porque o próprio serviço foi movido. O proxy inverso tem de resolver o endereço novamente e repetir o pedido.

Assim, o proxy inverso precisa de uma forma de distinguir entre estes dois casos. Para fazer essa distinção, é necessária uma sugestão do servidor.

  • Por predefinição, o proxy inverso assume o caso n.º 2 e tenta resolver e emitir o pedido novamente.

  • Para indicar o caso n.º 1 ao proxy inverso, o serviço deve devolver o seguinte cabeçalho de resposta HTTP:

    X-ServiceFabric : ResourceNotFound

Este cabeçalho de resposta HTTP indica uma situação normal de HTTP 404 em que o recurso pedido não existe e o proxy inverso não tentará resolver o endereço do serviço novamente.

Processamento especial para serviços em execução em contentores

Para serviços em execução dentro de contentores, pode utilizar a variável Fabric_NodeIPOrFQDN de ambiente para construir o URL de proxy inverso , tal como no seguinte código:

    var fqdn = Environment.GetEnvironmentVariable("Fabric_NodeIPOrFQDN");
    var serviceUrl = $"http://{fqdn}:19081/DockerSFApp/UserApiContainer";

Para o cluster local, Fabric_NodeIPOrFQDN está definido como "localhost" por predefinição. Inicie o cluster local com o parâmetro para garantir que os -UseMachineName contentores conseguem alcançar o proxy inverso em execução no nó. Para obter mais informações, veja Configurar o ambiente do programador para depurar contentores.

Os serviços do Service Fabric que são executados nos contentores do Docker Compose requerem uma secção de Portas docker-compose.yml especial http: ou https: configuração. Para obter mais informações, veja Suporte de implementação do Docker Compose no Azure Service Fabric.

Passos seguintes