1. Visão geral
A alocação dinâmica de portas (DPA, na sigla em inglês) é um novo recurso do Cloud NAT. Com a DPA ativada, o Cloud NAT aumenta/diminui dinamicamente as alocações de portas para instâncias, dependendo da necessidade delas. A DPA é configurada com limites mínimo e máximo de portas para que nunca reduza as portas abaixo do mínimo nem aumente além do máximo. Isso permite que algumas instâncias por trás dos gateways NAT escalonem verticalmente a contagem de conexões dinamicamente sem precisar alocar mais portas para todas as instâncias por trás do Cloud NAT.
Sem a DPA, todas as instâncias por trás do Cloud NAT recebem o mesmo número de portas, independente do uso, conforme definido pelo parâmetro minPortsPerVm .
Para mais informações, consulte a seção de documentação sobre a DPA de NAT .
O que você vai aprender
- Como configurar um gateway do Cloud NAT em preparação para a DPA.
- Como inspecionar alocações de portas sem DPA.
- Como ativar e configurar a DPA para um gateway NAT.
- Como observar os efeitos da DPA executando conexões de saída paralelas.
- Como adicionar regras NAT a um gateway NAT com o DPA ativado.
- Como ver o comportamento da DPA com regras executando conexões de saída para vários destinos.
O que é necessário
- Conhecimento básico do Google Compute Engine
- Conhecimento básico de TCP/IP e rede
- Conhecimento básico de linha de comando do Unix/Linux
- É recomendável ter concluído um tour de redes no Google Cloud, como o laboratório Redes no Google Cloud.
- Um projeto na nuvem do Google Cloud com o "Acesso Alfa" ativado.
- Entendimento dos conceitos básicos do Cloud NAT.
2. Como usar o console do Google Cloud e o Cloud Shell
Para interagir com o GCP, vamos usar o console do Google Cloud e o Cloud Shell ao longo deste laboratório.
Console do Google Cloud
O console do Cloud pode ser acessado em https://console.cloud.google.com.

Configuração de ambiente autoguiada
- Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.



- O Nome do projeto é o nome de exibição para os participantes do projeto. Ele é uma string de caracteres que não é usada pelas APIs do Google e pode ser atualizada a qualquer momento.
- O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser alterado após a definição. O Console do Cloud gera automaticamente uma string única, geralmente não importa o que seja. Na maioria dos codelabs, você precisará fazer referência ao ID do projeto, que geralmente é identificado como
PROJECT_ID. Então, se você não gostar dele, gere outro ID aleatório ou crie um próprio e veja se ele está disponível. Em seguida, ele fica "congelado" depois que o projeto é criado. - Há um terceiro valor, um Número de projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
- Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para encerrar os recursos e não gerar cobranças além deste tutorial, siga as instruções de "limpeza" encontradas no final do codelab. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.
Inicie o Cloud Shell
Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
No Console do GCP, clique no ícone do Cloud Shell na barra de ferramentas localizada no canto superior direito:

O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Todo o trabalho neste laboratório pode ser feito apenas com um navegador.
3. configurar o laboratório
Neste laboratório, você vai usar um projeto e criar duas VPCs com uma sub-rede em cada uma. Você vai reservar endereços IP externos e criar e configurar um gateway do Cloud NAT (com um Cloud Router), duas instâncias de produtor e duas de consumidor. Depois de validar o comportamento padrão do Cloud NAT, você vai ativar a alocação dinâmica de portas e validar o comportamento dela. Por fim, você também vai configurar regras de NAT e observar a interação entre o DPA e essas regras.
Visão geral da arquitetura de rede:

