1. Descripción general
La asignación dinámica de puertos (DPA) es una nueva función de Cloud NAT. Con la DPA habilitada, Cloud NAT aumenta o disminuye de forma dinámica las asignaciones de puertos para las instancias según sus necesidades. La DPA se configura con límites mínimos y máximos de puertos para que nunca reduzca la cantidad de puertos por debajo del mínimo ni la aumente por encima del máximo. Esto permite que algunas instancias detrás de las puertas de enlace de NAT aumenten de forma dinámica su recuento de conexiones sin tener que asignar más puertos a todas las instancias detrás de Cloud NAT.
Sin la DPA, a todas las instancias detrás de Cloud NAT se les asigna la misma cantidad de puertos, independientemente del uso, según lo define el parámetro minPortsPerVm .
Para obtener más información, consulta la sección de documentación sobre la DPA de NAT .
Qué aprenderás
- Cómo configurar una puerta de enlace de Cloud NAT en preparación para la DPA
- Cómo inspeccionar las asignaciones de puertos sin DPA
- Cómo habilitar y configurar el DPA para una puerta de enlace NAT
- Cómo observar los efectos de la DPA ejecutando conexiones de salida paralelas
- Cómo agregar reglas NAT a una puerta de enlace NAT con la DPA habilitada
- Cómo ver el comportamiento de la DPA con reglas ejecutando conexiones de salida a varios destinos
Requisitos
- Conocimiento básico de Google Compute Engine
- Conocimiento básico de herramientas de redes y TCP/IP
- Conocimiento básico de la línea de comandos de Unix/Linux
- Es útil haber completado un recorrido por las redes en Google Cloud, como el lab de Networking in Google Cloud.
- Un proyecto de Google Cloud con el "Acceso alfa" habilitado
- Comprensión de los conceptos básicos de Cloud NAT
2. Usa la consola de Google Cloud y Cloud Shell
Para interactuar con GCP, usaremos Google Cloud Console y Cloud Shell a lo largo de este lab.
Google Cloud Console
Puedes acceder a la consola de Cloud en https://console.cloud.google.com.

Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.



- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
- El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser
PROJECT_ID). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar. - Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no se te facture más allá de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.
Inicia Cloud Shell
Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
En GCP Console, haga clic en el ícono de Cloud Shell en la barra de herramientas superior derecha:

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Puedes realizar todo tu trabajo en este lab usando simplemente un navegador.
3. Configuración del lab
En este lab, usarás un proyecto y crearás dos VPC con una subred en cada una. Reservarás direcciones IP externas y, luego, crearás y configurarás una puerta de enlace de Cloud NAT (con un Cloud Router), dos instancias de productor y dos instancias de consumidor. Después de validar el comportamiento predeterminado de Cloud NAT, habilitarás la asignación de puertos dinámica y validarás su comportamiento. Por último, también configurarás reglas de NAT y observarás la interacción entre la DPA y las reglas de NAT.
Descripción general de la arquitectura de redes:

