1. Panoramica
L'allocazione dinamica delle porte (DPA) è una nuova funzionalità di Cloud NAT. Con DPA abilitata, Cloud NAT fa lo scale up/down in modo dinamico dell'allocazione delle porte per le istanze a seconda delle esigenze. La DPA è configurata con limiti di porte minimo e massimo in modo da non fare mai lo scale down delle porte al di sotto del numero minimo o lo scale up oltre il limite massimo. Ciò consente ad alcune istanze dietro i gateway NAT di fare lo scale up dinamico del numero di connessioni senza dover allocare più porte a tutte le istanze dietro Cloud NAT.
Senza DPA, a tutte le istanze dietro Cloud NAT viene allocato lo stesso numero di porte indipendentemente dall'utilizzo, come definito dal parametro minPortsPerVm
.
Per ulteriori informazioni, consulta la sezione della documentazione relativa all'ATD NAT .
Cosa imparerai a fare
- Come configurare un gateway Cloud NAT in preparazione per DPA.
- Come controllare le allocazioni delle porte senza DPA.
- Come abilitare e configurare DPA per un gateway NAT.
- Come osservare gli effetti della DPA eseguendo connessioni in uscita parallele.
- Come aggiungere regole NAT a un gateway NAT con DPA abilitato.
- Come visualizzare il comportamento dell'ATD con regole eseguendo connessioni in uscita verso più destinazioni.
Che cosa ti serve
- Conoscenza di base di Google Compute Engine
- Conoscenza di base del networking e di TCP/IP
- Conoscenza di base della riga di comando Unix/Linux
- È utile aver completato un tour del networking in Google Cloud, come il lab Networking in Google Cloud.
- Un progetto Google Cloud con "Alpha Access" in un bucket con il controllo delle versioni attivo.
- Comprensione delle nozioni di base di Cloud NAT.
2. Utilizzo della console Google Cloud e di Cloud Shell
Per interagire con Google Cloud, utilizzeremo sia la console Google Cloud sia Cloud Shell durante questo lab.
Google Cloud Console
La console Cloud è disponibile all'indirizzo https://console.cloud.google.com.
Configurazione dell'ambiente da seguire in modo autonomo
- Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.
- Il Nome progetto è il nome visualizzato dei partecipanti del progetto. Si tratta di una stringa di caratteri non utilizzata dalle API di Google e può essere aggiornata in qualsiasi momento.
- L'ID progetto deve essere univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca. di solito non ti importa cosa sia. Nella maggior parte dei codelab, devi fare riferimento all'ID progetto (che solitamente è identificato come
PROJECT_ID
), quindi, se non ti piace, generane un altro a caso oppure puoi fare un tentativo personalizzato e controllare se è disponibile. Poi c'è "congelato" dopo la creazione del progetto. - C'è un terzo valore, il numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
- Successivamente, dovrai abilitare la fatturazione nella console Cloud per utilizzare le risorse/le API Cloud. Eseguire questo codelab non dovrebbe costare molto. Per arrestare le risorse in modo da non incorrere in fatturazione oltre questo tutorial, segui eventuali "pulizie" istruzioni riportate alla fine del codelab. I nuovi utenti di Google Cloud sono idonei al programma prova senza costi di 300$.
Avvia Cloud Shell
Anche se Google Cloud può essere utilizzato da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.
Dalla console di Google Cloud, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:
Dovrebbe richiedere solo qualche istante per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere una schermata simile al seguente:
Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Tutto il lavoro in questo lab può essere svolto semplicemente con un browser.
3. Configurazione del lab
Per questo lab, utilizzerai un progetto e creerai due VPC con una subnet ciascuno. Prenoterai indirizzi IP esterni e quindi creerai e configurerai un gateway Cloud NAT (con un router Cloud), due istanze producer e due istanze consumer. Dopo aver convalidato il comportamento predefinito di Cloud NAT, dovrai abilitare l'allocazione dinamica delle porte e convalidarne il comportamento. Infine, configurerai anche le regole NAT e osserverai l'interazione tra DPA e regole NAT.
Panoramica dell'architettura di networking:
4. Prenota indirizzi IP esterni
Prenotiamo tutti gli indirizzi IP esterni da utilizzare in questo lab. Questo ti aiuterà a scrivere tutte le regole NAT e firewall pertinenti nel VPC consumer e producer.
Da Cloud Shell:
gcloud compute addresses create nat-address-1 nat-address-2 \ producer-address-1 producer-address-2 --region us-east4
Output:
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].
Compila gli indirizzi IP riservati come variabili di 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)"`
Non è previsto alcun output, ma è necessario verificare che gli indirizzi siano stati compilati correttamente. Inviamo un output con i valori di tutte le variabili di ambiente.
env | egrep '^(nat|producer)ip[1-3]'
Output:
producerip1=<Actual Producer IP 1> producerip2=<Actual Producer IP 2> natip1=<NAT IP 1> natip2=<NAT IP 2>
5. VPC del producer e configurazione delle istanze.
Ora creeremo le risorse per le risorse producer. Le istanze in esecuzione nel VPC del producer offriranno il servizio per internet utilizzando due IP pubblici "producer-address-1" e "producer-address-2" di Google.
Innanzitutto, creiamo il VPC. Da Cloud Shell:
gcloud compute networks create producer-vpc --subnet-mode custom
Output:
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
Ora creiamo la subnet in us-east4. Da Cloud Shell:
gcloud compute networks subnets create prod-net-e4 \ --network producer-vpc --range 10.0.0.0/24 --region us-east4
Output:
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
Ora creiamo le regole firewall VPC per consentire agli indirizzi IP NAT di raggiungere le istanze del producer sulla porta 8080.
Per la prima regola, da Cloud Shell:
gcloud compute firewall-rules create producer-allow-80 \ --network producer-vpc --allow tcp:80 \ --source-ranges $natip1,$natip2
Output:
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
Il passaggio successivo prevede la creazione delle due istanze producer.
Le istanze del producer eseguiranno un semplice deployment del proxy nginx.
Per eseguire rapidamente il provisioning delle istanze con tutto il software necessario, creeremo le istanze con uno script di avvio che installa nginx mediante il gestore di pacchetti Debian APT.
Per poter scrivere regole NAT, eseguiremo il provisioning di ogni istanza con un indirizzo IP riservato diverso.
Crea la prima istanza. Da 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"
Output:
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
Poi crea la seconda istanza. Da 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"
Output:
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. Configura VPC consumer, Cloud NAT e istanze
Ora che hai creato il servizio producer, è il momento di creare il VPC consumer e il relativo gateway Cloud NAT.
Dopo aver creato il VPC e la subnet, aggiungeremo una semplice regola firewall in entrata per consentire gli intervalli IP di origine IAP per TCP. Questo ci consentirà di stabilire una connessione SSH direttamente alle istanze consumer utilizzando gcloud.
Creeremo quindi un semplice gateway Cloud NAT in modalità di allocazione manuale e l'indirizzo riservato "nat-address-1" associate. Nelle parti successive del codelab aggiorneremo la configurazione del gateway per abilitare l'allocazione dinamica delle porte e, successivamente, aggiungeremo regole personalizzate.
Innanzitutto, creiamo il VPC. Da Cloud Shell:
gcloud compute networks create consumer-vpc --subnet-mode custom
Output:
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
Ora creiamo una subnet in us-east4. Da Cloud Shell:
gcloud compute networks subnets create cons-net-e4 \ --network consumer-vpc --range 10.0.0.0/24 --region us-east4
Output:
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
Ora creiamo una regola firewall VPC per consentire agli indirizzi degli intervalli IAP di raggiungere le istanze consumer sulla porta 22.
Per la prima regola firewall, esegui il comando seguente da Cloud Shell:
gcloud compute firewall-rules create consumer-allow-iap \ --network consumer-vpc --allow tcp:22 \ --source-ranges 35.235.240.0/20
Output:
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
Prima di creare un gateway NAT, dobbiamo creare un'istanza di router Cloud (utilizziamo un numero ASN privato, ma non è pertinente per le attività di questo lab). Da Cloud Shell:
gcloud compute routers create consumer-cr \ --region=us-east4 --network=consumer-vpc \ --asn=65501
Output:
Creating router [consumer-cr]...done. NAME REGION NETWORK consumer-cr us-east4 consumer-vpc
Quindi crea l'istanza del gateway NAT. Da 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
Output:
Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.
Tieni presente che, per impostazione predefinita, il gateway Cloud NAT viene creato con il campo minPortsPerVm
impostato su 64
Creare le istanze di test consumer. Popoliamo qui gli IP dei producer prenotati per poterli consultare in un secondo momento all'interno dell'istanza. Da 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
Output:
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. Verifica il comportamento predefinito di Cloud NAT
A questo punto, le istanze consumer utilizzano il comportamento Cloud NAT predefinito che usa lo stesso IP riservato "nat-address-1" per comunicare con tutti gli indirizzi esterni. Inoltre, DPA non è ancora abilitato per Cloud NAT.
Convalidiamo le porte su cui Cloud NAT ha allocato le nostre istanze consumer eseguendo questo comando
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Esempio di output
--- 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
Come puoi vedere dall'output precedente, Cloud NAT ha allocato 64 porte per istanza dallo stesso IP esterno nat-address-1
Convalidiamo il numero di connessioni che possiamo aprire in parallelo prima di abilitare DPA.
Accedi tramite SSH alla prima istanza consumer. Da Cloud Shell:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
A questo punto dovresti essere nella shell dell'istanza.
Output di esempio (output completo troncato per brevità)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
Dall'interno dell'istanza consumer, innanzitutto recuperiamo gli IP dei producer e li completiamo come variabili di 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"`
Quindi prova a utilizzare il comando curl per entrambe le istanze del producer per assicurarci di poterle raggiungere correttamente.
<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>
Ora proviamo a creare molte connessioni parallele a una delle istanze del producer eseguendo curl attraverso un loop. Ricorda che Cloud NAT non consente il riutilizzo di socket chiusi per 2 minuti. Quindi, purché siamo in grado di eseguire il loop di tutti i tentativi di connessione entro 2 minuti, siamo in grado di simulare le connessioni parallele in questo modo.
Esegui questo comando nella sessione SSH dell'istanza
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
Dovresti riuscire ad aprire 64 connessioni parallele e lo script dovrebbe stampare quanto segue
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Per vedere che non è possibile superare le 64 connessioni parallele, attendi 2 minuti per consentire lo svuotamento di tutti i vecchi socket. Poi modifica la stessa riga di testo come segue ed eseguila di nuovo
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
Ora ti aspetteresti il seguente output
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
Questo indica che mentre le prime 64 connessioni hanno avuto esito positivo, le 6 rimanenti non sono riuscite a causa dell'indisponibilità delle porte.
Facciamo qualcosa al riguardo, quindi esci dalla shell SSH e attiviamo DPA nella sezione seguente.
8. Abilita l'ETD e convalida il suo comportamento
Esegui il seguente comando gcloud, che abilita DPA, imposta l'allocazione minima delle porte per VM su 64 e l'allocazione massima delle porte su 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
Il risultato è il seguente
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Ora eseguiamo di nuovo get-nat-mapping-info
per confermare che a entrambe le istanze siano ancora allocate solo 64 porte
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Output di esempio (troncato per brevità)
--- 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 ...
Non è cambiato molto in termini di allocazione delle porte, poiché l'istanza non sta ancora utilizzando attivamente nessuna porta.
Accedi di nuovo tramite SSH all'istanza:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Esporta di nuovo le variabili di ambiente IP del producer.
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"`
ed esegui di nuovo il loop precedente per simulare le connessioni parallele:
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
Ora dovremmo vedere l'output seguente
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 70 successful Loop Done, Sleeping for 150s
Che cosa è successo qui? Cloud NAT incrementa l'allocazione delle porte all'aumento dell'utilizzo delle porte, ma la programmazione richiede un po' di tempo in tutto il livello di networking. Di conseguenza, vediamo 1-3 timeout di connessione prima di completare gli altri tentativi di connessione.
Abbiamo specificato un timeout aggressivo per curl (5 secondi), ma le applicazioni con timeout più lunghi dovrebbero riuscire a completare le connessioni correttamente, mentre DPA sta aumentando l'allocazione delle porte.
Questo comportamento di incremento può essere visto più chiaramente quando eseguiamo il loop per 1024 tentativi di connessione in questo modo.
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
Ora ci aspettiamo di vedere l'output seguente
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
Poiché Cloud NAT alloca le porte con potenze di 2, raddoppiando essenzialmente le allocazioni in ogni passaggio, vediamo i timeout della connessione evidenziati attorno alle potenze di 2 tra 64 e 1024.
Poiché abbiamo impostato maxPortsPerVM
su 1024, non prevediamo di supportare più di 1024 connessioni. Possiamo verificarlo eseguendo di nuovo il loop curl con un conteggio superiore a 1024 (dopo aver atteso 2 minuti per reimpostare le porte inattive).
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
E come previsto, l'output mostra che le connessioni dopo la data 1024 iniziano a non riuscire
<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
Se imposti maxPortsPerVM
su 1024, abbiamo indicato a Cloud NAT di non scalare mai le allocazioni delle porte oltre 1024 per VM.
Se usciamo dalla sessione SSH ed eseguiamo di nuovo get-nat-mapping-info
abbastanza velocemente, possiamo vedere le porte aggiuntive allocate
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
E osserva il seguente output
--- 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
Nota come consumer-instance-1
ha 1024 porte allocate, ma consumer-instance-2
ha solo 64 porte allocate. Ciò non era facilmente possibile prima dell'ATD ed è questo che mette esattamente in evidenza la potenza dell'ATD per Cloud NAT.
Se attendi 2 minuti prima di eseguire di nuovo il comando get-nat-mapping-info
, noterai che consumer-instance-1
è tornato al suo valore minimo di appena 64 porte allocate. Illustrazione non solo della capacità della DPA di aumentare l'allocazione delle porte, ma anche di rilasciarle quando non in uso per un potenziale utilizzo da parte di altre istanze dietro lo stesso gateway NAT.
9. Testa le regole Cloud NAT con DPA
Di recente abbiamo inoltre rilasciato la funzionalità delle regole NAT per Cloud NAT, che consente ai clienti di scrivere regole che utilizzano IP NAT specifici per determinate destinazioni esterne. Per saperne di più, consulta la pagina della documentazione sulle regole NAT.
In questo esercizio, osserviamo l'interazione tra DPA e regole NAT. Innanzitutto, definiamo una regola NAT per utilizzare nat-address-2
durante l'accesso a producer-address-2
.
Esegui il seguente comando gcloud, che crea la regola NAT utilizzando
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
Dovresti vedere l'output seguente
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Ora eseguiamo di nuovo get-nat-mapping-info
per vedere l'effetto della nuova regola NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
che dovrebbe restituire quanto segue
--- 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
Tieni presente che ora sono assegnate porte aggiuntive (anch'esse a 64, il numero minimo specificato) specifiche per nat-address-2
nella gerarchia ruleMappings
.
Cosa succede se un'istanza apre molte connessioni alla destinazione specificata dalla regola NAT? Scopriamolo.
Accedi di nuovo tramite SSH all'istanza:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Esporta di nuovo le variabili di ambiente IP del producer.
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"`
Eseguiamo di nuovo il loop curl questa volta su producerip2
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
Dovrebbe essere visualizzato un output simile al seguente
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
Sostanzialmente, il mirroring del test precedente. Esci dalla sessione SSH dell'istanza e osserviamo di nuovo le mappature nat.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
che dovrebbe restituire quanto segue
--- 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
Come puoi notare in precedenza, all'IP NAT predefinito di consumer-instance-1
( l'IP di nat-address-1
) sono ancora state allocate solo 64 porte, mentre all'IP della regola NAT (IP per nat-address-2
) sono state allocate 1024 porte. Per tutto il tempo consumer-instance-2
ha mantenuto le allocazioni predefinite di 64 porte per tutti gli IP NAT.
Come esercizio, puoi testare il caso inverso. Consenti a Cloud NAT di deallocare tutte le porte aggiuntive, quindi esegui il loop curl su producerip1
e osserva gli effetti sull'output di get-nat-mapping-info
10. Procedura di pulizia
Per evitare addebiti ricorrenti, devi eliminare tutte le risorse associate a questo codelab.
Elimina prima tutte le istanze.
Da Cloud Shell:
gcloud compute instances delete consumer-instance-1 consumer-instance-2 \ producer-instance-1 producer-instance-2 \ --zone us-east4-a --quiet
Output previsto :
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].
Quindi, elimina il router Cloud. Da Cloud Shell:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Dovresti vedere l'output seguente :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Rilascia tutti gli indirizzi IP esterni. Da Cloud Shell:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Dovresti vedere l'output seguente :
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].
Elimina le regole firewall VPC. Da Cloud Shell:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Dovresti vedere l'output seguente :
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].
Elimina le subnet. Da Cloud Shell:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Dovresti vedere l'output seguente :
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].
Infine, eliminiamo i VPC. Da Cloud Shell:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Dovresti vedere l'output seguente :
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. Complimenti
Hai completato il lab DPA di Cloud NAT.
Argomenti trattati
- Come configurare un gateway Cloud NAT in preparazione per DPA.
- Come controllare le allocazioni delle porte senza DPA.
- Come abilitare e configurare DPA per un gateway NAT.
- Come osservare gli effetti della DPA eseguendo connessioni in uscita parallele.
- Come aggiungere regole NAT a un gateway NAT con DPA abilitato.
- Come visualizzare il comportamento dell'ATD con regole eseguendo connessioni in uscita verso più destinazioni.
Passaggi successivi
- Consulta la pagina della documentazione sull'allocazione dinamica delle porte
- Prova a modificare i timeout NAT e i valori di allocazione delle porte con la tua applicazione.
- Scopri di più sul networking su Google Cloud Platform
©Google, Inc. e/o le sue società consociate. Tutti i diritti riservati. Distribuzione vietata.