4. Reservar endereços IP externos
Vamos reservar todos os endereços IP externos que serão usados neste laboratório. Isso vai ajudar você a escrever todas as regras de NAT e firewall relevantes nas VPCs do consumidor e do produtor.
No Cloud Shell:
gcloud compute addresses create nat-address-1 nat-address-2 \ producer-address-1 producer-address-2 --region us-east4
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].
Preencha os endereços IP reservados como variáveis de ambiente.
export natip1=`gcloud compute addresses list --filter name:nat-address-1 --format="get(address)"` export natip2=`gcloud compute addresses list --filter name:nat-address-2 --format="get(address)"` export producerip1=`gcloud compute addresses list --filter name:producer-address-1 --format="get(address)"` export producerip2=`gcloud compute addresses list --filter name:producer-address-2 --format="get(address)"`
Nenhuma saída é esperada, mas para confirmar que os endereços foram preenchidos corretamente. Vamos gerar os valores de todas as variáveis de ambiente.
env | egrep '^(nat|producer)ip[1-3]'
Saída:
producerip1=<Actual Producer IP 1> producerip2=<Actual Producer IP 2> natip1=<NAT IP 1> natip2=<NAT IP 2>
5. Configuração da VPC e das instâncias do produtor.
Agora vamos criar os recursos do produtor. As instâncias em execução na VPC do produtor vão oferecer o serviço voltado à Internet usando dois IPs públicos "producer-address-1" e "producer-address-2" .
Primeiro, vamos criar a VPC. No Cloud Shell:
gcloud compute networks create producer-vpc --subnet-mode custom
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/networks/producer-vpc]. NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 producer-vpc CUSTOM REGIONAL Instances on this network will not be reachable until firewall rules are created. As an example, you can allow all internal traffic between instances as well as SSH, RDP, and ICMP by running: $ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE> $ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp:22,tcp:3389,icmp
Em seguida, vamos criar a sub-rede em us-east4. No Cloud Shell:
gcloud compute networks subnets create prod-net-e4 \ --network producer-vpc --range 10.0.0.0/24 --region us-east4
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4]. NAME REGION NETWORK RANGE STACK_TYPE IPV6_ACCESS_TYPE IPV6_CIDR_RANGE EXTERNAL_IPV6_CIDR_RANGE prod-net-e4 us-east4 producer-vpc 10.0.0.0/24 IPV4_ONLY
Em seguida, vamos criar regras de firewall da VPC para permitir que os endereços IP do NAT alcancem as instâncias do produtor na porta 8080.
Para a primeira regra, no Cloud Shell:
gcloud compute firewall-rules create producer-allow-80 \ --network producer-vpc --allow tcp:80 \ --source-ranges $natip1,$natip2
Saída:
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80]. Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED producer-allow-80 producer-vpc INGRESS 1000 tcp:80 False
A próxima etapa é criar as duas instâncias de produtor.
As instâncias do produtor vão executar uma implantação simples de proxy nginx.
Para provisionar rapidamente as instâncias com todo o software necessário, vamos criar as instâncias com um script de inicialização que instala o nginx usando o gerenciador de pacotes APT do Debian.
Para escrever regras de NAT, vamos provisionar cada instância com um endereço IP reservado diferente.
Crie a primeira instância. No Cloud Shell:
gcloud compute instances create producer-instance-1 \ --zone=us-east4-a --machine-type=e2-medium \ --network-interface=address=producer-address-1,network-tier=PREMIUM,subnet=prod-net-e4 \ --metadata startup-script="#! /bin/bash sudo apt update sudo apt install -y nginx mkdir /var/www/html/nginx/ cat <<EOF > /var/www/html/nginx/index.html <html><body><h1>This is producer instance 1</h1> </body></html> EOF"
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-1]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS producer-instance-1 us-east4-a e2-medium 10.0.0.2 <Producer IP1> RUNNING
Em seguida, crie a segunda instância. No Cloud Shell:
gcloud compute instances create producer-instance-2 \ --zone=us-east4-a --machine-type=e2-medium \ --network-interface=address=producer-address-2,network-tier=PREMIUM,subnet=prod-net-e4 \ --metadata startup-script="#! /bin/bash sudo apt update sudo apt install -y nginx mkdir /var/www/html/nginx/ cat <<EOF > /var/www/html/nginx/index.html <html><body><h1>This is producer instance 2</h1> </body></html> EOF"
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-2]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS producer-instance-2 us-east4-a e2-medium 10.0.0.3 <Producer IP2> RUNNING
6. Configurar a VPC do consumidor, o Cloud NAT e as instâncias
Agora que você criou o serviço produtor, é hora de criar a VPC consumidora e o gateway do Cloud NAT.
Depois de criar a VPC e a sub-rede, vamos adicionar uma regra de firewall de entrada simples para permitir o IAP para intervalos de IP de origem TCP. Isso vai permitir que façamos SSH nas instâncias do consumidor diretamente usando o gcloud.
Em seguida, vamos criar um gateway simples do Cloud NAT no modo de alocação manual e o endereço reservado "nat-address-1" associado a ele. Nas próximas partes do codelab, vamos atualizar a configuração do gateway para ativar a alocação dinâmica de portas e, depois, adicionar regras personalizadas.
Primeiro, vamos criar a VPC. No Cloud Shell:
gcloud compute networks create consumer-vpc --subnet-mode custom
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc]. NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 consumer-vpc CUSTOM REGIONAL Instances on this network will not be reachable until firewall rules are created. As an example, you can allow all internal traffic between instances as well as SSH, RDP, and ICMP by running: $ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE> $ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp:22,tcp:3389,icmp
Em seguida, vamos criar uma sub-rede em us-east4. No Cloud Shell:
gcloud compute networks subnets create cons-net-e4 \ --network consumer-vpc --range 10.0.0.0/24 --region us-east4
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4]. NAME REGION NETWORK RANGE STACK_TYPE IPV6_ACCESS_TYPE IPV6_CIDR_RANGE EXTERNAL_IPV6_CIDR_RANGE cons-net-e4 us-east4 consumer-vpc 10.0.0.0/24 IPV4_ONLY
Em seguida, vamos criar regras de firewall da VPC para permitir que os endereços de intervalos do IAP alcancem as instâncias do consumidor na porta 22.
Para a primeira regra de firewall, execute o seguinte no Cloud Shell:
gcloud compute firewall-rules create consumer-allow-iap \ --network consumer-vpc --allow tcp:22 \ --source-ranges 35.235.240.0/20
Saída:
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/consumer-allow-iap]. Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED consumer-allow-iap consumer-vpc INGRESS 1000 tcp:22 False
Antes de criar um gateway NAT, precisamos criar uma instância do Cloud Router. Usamos um número de ASN particular, mas isso é irrelevante para as atividades deste laboratório. No Cloud Shell:
gcloud compute routers create consumer-cr \ --region=us-east4 --network=consumer-vpc \ --asn=65501
Saída:
Creating router [consumer-cr]...done. NAME REGION NETWORK consumer-cr us-east4 consumer-vpc
Em seguida, crie a instância do gateway NAT. No Cloud Shell:
gcloud compute routers nats create consumer-nat-gw \
--router=consumer-cr \
--router-region=us-east4 \
--nat-all-subnet-ip-ranges \
--nat-external-ip-pool=nat-address-1
Saída:
Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.
Por padrão, o gateway do Cloud NAT é criado com minPortsPerVm definido como 64.
Crie as instâncias de teste do consumidor. Preenchemos os IPs de produtor reservados aqui para poder consultar eles na instância mais tarde. No Cloud Shell:
gcloud compute instances create consumer-instance-1 --zone=us-east4-a \ --machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \ --metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2 gcloud compute instances create consumer-instance-2 --zone=us-east4-a \ --machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \ --metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2
Saída:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-1]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS consumer-instance-1 us-east4-a e2-medium 10.0.0.2 RUNNING Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-2]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS consumer-instance-2 us-east4-a e2-medium 10.0.0.3 RUNNING
7. Verificar o comportamento padrão do Cloud NAT
Neste ponto, as instâncias consumidoras usam o comportamento padrão do Cloud NAT, que usa o mesmo IP reservado "nat-address-1" para se comunicar com todos os endereços externos. O Cloud NAT ainda não tem a DPA ativada.
Vamos validar quais portas o Cloud NAT alocou para nossas instâncias de consumidor executando o seguinte comando:
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Exemplo de saída
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Consumer IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Consumer IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3
Como você pode ver na saída acima, o Cloud NAT alocou 64 portas por instância do mesmo IP externo nat-address-1.
Vamos validar quantas conexões podemos abrir em paralelo antes de ativar a DPA.
Conecte-se por SSH à primeira instância de consumidor. No Cloud Shell:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Agora você está no shell da instância.
Exemplo de saída (saída completa truncada para brevidade)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
Na instância do consumidor, vamos buscar os IPs do produtor e preenchê-los como variáveis de ambiente.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
Em seguida, tente fazer curl nas duas instâncias de produtor para garantir que elas possam ser acessadas.
<username>@consumer-instance-1:~$ curl http://$producerip1/nginx/ <html><body><h1>This is producer instance 1</h1> </body></html> <username>@consumer-instance-1:~$ curl http://$producerip2/nginx/ <html><body><h1>This is producer instance 2</h1> </body></html>
Agora vamos tentar criar muitas conexões paralelas com uma das instâncias do produtor executando curl em um loop. O Cloud NAT não permite a reutilização de sockets fechados por dois minutos. Portanto, desde que possamos fazer um loop em todas as tentativas de conexão em dois minutos, é possível simular conexões paralelas dessa forma.
Execute o seguinte comando na sessão SSH da instância:
while true; do for i in {1..64}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Você espera conseguir abrir 64 conexões paralelas, e o script vai imprimir o seguinte:
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Para ver que não é possível ir além de 64 conexões paralelas, aguarde dois minutos para que todos os sockets antigos sejam limpos. Em seguida, ajuste o mesmo comando de uma linha para o seguinte e execute-o novamente:
while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Agora você vai ver a seguinte saída
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 67 failed Connection # 68 failed Connection # 69 failed Connection # 70 failed Loop Done, Sleeping for 150s
Isso indica que, embora as primeiras 64 conexões tenham sido bem-sucedidas, as 6 restantes falharam devido à indisponibilidade de portas.
Vamos fazer algo a respeito. Saia do shell SSH e ative a DPA na seção a seguir.
8. Ativar a DPA e validar o comportamento dela
Execute o seguinte comando gcloud, que ativa a DPA e define a alocação mínima de portas por VM como 64 e a alocação máxima como 1024.
gcloud alpha compute routers nats update consumer-nat-gw --router=consumer-cr \ --region=us-east4 --min-ports-per-vm=64 --max-ports-per-vm=1024 \ --enable-dynamic-port-allocation
que produz o seguinte:
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Agora, execute get-nat-mapping-info novamente para confirmar que as duas instâncias ainda têm apenas 64 portas alocadas.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Exemplo de saída (truncada para facilitar a leitura)
--- instanceName: consumer-instance-1 ... - <NAT Consumer IP1>:1024-1055 numTotalNatPorts: 32 ... - natIpPortRanges: - <NAT Consumer IP1>:32768-32799 numTotalNatPorts: 32 ... --- instanceName: consumer-instance-2 ... - <NAT Address IP1>:1056-1087 numTotalNatPorts: 32 ... - <NAT Address IP1>:32800-32831 numTotalNatPorts: 32 ...
Não houve muitas mudanças em termos de alocações de portas, já que a instância ainda não está usando nenhuma porta ativamente.
Vamos acessar a instância novamente por SSH:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Reexporte as variáveis de ambiente de IP do produtor.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
E execute novamente o loop anterior para simular conexões paralelas:
while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Agora você vai ver a seguinte saída
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 70 successful Loop Done, Sleeping for 150s
O que aconteceu aqui? O Cloud NAT aumenta a alocação de portas com o aumento do uso, mas isso leva algum tempo para ser programado em toda a camada de rede. Por isso, vemos de uma a três vezes o tempo limite de conexão antes de concluir as demais tentativas.
Especificamos um tempo limite agressivo para curl (5 segundos), mas aplicativos com tempos limite mais longos podem concluir as conexões com sucesso enquanto a DPA aumenta as alocações de porta.
Esse comportamento de aumento pode ser visto mais claramente quando executamos o loop para 1024 tentativas de conexão, assim:
while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Agora esperamos ver a seguinte saída
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 129 successful Connection # 130 failed Connection # 131 failed Connection # 258 successful Connection # 259 failed Connection # 260 failed Connection # 515 successful Connection # 516 failed Connection # 1024 successful Loop Done, Sleeping for 150s
Como o Cloud NAT aloca portas em potências de 2, essencialmente dobrando as alocações em cada etapa, vemos os tempos limite de conexão destacados em torno das potências de 2 entre 64 e 1024.
Como definimos maxPortsPerVM como 1024, não esperamos conseguir mais de 1024 conexões. Para testar isso, execute o loop curl novamente com uma contagem maior que 1024 (depois de esperar dois minutos para redefinir as portas inativas).
while true; do for i in {1..1035}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Como esperado, a saída mostra que as conexões acima de 1024 começam a falhar.
<truncated output> ... Connection # 1028 successful Connection # 1029 failed Connection # 1030 failed Connection # 1031 failed Connection # 1032 failed Connection # 1033 failed Connection # 1034 failed Connection # 1035 failed ... Loop Done, Sleeping for 150s
Ao definir maxPortsPerVM como 1024, instruímos o Cloud NAT a nunca dimensionar as alocações de porta além de 1024 por VM.
Se sairmos da sessão SSH e executarmos get-nat-mapping-info novamente com rapidez suficiente, poderemos ver as portas extras alocadas.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
e observe a seguinte saída:
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1024-1055 - <NAT Address IP1>1088-1119 -<NAT Address IP1>:1152-1215 - <NAT Address IP1>:1280-1407 - <NAT Address IP1>:1536-1791 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Address IP1>:32768-32799 - <NAT Address IP1>:32832-32863 - <NAT Address IP1>:32896-32959 - <NAT Address IP1>:33024-33151 - <NAT Address IP1>:33536-33791 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3
Observe como consumer-instance-1 tem 1.024 portas alocadas, mas consumer-instance-2 tem apenas 64. Isso não era possível antes do DPA e destaca exatamente o poder do DPA para o Cloud NAT.
Se você esperar dois minutos antes de executar o comando get-nat-mapping-info novamente, vai notar que consumer-instance-1 voltou ao valor mínimo de apenas 64 portas alocadas. Ilustrando não apenas a capacidade do DPA de aumentar as alocações de porta, mas também de liberá-las quando não estão em uso para possível uso por outras instâncias por trás do mesmo gateway NAT.
9. Testar regras do Cloud NAT com DPA
Também lançamos recentemente a funcionalidade de regras de NAT para o Cloud NAT, permitindo que os clientes escrevam regras que usam IPs NAT específicos para determinados destinos externos. Para mais informações, consulte a página de documentação sobre regras de NAT.
Neste exercício, vamos observar a interação entre a DPA e as regras de NAT. Primeiro, vamos definir uma regra NAT para usar nat-address-2 ao acessar producer-address-2.
Execute o seguinte comando gcloud, que cria a regra de NAT usando
gcloud alpha compute routers nats rules create 100 \ --match='destination.ip == "'$producerip2'"' \ --source-nat-active-ips=nat-address-2 --nat=consumer-nat-gw \ --router=consumer-cr --router-region=us-east4
Você vai receber a seguinte saída
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Agora, vamos executar get-nat-mapping-info novamente para ver o efeito da nova regra de NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
que vai gerar o seguinte resultado:
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
Agora temos portas extras alocadas (também em 64, o mínimo especificado) especificamente para nat-address-2 na hierarquia ruleMappings.
O que acontece se uma instância abrir muitas conexões com o destino especificado pela regra de NAT? Vamos descobrir.
Vamos acessar a instância novamente por SSH:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Reexporte as variáveis de ambiente de IP do produtor.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
Agora, vamos executar o loop curl novamente em producerip2 desta vez.
while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip2/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
A saída será semelhante a esta:
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 129 successful Connection # 130 failed Connection # 131 failed Connection # 258 successful Connection # 259 failed Connection # 260 failed Connection # 515 successful Connection # 516 failed Connection # 1024 successful Loop Done, Sleeping for 150s
Basicamente, espelhando o teste anterior. Vamos sair da sessão SSH da instância e analisar os mapeamentos de NAT novamente.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
que vai gerar o seguinte resultado:
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
- <NAT Address IP2>:1088-1119
- <NAT Address IP2>:1152-1215
- <NAT Address IP2>:1280-1407
- <NAT Address IP2>:1536-1791
numTotalDrainNatPorts: 0
numTotalNatPorts: 512
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
- <NAT Address IP2>:32832-32863
- <NAT Address IP2>:32896-32959
- <NAT Address IP2>:33024-33151
- <NAT Address IP2>:33280-33535
numTotalDrainNatPorts: 0
numTotalNatPorts: 512
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
---
instanceName: consumer-instance-2
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1056-1087
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1056-1087
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.3
- natIpPortRanges:
- <NAT Address IP1>:32800-32831
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32800-32831
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.3
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
Como você pode observar acima, o IP NAT padrão de consumer-instance-1 ( o IP de nat-address-1) ainda tem apenas 64 portas alocadas, mas o IP da regra NAT (IP de nat-address-2) tem 1.024 portas alocadas. Enquanto isso, o consumer-instance-2 manteve as alocações padrão de 64 portas para todos os IPs NAT.
Como exercício, teste o caso inverso. Deixe o Cloud NAT desalocar todas as portas extras e execute o loop curl em producerip1. Observe os efeitos na saída de get-nat-mapping-info.
10. Etapas de limpeza
Para evitar cobranças recorrentes, exclua todos os recursos associados a este codelab.
Primeiro, exclua todas as instâncias.
No Cloud Shell:
gcloud compute instances delete consumer-instance-1 consumer-instance-2 \ producer-instance-1 producer-instance-2 \ --zone us-east4-a --quiet
Resposta esperada :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-2]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-2].
Em seguida, exclua o Cloud Router. No Cloud Shell:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Você vai receber esta resposta :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Libere todos os endereços IP externos. No Cloud Shell:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Você vai receber esta resposta :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-3]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].
Exclua regras de firewall da VPC. No Cloud Shell:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Você vai receber esta resposta :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/consumer-allow-iap]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80].
Exclua sub-redes. No Cloud Shell:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Você vai receber esta resposta :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4].
Por fim, vamos excluir as VPCs. No Cloud Shell:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Você vai receber esta resposta :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/producer-vpc].
11. Parabéns!
Você concluiu o laboratório sobre a DPA do Cloud NAT.
O que você abordou
- Como configurar um gateway do Cloud NAT em preparação para a DPA.
- Como inspecionar alocações de portas sem DPA.
- Como ativar e configurar a DPA para um gateway NAT.
- Como observar os efeitos da DPA executando conexões de saída paralelas.
- Como adicionar regras NAT a um gateway NAT com o DPA ativado.
- Como ver o comportamento da DPA com regras executando conexões de saída para vários destinos.
Próximas etapas
- Consulte a página de documentação sobre alocação dinâmica de porta.
- Teste o ajuste dos tempos limite de NAT e dos valores de alocação de porta com seu aplicativo.
- Saiba mais sobre rede no Google Cloud Platform.
©Google, Inc. ou afiliadas. Todos os direitos reservados. Distribuição proibida.