Partilhar via


Proxy reverso no Azure Service Fabric

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

Modelo de comunicação de microsserviços

Os microsserviços no Service Fabric são executados em um subconjunto de nós no cluster e podem migrar entre os nós por vários motivos. Como resultado, os pontos de extremidade para microsserviços podem mudar dinamicamente. Para descobrir e se comunicar com outros serviços no cluster, o microsserviço deve passar pelas seguintes etapas:

  1. Resolva o local do serviço por meio do serviço de nomenclatura.
  2. Conecte-se ao serviço.
  3. Envolva as etapas anteriores em um loop que implementa a resolução de serviço e as políticas de repetição a serem aplicadas em falhas de conexão

Para obter mais informações, consulte Conectar-se e comunicar-se com serviços.

Comunicação usando o proxy reverso

O proxy reverso é um serviço que é executado em cada nó e lida com a resolução de pontos finais, novas tentativas automáticas e outras falhas de conexão em nome dos serviços do cliente. O proxy reverso pode ser configurado para aplicar várias políticas à medida que lida com solicitações de serviços de cliente. O uso de um proxy reverso permite que o serviço do cliente use qualquer biblioteca 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 reverso expõe um ou mais pontos de extremidade no nó local para os serviços do cliente usarem para enviar solicitações a outros serviços.

Comunicação interna

Nota

Plataformas suportadas

Atualmente, o proxy reverso no Service Fabric suporta as seguintes plataformas:

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

Alcançando microsserviços de fora do cluster

O modelo de comunicação externa padrão para microsserviços é um modelo de aceitação em que cada serviço não pode ser acessado diretamente de clientes externos. O Azure Load Balancer, que é um limite de rede entre microsserviços e clientes externos, executa a conversão de endereços de rede e encaminha solicitações externas para pontos de extremidade IP:port internos. Para tornar o ponto de extremidade de um microsserviço diretamente acessível a clientes externos, você deve primeiro configurar o Balanceador de Carga para encaminhar o tráfego para cada porta que o serviço usa no cluster. No entanto, a maioria dos microsserviços, especialmente os microsserviços com monitoração de estado, não vivem em todos os nós do cluster. Os microsserviços podem se mover entre nós no failover. Nesses casos, o Load Balancer não pode determinar efetivamente o local do nó de destino das réplicas para as quais ele deve encaminhar o tráfego.

Alcançando microsserviços por meio do proxy reverso de fora do cluster

Em vez de configurar a porta de um serviço individual no Load Balancer, você pode configurar apenas a porta do proxy reverso no Load Balancer. Essa configuração permite que clientes fora do cluster alcancem serviços dentro do cluster usando o proxy reverso sem configuração adicional.

Comunicação externa

Aviso

Quando você configura a porta do proxy reverso no Balanceador de Carga, todos os microsserviços no cluster que expõem um ponto de extremidade HTTP são endereçáveis de fora do cluster. Isso significa que microsserviços destinados a serem internos podem ser descobertos por um determinado usuário mal-intencionado. Esta situação apresenta potencialmente vulnerabilidades graves que podem ser exploradas; Por exemplo:

  • Um usuário mal-intencionado pode iniciar um ataque de negação de serviço chamando repetidamente um serviço interno que não tenha uma superfície de ataque suficientemente protegida.
  • Um usuário mal-intencionado pode entregar pacotes malformados para um serviço interno, resultando em comportamento não intencional.
  • Um serviço destinado a ser interno pode retornar informações privadas ou confidenciais que não se destinam a ser expostas a serviços fora do cluster, expondo assim essas informações confidenciais a um usuário mal-intencionado.

Certifique-se de entender completamente e mitigar as possíveis ramificações de segurança para seu cluster e os aplicativos em execução nele, antes de tornar pública a porta de proxy reverso.

Formato URI para endereçamento de serviços usando o proxy reverso