4. Reserva direcciones IP externas
Reservaremos todas las direcciones IP externas que se usarán en este lab. Esto te ayudará a escribir todas las reglas de NAT y de firewall pertinentes en la VPC del consumidor y del productor.
En Cloud Shell, ingresa lo siguiente:
gcloud compute addresses create nat-address-1 nat-address-2 \ producer-address-1 producer-address-2 --region us-east4
Resultado:
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].
Propaga las direcciones IP que se reservaron como variables de entorno.
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)"`
No se espera ningún resultado, pero se puede confirmar que las direcciones se completaron correctamente. Generemos los valores de todas las variables de entorno.
env | egrep '^(nat|producer)ip[1-3]'
Resultado:
producerip1=<Actual Producer IP 1> producerip2=<Actual Producer IP 2> natip1=<NAT IP 1> natip2=<NAT IP 2>
5. Configuración de la VPC y las instancias del productor
Ahora crearemos los recursos para los recursos del productor. Las instancias que se ejecutan en la VPC del productor ofrecerán el servicio orientado a Internet con dos IPs públicas: "producer-address-1" y "producer-address-2" .
Primero, creemos la VPC. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks create producer-vpc --subnet-mode custom
Resultado:
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 continuación, crearemos la subred en us-east4. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks subnets create prod-net-e4 \ --network producer-vpc --range 10.0.0.0/24 --region us-east4
Resultado:
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
A continuación, crearemos reglas de firewall de VPC para permitir que las direcciones IP de NAT lleguen a las instancias del productor en el puerto 8080.
Para la primera regla, desde Cloud Shell, haz lo siguiente:
gcloud compute firewall-rules create producer-allow-80 \ --network producer-vpc --allow tcp:80 \ --source-ranges $natip1,$natip2
Resultado:
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
El siguiente paso es crear las dos instancias de productor.
Las instancias de productor ejecutarán una implementación de proxy de nginx simple.
Para aprovisionar rápidamente las instancias con todo el software necesario, crearemos las instancias con una secuencia de comandos de inicio que instale nginx con el administrador de paquetes APT de Debian.
Para poder escribir reglas de NAT, aprovisionaremos cada instancia con una dirección IP reservada diferente.
Crea la primera instancia. En Cloud Shell, ingresa lo siguiente:
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"
Resultado:
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
Luego, crea la segunda instancia. En Cloud Shell, ingresa lo siguiente:
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"
Resultado:
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 la VPC del consumidor, Cloud NAT y las instancias
Ahora que creaste el servicio del productor, es momento de crear la VPC del consumidor y su puerta de enlace de Cloud NAT.
Después de crear la VPC y la subred, agregaremos una regla de firewall de entrada simple para permitir los rangos de IP de origen de IAP para TCP. Esto nos permitirá acceder a las instancias de consumidor directamente con SSH a través de gcloud.
Luego, crearemos una puerta de enlace de Cloud NAT simple en el modo de asignación manual y la dirección reservada "nat-address-1" asociada a ella. En las siguientes partes del codelab, actualizaremos la configuración de la puerta de enlace para habilitar la asignación dinámica de puertos y, luego, agregaremos reglas personalizadas.
Primero, creemos la VPC. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks create consumer-vpc --subnet-mode custom
Resultado:
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
A continuación, crearemos una subred en us-east4. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks subnets create cons-net-e4 \ --network consumer-vpc --range 10.0.0.0/24 --region us-east4
Resultado:
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
A continuación, crearemos reglas de firewall de VPC para permitir que los rangos de direcciones de IAP lleguen a las instancias del consumidor en el puerto 22.
Para la primera regla de firewall, ejecuta lo siguiente desde Cloud Shell:
gcloud compute firewall-rules create consumer-allow-iap \ --network consumer-vpc --allow tcp:22 \ --source-ranges 35.235.240.0/20
Resultado:
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/consumer-allow-iap]. Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED consumer-allow-iap consumer-vpc INGRESS 1000 tcp:22 False
Antes de crear una puerta de enlace de NAT, primero debemos crear una instancia de Cloud Router (usamos un número de ASN privado, pero es irrelevante para las actividades de este lab). En Cloud Shell, ingresa lo siguiente:
gcloud compute routers create consumer-cr \ --region=us-east4 --network=consumer-vpc \ --asn=65501
Resultado:
Creating router [consumer-cr]...done. NAME REGION NETWORK consumer-cr us-east4 consumer-vpc
Luego, crea la instancia de puerta de enlace NAT. En Cloud Shell, ingresa lo siguiente:
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
Resultado:
Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.
Ten en cuenta que, de forma predeterminada, la puerta de enlace de Cloud NAT se crea con minPortsPerVm establecido en 64.
Crea las instancias de prueba del consumidor. Aquí completamos las IPs de los productores reservadas para poder consultarlas más adelante en la instancia. En Cloud Shell, ingresa lo siguiente:
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
Resultado:
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 el comportamiento predeterminado de Cloud NAT
En este punto, las instancias del consumidor usan el comportamiento predeterminado de Cloud NAT, que usa la misma IP reservada "nat-address-1" para comunicarse con todas las direcciones externas. Cloud NAT tampoco tiene habilitado el DPA aún.
Para validar qué puertos asignó Cloud NAT a nuestras instancias de consumidor, ejecuta el siguiente comando:
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Resultado de ejemplo
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Consumer IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Consumer IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3
Como puedes ver en el resultado anterior, Cloud NAT asignó 64 puertos por instancia desde la misma IP externa nat-address-1.
Validemos cuántas conexiones podemos abrir en paralelo antes de habilitar el DPA.
Establece una conexión SSH a la primera instancia del consumidor. En Cloud Shell, ingresa lo siguiente:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Ahora deberías estar en la shell de la instancia.
Resultado de muestra (el resultado completo se truncó para mayor brevedad)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
Desde la instancia del consumidor, primero recuperemos las IPs del productor y propaguémoslas como variables de entorno.
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"`
Luego, intenta usar curl en ambas instancias de productores para asegurarte de que podamos acceder a ellas correctamente.
<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>
Ahora intentemos crear muchas conexiones paralelas a una de las instancias del productor ejecutando curl a través de un bucle. Recuerda que Cloud NAT no permite la reutilización de sockets cerrados durante 2 minutos. Por lo tanto, siempre que podamos iterar todos los intentos de conexión en un plazo de 2 minutos, podremos simular conexiones paralelas de esta manera.
Ejecuta el siguiente comando en la sesión de SSH de la instancia
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
Se espera que puedas abrir 64 conexiones paralelas correctamente y que la secuencia de comandos imprima lo siguiente:
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Para ver que no podemos superar las 64 conexiones paralelas, primero espera 2 minutos para que se borren todos los sockets antiguos. Luego, modifica la misma línea de código de la siguiente manera y vuelve a ejecutarla:
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
Ahora deberías ver el siguiente resultado:
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
Esto indica que, si bien las primeras 64 conexiones se realizaron correctamente, las 6 restantes fallaron debido a la falta de puertos.
Entonces, hagamos algo al respecto. Sal de la shell de SSH y habilita DPA en la siguiente sección.
8. Habilita el DPA y valida su comportamiento
Ejecuta el siguiente comando de gcloud, que habilita la DPA y establece la asignación mínima de puertos por VM en 64 y la asignación máxima de puertos en 1,024.
gcloud alpha compute routers nats update consumer-nat-gw --router=consumer-cr \ --region=us-east4 --min-ports-per-vm=64 --max-ports-per-vm=1024 \ --enable-dynamic-port-allocation
que produce lo siguiente
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Ahora, volvamos a ejecutar get-nat-mapping-info para confirmar que ambas instancias aún tienen solo 64 puertos asignados.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Resultado de muestra (truncado para mayor brevedad)
--- 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 ...
No cambió mucho en términos de asignaciones de puertos, ya que la instancia aún no usa ningún puerto de forma activa.
Volvamos a establecer una conexión SSH a la instancia:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Vuelve a exportar las variables de entorno de la IP del productor.
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"`
Vuelve a ejecutar el bucle anterior para simular conexiones paralelas:
while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Ahora deberíamos ver el siguiente resultado:
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 70 successful Loop Done, Sleeping for 150s
Entonces, ¿qué pasó aquí? Cloud NAT aumenta la asignación de puertos a medida que aumenta el uso de puertos, pero esto lleva un tiempo para programarse en toda la capa de redes. Por lo tanto, vemos de 1 a 3 tiempos de espera de conexión antes de completar correctamente el resto de los intentos de conexión.
Especificamos un tiempo de espera agresivo para curl (5 segundos), pero las aplicaciones con tiempos de espera más largos deberían poder completar las conexiones correctamente mientras el DPA aumenta las asignaciones de puertos.
Este comportamiento de aumento se puede ver con mayor claridad cuando ejecutamos el bucle para 1,024 intentos de conexión de la siguiente manera:
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
Ahora esperamos ver el siguiente resultado
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
Dado que Cloud NAT asigna puertos en potencias de 2, lo que duplica las asignaciones en cada paso, vemos que los tiempos de espera de conexión se destacan alrededor de las potencias de 2 entre 64 y 1,024.
Como establecimos maxPortsPerVM en 1,024, no esperamos poder realizar más de 1,024 conexiones. Para probarlo, vuelve a ejecutar el bucle de curl con un recuento superior a 1,024 (después de esperar 2 minutos para restablecer los puertos inactivos).
while true; do for i in {1..1035}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Como se esperaba, el resultado muestra que las conexiones más allá de 1,024 comienzan a fallar.
<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
Si establecemos maxPortsPerVM en 1,024, le indicamos a Cloud NAT que nunca escale las asignaciones de puertos más allá de 1,024 por VM.
Si salimos de la sesión de SSH y volvemos a ejecutar get-nat-mapping-info con la suficiente rapidez, podemos ver los puertos adicionales asignados.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Observa el siguiente resultado:
--- 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
Observa cómo consumer-instance-1 tiene 1,024 puertos asignados, pero consumer-instance-2 solo tiene 64. Esto no era posible antes de la DPA y destaca exactamente el poder de la DPA para Cloud NAT.
Si esperas 2 minutos antes de volver a ejecutar el comando get-nat-mapping-info, notarás que consumer-instance-1 vuelve a su valor mínimo de solo 64 puertos asignados. Ilustra no solo la capacidad de la DPA para aumentar las asignaciones de puertos, sino también para liberarlos cuando no se usan y que otras instancias detrás de la misma puerta de enlace NAT los puedan usar.
9. Prueba las reglas de Cloud NAT con DPA
Recientemente, también lanzamos la funcionalidad de reglas de NAT para Cloud NAT, que permite a los clientes escribir reglas que usan IPs de NAT específicas para ciertos destinos externos. Para obtener más información, consulta la página de documentación sobre las reglas de NAT.
En este ejercicio, observaremos la interacción entre las reglas de DPA y NAT. Primero, definamos una regla NAT para usar nat-address-2 cuando se acceda a producer-address-2.
Ejecuta el siguiente comando de gcloud, que crea la regla de NAT con
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
Deberías obtener el siguiente resultado:
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Ahora volvamos a ejecutar get-nat-mapping-info para ver el efecto de la nueva regla de NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
que debería producir el siguiente resultado
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
Observa que ahora tenemos puertos adicionales asignados (también en 64, el mínimo especificado) específicamente para nat-address-2 en la jerarquía de ruleMappings.
Entonces, ¿qué sucede si una instancia abre muchas conexiones al destino especificado por la regla de NAT? Averigüémoslo.
Volvamos a establecer una conexión SSH a la instancia:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Vuelve a exportar las variables de entorno de la IP del productor.
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"`
Ahora, volvamos a ejecutar el bucle curl en producerip2 esta vez.
while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip2/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Deberías obtener un resultado similar al siguiente:
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
Básicamente, se replica la prueba anterior. Salgamos de la sesión de SSH de la instancia y volvamos a ver las asignaciones de NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
que debería producir el siguiente resultado
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
- <NAT Address IP2>:1088-1119
- <NAT Address IP2>:1152-1215
- <NAT Address IP2>:1280-1407
- <NAT Address IP2>:1536-1791
numTotalDrainNatPorts: 0
numTotalNatPorts: 512
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
- <NAT Address IP2>:32832-32863
- <NAT Address IP2>:32896-32959
- <NAT Address IP2>:33024-33151
- <NAT Address IP2>:33280-33535
numTotalDrainNatPorts: 0
numTotalNatPorts: 512
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
---
instanceName: consumer-instance-2
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1056-1087
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1056-1087
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.3
- natIpPortRanges:
- <NAT Address IP1>:32800-32831
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32800-32831
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.3
---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
- <NAT Address IP1>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
- <NAT Address IP1>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleMappings:
- natIpPortRanges:
- <NAT Address IP2>:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
ruleNumber: 100
sourceAliasIpRange: ''
sourceVirtualIp: 10.0.0.2
Como puedes observar arriba, la IP de NAT predeterminada de consumer-instance-1 ( la IP de nat-address-1) aún tiene solo 64 puertos asignados, pero la IP de la regla de NAT (la IP de nat-address-2) tiene 1,024 puertos asignados. Mientras tanto, consumer-instance-2 mantuvo sus asignaciones predeterminadas de 64 puertos para todas las IPs de NAT.
Como ejercicio, puedes probar el caso inverso. Permite que Cloud NAT desasigne todos los puertos adicionales y, luego, ejecuta el bucle de curl en producerip1 y observa los efectos en el resultado de get-nat-mapping-info.
10. Pasos para la limpieza
Para evitar cargos recurrentes, debes borrar todos los recursos asociados con este codelab.
Primero, borra todas las instancias.
En Cloud Shell, ingresa lo siguiente:
gcloud compute instances delete consumer-instance-1 consumer-instance-2 \ producer-instance-1 producer-instance-2 \ --zone us-east4-a --quiet
Resultado esperado :
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].
A continuación, borra el Cloud Router. En Cloud Shell, ingresa lo siguiente:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Deberías obtener el siguiente resultado :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Liberar todas las direcciones IP externas En Cloud Shell, ingresa lo siguiente:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Deberías obtener el siguiente resultado :
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].
Borra reglas de firewall de VPC. En Cloud Shell, ingresa lo siguiente:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Deberías obtener el siguiente resultado :
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].
Borra subredes. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Deberías obtener el siguiente resultado :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4].
Por último, borremos las VPC. En Cloud Shell, ingresa lo siguiente:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Deberías obtener el siguiente resultado :
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. ¡Felicitaciones!
Completaste el lab de DPA de Cloud NAT.
Temas abordados
- Cómo configurar una puerta de enlace de Cloud NAT en preparación para la DPA
- Cómo inspeccionar las asignaciones de puertos sin DPA
- Cómo habilitar y configurar el DPA para una puerta de enlace NAT
- Cómo observar los efectos de la DPA ejecutando conexiones de salida paralelas
- Cómo agregar reglas NAT a una puerta de enlace NAT con la DPA habilitada
- Cómo ver el comportamiento de la DPA con reglas ejecutando conexiones de salida a varios destinos
Próximos pasos
- Explora nuestra página de documentación sobre la asignación dinámica de puertos.
- Experimenta con el ajuste de los tiempos de espera de NAT y los valores de asignación de puertos con tu aplicación.
- Obtenga más información sobre Herramientas de redes en Google Cloud Platform
©Google LLC o sus afiliados. Todos los derechos reservados. Do not distribute.