Utilizzo dell'allocazione dinamica delle porte di Cloud NAT

1. Panoramica

L'allocazione dinamica delle porte (DPA) è una nuova funzionalità di Cloud NAT. Se la DPA è abilitata, Cloud NAT esegue dinamicamente lo scale up/down delle allocazioni delle porte per le istanze in base alle loro esigenze. La DPA è configurata con limiti minimi e massimi per le porte, in modo che non venga mai eseguito lo scale down delle porte al di sotto del minimo o lo scale up al di sopra del massimo. In questo modo, alcune istanze dietro i gateway NAT possono aumentare dinamicamente il numero di connessioni senza dover allocare più porte a tutte le istanze dietro Cloud NAT.

Senza l'allocazione dinamica delle porte, a tutte le istanze dietro Cloud NAT viene assegnato lo stesso numero di porte indipendentemente dall'utilizzo, come definito dal parametro minPortsPerVm .

Per saperne di più, consulta la sezione della documentazione relativa al DPA NAT .

Cosa imparerai a fare

  • Come configurare un gateway Cloud NAT in preparazione al DPA.
  • Come ispezionare le allocazioni delle porte senza DPA.
  • Come attivare e configurare DPA per un gateway NAT.
  • Come osservare gli effetti di DPA eseguendo connessioni di uscita parallele.
  • Come aggiungere regole NAT a un gateway NAT con DPA abilitato.
  • Come visualizzare il comportamento di DPA con le regole eseguendo connessioni di uscita a 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, ad esempio il lab Networking in Google Cloud.
  • Un progetto Google Cloud con "Accesso alpha" abilitato.
  • Comprensione delle nozioni di base di Cloud NAT.

2. Utilizzo di Google Cloud Console e Cloud Shell

Per interagire con GCP, utilizzeremo sia la console Google Cloud che Cloud Shell durante questo lab.

Google Cloud Console

Puoi accedere alla console Cloud all'indirizzo https://console.cloud.google.com.

75eef5f6fd6d7e41.png

Configurazione dell'ambiente 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 del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google e puoi aggiornarla 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). Cloud Console genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, devi fare riferimento all'ID progetto (che in genere è identificato come PROJECT_ID), quindi, se non ti piace, generane un altro casuale oppure puoi provare il tuo e vedere se è disponibile. Viene "congelato" dopo la creazione del progetto.
  • Esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Per arrestare le risorse in modo da non incorrere in costi di fatturazione al termine di questo tutorial, segui le istruzioni di "pulizia" riportate alla fine del codelab. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.

Avvia Cloud Shell

Sebbene Google Cloud possa essere gestito da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.

Nella console GCP, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:

bce75f34b2c53987.png

Bastano pochi istanti per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere un risultato simile a questo:

f6ef2b5f13479f3a.png

Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Tutto il lavoro di 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 in ciascuno. Prenoterai indirizzi IP esterni, quindi creerai e configurerai un gateway Cloud NAT (con un router Cloud), due istanze di produttore e due istanze di consumer. Dopo aver convalidato il comportamento predefinito di Cloud NAT, attiverai l'allocazione dinamica delle porte e ne convaliderai il comportamento. Infine, configurerai anche le regole NAT e osserverai l'interazione tra DPA e regole NAT.

Panoramica dell'architettura di rete:

a21caa6c333909d8.png

4. Prenota indirizzi IP esterni

Prenotiamo tutti gli indirizzi IP esterni da utilizzare in questo lab. In questo modo, potrai scrivere tutte le regole NAT e firewall pertinenti sia nel VPC consumer che in quello 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 per confermare che gli indirizzi siano stati compilati correttamente. Visualizziamo 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. Configurazione di VPC e istanze producer.

Ora creeremo le risorse per le risorse del produttore. Le istanze in esecuzione nel VPC del producer offriranno il servizio rivolto a internet utilizzando due IP pubblici "producer-address-1" e "producer-address-2" .

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

A questo punto, 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

Successivamente, creiamo regole firewall VPC per consentire agli indirizzi IP NAT di raggiungere le istanze del produttore 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 consiste nel creare le due istanze del produttore.