O proxy reverso usa um formato de URI (uniform resource identifier) específico para identificar a partição de serviço para a qual a solicitação de entrada deve ser encaminhada:

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 reverso pode ser configurado para aceitar tráfego HTTP ou HTTPS. Para encaminhamento HTTPS, consulte Conectar-se a um serviço seguro com o proxy reverso depois de configurar o proxy reverso para ouvir HTTPS.

  • FQDN (nome de domínio totalmente qualificado) do cluster | IP interno: para clientes externos, você pode configurar o proxy reverso para que ele seja acessível através do domínio do cluster, como mycluster.eastus.cloudapp.azure.com. Por padrão, o proxy reverso é executado em cada nó. Para tráfego interno, o proxy reverso 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 reverso.

  • ServiceInstanceName: Este é o nome totalmente qualificado da instância de serviço implantada que você está tentando alcançar sem o esquema "fabric:/". Por exemplo, para alcançar a malha:/myapp/myservice/ service, você usaria myapp/myservice.

    O nome da instância de serviço diferencia maiúsculas de minúsculas. Usar um invólucro diferente para o nome da instância de serviço na URL faz com que as solicitações 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 você deseja se conectar.

  • PartitionKey: Para um serviço particionado, esta é a chave de partição computada da partição que você deseja alcançar. Observe que este não é o GUID do ID da partição. Este parâmetro não é necessário para serviços que usam 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 usam o esquema de partição singleton.

  • ListenerName Os pontos de extremidade do serviço são do formato {"Endpoints":{"Listener1":"Endpoint1","Listener2":"Endpoint2" ...}}. Quando o serviço expõe vários pontos de extremidade, isso identifica o ponto de extremidade para o qual a solicitação do cliente deve ser encaminhada. Isso pode ser omitido se o serviço tiver apenas um ouvinte.

  • TargetReplicaSelector Especifica como a réplica ou instância de destino deve ser selecionada.

    • Quando o serviço de destino é stateful, o TargetReplicaSelector pode ser um dos seguintes: 'PrimaryReplica', 'RandomSecondaryReplica' ou 'RandomReplica'. Quando esse parâmetro não é especificado, o padrão é 'PrimaryReplica'.
    • Quando o serviço de destino é sem monitoração de estado, o proxy reverso seleciona uma instância aleatória da partição de serviço para encaminhar a solicitação.
  • Tempo limite: especifica o tempo limite para a solicitação HTTP criada pelo proxy reverso para o serviço em nome da solicitação do cliente. O valor predefinido é 120 segundos. Este é um parâmetro opcional.

Exemplo de utilização

Como exemplo, vamos pegar o serviço fabric:/MyApp/MyService que abre um ouvinte HTTP na seguinte URL:

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

A seguir estão os recursos para o serviço:

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

Se o serviço usa o esquema de particionamento singleton, os parâmetros de cadeia de caracteres de consulta PartitionKey e PartitionKind não são necessários, e o serviço pode ser acessado usando o gateway como:

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

Se o serviço usa o esquema de particionamento Uniform Int64, os parâmetros de cadeia de caracteres de consulta PartitionKey e PartitionKind devem ser usados 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 alcançar os recursos que o serviço expõe, basta colocar o caminho do recurso após o nome do serviço na 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

O gateway encaminhará essas solicitações para a 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

Tratamento especial para serviços de partilha de portos

O proxy reverso do Service Fabric tenta resolver um endereço de serviço novamente e tenta novamente a solicitação quando um serviço não pode ser alcançado. Geralmente, quando um serviço não pode ser alcançado, a instância de serviço ou réplica é movida para um nó diferente como parte de seu ciclo de vida normal. Quando isso acontece, o proxy reverso pode receber um erro de conexão de rede indicando que um ponto de extremidade não está mais aberto no endereço originalmente resolvido.

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

Nessa situação, é provável que o servidor Web esteja disponível no processo de host e respondendo a solicitações, mas a instância de serviço resolvida ou réplica não está mais disponível no host. Nesse caso, o gateway receberá uma resposta HTTP 404 do servidor Web. Assim, uma resposta HTTP 404 pode ter dois significados distintos:

  • Caso #1: O endereço do serviço está correto, mas o recurso que o usuário solicitou não existe.
  • Caso #2: O endereço do serviço está incorreto e o recurso que o usuário solicitou pode existir em um nó diferente.

O primeiro caso é um HTTP 404 normal, que é considerado um erro do usuário. No entanto, no segundo caso, o usuário solicitou um recurso que existe. O proxy reverso não conseguiu localizá-lo porque o próprio serviço foi movido. O proxy reverso precisa resolver o endereço novamente e tentar novamente a solicitação.

A procuração inversa necessita, portanto, de uma forma de distinguir entre estes dois casos. Para fazer essa distinção, é necessária uma dica do servidor.

  • Por padrão, o proxy reverso assume o caso #2 e tenta resolver e emitir a solicitação novamente.

  • Para indicar o caso #1 para o proxy reverso, o serviço deve retornar o seguinte cabeçalho de resposta HTTP:

    X-ServiceFabric : ResourceNotFound

Esse cabeçalho de resposta HTTP indica uma situação HTTP 404 normal na qual o recurso solicitado não existe e o proxy reverso não tentará resolver o endereço do serviço novamente.

Manuseamento especial para serviços executados em contentores

Para serviços executados dentro de contêineres, você pode usar a variável Fabric_NodeIPOrFQDN de ambiente para construir a URL de proxy reverso como no código a seguir:

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

Para o cluster local, Fabric_NodeIPOrFQDN é definido como "localhost" por padrão. Inicie o cluster local com o -UseMachineName parâmetro para garantir que os contêineres possam alcançar proxy reverso em execução no nó. Para obter mais informações, consulte Configurar seu ambiente de desenvolvedor para depurar contêineres.

Os serviços do Service Fabric executados em contêineres do Docker Compose exigem uma seção especial docker-compose.yml Ports http: ou https: configuration. Para obter mais informações, consulte Suporte à implantação do Docker Compose no Azure Service Fabric.

Próximos passos