Utilizzo dell'allocazione dinamica delle porte di Cloud NAT

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.

75eef5f6fd6d7e41.png

Configurazione dell'ambiente da seguire in modo autonomo

  1. 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.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • 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.
  1. 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:

bce75f34b2c53987.png

Dovrebbe richiedere solo qualche istante per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere una schermata simile al seguente:

f6ef2b5f13479f3a.png

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:

a21caa6c333909d8.png

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

©Google, Inc. e/o le sue società consociate. Tutti i diritti riservati. Distribuzione vietata.