Le istanze del produttore 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 utilizzando il gestore di pacchetti APT di Debian.

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 il VPC consumer, Cloud NAT e le 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 a IAP gli intervalli IP di origine TCP. In questo modo potremo accedere con SSH alle istanze consumer direttamente utilizzando gcloud.

Creeremo quindi un semplice gateway Cloud NAT in modalità di allocazione manuale e l'indirizzo riservato "nat-address-1" associato. Nelle parti successive del codelab, aggiorneremo la configurazione del gateway per attivare l'allocazione dinamica delle porte e, in un secondo momento, 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

Successivamente, 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

Successivamente, creiamo regole firewall VPC per consentire agli indirizzi degli intervalli IAP di raggiungere le istanze consumer sulla porta 22.

Per la prima regola firewall, esegui questo comando 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 prima creare un'istanza di Cloud Router (utilizziamo un numero ASN privato, ma è irrilevante 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

Poi 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 minPortsPerVm impostato su 64

Crea le istanze di test dei consumatori. Inseriamo qui gli IP del produttore riservati 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 predefinito di Cloud NAT, che utilizza lo stesso IP riservato "nat-address-1" per comunicare con tutti gli indirizzi esterni. Inoltre, Cloud NAT non ha ancora abilitato il DPA.

Convalidiamo le porte che Cloud NAT ha allocato alle nostre istanze consumer eseguendo il seguente 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

Verifichiamo quante connessioni possiamo aprire in parallelo prima di attivare DPA.

Accedi tramite SSH alla prima istanza consumer. Da Cloud Shell:

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

Ora dovresti essere nella shell dell'istanza.

Esempio di output (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, recuperiamo prima gli IP del produttore e inseriamoli 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"`

Poi prova a eseguire il comando curl su entrambe le istanze del produttore per assicurarti 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 produttore eseguendo curl in un ciclo. Ricorda che Cloud NAT non consente il riutilizzo dei socket chiusi per 2 minuti. Pertanto, se riusciamo a eseguire il ciclo di tutti i tentativi di connessione entro 2 minuti, possiamo simulare 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

Ti aspetteresti di poter 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 verificare che non sia possibile superare le 64 connessioni parallele, attendi prima 2 minuti per consentire la cancellazione di tutti i socket precedenti. Poi modifica la stessa riga di comando nel seguente modo 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 dovresti aspettarti 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

Ciò indica che, mentre le prime 64 connessioni sono andate a buon fine, le 6 rimanenti non sono riuscite a causa della mancata disponibilità di porte.

Interveniamo allora, esci dalla shell SSH e attiviamo DPA nella sezione seguente.

8. Attiva DPA e convalida il suo comportamento

Esegui il seguente comando gcloud, che attiva l'allocazione dinamica delle porte, 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

che restituisce quanto segue

Updating nat [consumer-nat-gw] in router [consumer-cr]...done.

Ora eseguiamo di nuovo get-nat-mapping-info per verificare che entrambe le istanze abbiano ancora solo 64 porte allocate.

gcloud  compute routers get-nat-mapping-info consumer-cr --region=us-east4

Esempio di output (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 sono state apportate molte modifiche in termini di allocazioni delle porte, poiché l'istanza non utilizza ancora attivamente alcuna porta.

Accediamo di nuovo all'istanza tramite SSH:

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

Esporta nuovamente le variabili di ambiente dell'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"`

E riesegui il ciclo 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 il seguente output

Connection # 64 successful
Connection # 65 failed

Connection # 66 failed
Connection # 70 successful
Loop Done, Sleeping for 150s

Che cosa è successo? Cloud NAT aumenta l'allocazione delle porte in base all'aumento dell'utilizzo delle porte, ma la programmazione a livello di rete richiede un po' di tempo. Pertanto, si verificano 1-3 timeout della connessione prima di completare correttamente il resto dei tentativi di connessione.

Abbiamo specificato un timeout aggressivo per curl (5 secondi), ma le applicazioni con timeout più lunghi dovrebbero essere in grado di completare le connessioni correttamente mentre DPA aumenta le allocazioni delle porte.

Questo comportamento di aumento può essere visto più chiaramente quando eseguiamo il ciclo per 1024 tentativi di connessione come segue

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 in potenze di 2, raddoppiando essenzialmente le allocazioni a ogni passaggio, i timeout di connessione vengono evidenziati intorno alle potenze di 2 tra 64 e 1024.

Poiché abbiamo impostato maxPortsPerVM su 1024, non prevediamo di poter superare le 1024 connessioni. Possiamo testarlo eseguendo nuovamente il ciclo curl con un conteggio superiore a 1024 (dopo aver atteso 2 minuti per reimpostare le porte obsolete).

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

Come previsto, l'output mostra che le connessioni oltre 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

Impostando maxPortsPerVM su 1024, abbiamo indicato a Cloud NAT di non scalare mai le allocazioni di porte oltre 1024 per VM.

Se usciamo dalla sessione SSH e eseguiamo di nuovo get-nat-mapping-info abbastanza rapidamente, possiamo vedere le porte aggiuntive allocate

gcloud  compute routers get-nat-mapping-info consumer-cr --region=us-east4

e osserva l'output seguente

---
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 abbia 1024 porte allocate, mentre consumer-instance-2 ne abbia solo 64. Prima dell'ETD, questa operazione non era facilmente possibile ed evidenzia esattamente la potenza dell'ETD per Cloud NAT.

Se aspetti 2 minuti prima di eseguire nuovamente il comando get-nat-mapping-info, noterai che consumer-instance-1 è tornato al suo valore minimo di soli 64 porti allocati. Illustrando non solo la capacità di DPA di aumentare le allocazioni delle porte, ma anche di rilasciarle quando non sono in uso per un potenziale utilizzo da parte di altre istanze dietro lo stesso gateway NAT.

9. Testare le regole Cloud NAT con DPA

Di recente abbiamo anche 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 le regole DPA e NAT. Definiamo innanzitutto una regola NAT per utilizzare nat-address-2 quando si accede 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 aspettarti il seguente output

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 il seguente output

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

Nota che ora sono state allocate porte aggiuntive (anche a 64, il minimo specificato) specificamente per nat-address-2 nella gerarchia ruleMappings.

Quindi, cosa succede se un'istanza apre molte connessioni alla destinazione specificata dalla regola NAT? Scopriamolo.

Accediamo di nuovo all'istanza tramite SSH:

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

Esporta nuovamente le variabili di ambiente dell'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"`

Ora eseguiamo di nuovo il ciclo curl 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

Dovresti vedere 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

Fondamentalmente, rispecchia il test precedente. Usciamo dalla sessione SSH dell'istanza e diamo un'altra occhiata ai mapping NAT.

gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4

che dovrebbe restituire il seguente output

---
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 osservare sopra, l'IP NAT predefinito di consumer-instance-1 ( l'IP per nat-address-1) ha ancora solo 64 porte allocate, ma l'IP della regola NAT (l'IP per nat-address-2) ha 1024 porte allocate. Nel frattempo, 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 ciclo 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].

Dopodiché, elimina il router Cloud. Da Cloud Shell:

gcloud compute routers delete consumer-cr \
 --region us-east4 --quiet

Dovresti aspettarti il seguente output :

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 aspettarti il seguente output :

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 aspettarti il seguente output :

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 aspettarti il seguente output :

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 aspettarti il seguente output :

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 sul DPA di Cloud NAT.

Argomenti trattati

  • Come configurare un gateway Cloud NAT in preparazione al DPA.
  • Come ispezionare le allocazioni delle porte senza DPA.
  • Come attivare e configurare DPA per un gateway NAT.
  • Come osservare gli effetti di DPA eseguendo connessioni di uscita parallele.
  • Come aggiungere regole NAT a un gateway NAT con DPA abilitato.
  • Come visualizzare il comportamento di DPA con le regole eseguendo connessioni di uscita a più destinazioni.

Passaggi successivi

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