1. Descripción general
La asignación dinámica de puertos (DPA) es una función nueva de Cloud NAT. Con el DPA habilitado, Cloud NAT aumenta o reduce dinámicamente las asignaciones de puertos para las instancias según sus necesidades. El DPA está configurado con límites mínimos y máximos de puertos para que nunca reduzca la escala verticalmente de los puertos por debajo del mínimo ni escale verticalmente más allá del máximo. Esto permite que algunas instancias detrás de las puertas de enlace NAT escalen verticalmente 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 DPA, a todas las instancias detrás de Cloud NAT se les asigna la misma cantidad de puertos independientemente del uso, como se define en el parámetro minPortsPerVm
.
Para obtener más información, consulta la sección de documentación sobre el DPA de NAT .
Qué aprenderás
- Cómo configurar una puerta de enlace de Cloud NAT como preparación para 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 del DPA mediante la ejecución de conexiones de salida paralelas
- Cómo agregar reglas de NAT a una puerta de enlace de NAT con DPA habilitado
- Cómo ver el comportamiento del DPA con reglas mediante la ejecución de 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 Herramientas de redes en Google Cloud.
- Un proyecto de Google Cloud con “acceso alfa” habilitado.
- Comprender los conceptos básicos de Cloud NAT
2. Usa la consola de Google Cloud y Cloud Shell
Para interactuar con GCP, usaremos la consola de Google Cloud 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 dinámica de puertos y validarás su comportamiento. Por último, también configurarás las reglas de NAT y observarás la interacción entre las reglas de NAT y DPA.
Descripción general de la arquitectura de Herramientas de redes:
4. Reservar direcciones IP externas
Reservemos todas las direcciones IP externas para usar en este lab. Esto te ayudará a escribir todas las reglas relevantes de NAT y firewall en la VPC del consumidor y del productor.
Desde Cloud Shell:
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 para confirmar que las direcciones se propagaron correctamente. Obtengamos el resultado de 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 instancias y VPC 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 mediante dos IP públicas “producer-address-1” y “producer-address-2” de Google Cloud.
Primero, creemos la VPC. Desde Cloud Shell:
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. Desde Cloud Shell:
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:
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 del productor ejecutarán una implementación simple del proxy de nginx.
Para aprovisionar rápidamente las instancias con todo el software requerido, 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. Desde 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"
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. Desde 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"
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 de 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 el IAP para los rangos de IP de origen de TCP. Esto nos permitirá establecer una conexión SSH a las instancias del consumidor directamente con gcloud.
A continuación, crearemos una puerta de enlace de Cloud NAT simple en el modo de asignación manual y la dirección reservada “nat-address-1”. asociados con ella. En partes posteriores del codelab, actualizaremos la configuración de la puerta de enlace para habilitar la asignación dinámica de puertos y, más adelante, agregaremos reglas personalizadas.
Primero, creemos la VPC. Desde Cloud Shell:
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. Desde Cloud Shell:
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 una regla de firewall de VPC para permitir que las direcciones de rangos 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 NAT, primero debemos crear una instancia de Cloud Router (usamos un número ASN privado, pero es irrelevante para las actividades de este lab). Desde Cloud Shell:
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. Desde 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
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. Propagamos las IP de productor reservadas aquí para poder hacer referencia a ellas dentro de la instancia más adelante. Desde 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
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 DPA habilitado aún.
Ejecuta el siguiente comando para validar qué puertos asignó Cloud NAT a nuestras instancias de consumidor
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Resultado de muestra
--- 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. Desde Cloud Shell:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Ahora deberías estar en la shell de la instancia.
Resultado de muestra (resultado completo truncado para abreviación)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
Desde la instancia del consumidor, primero recuperamos ambas IP de productor y las propagamos 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 ejecutar el comando curl en ambas instancias de productor para asegurarte de que podemos llegar 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 de 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 realizar un bucle a lo largo de todos los intentos de conexión en 2 minutos, podemos simular conexiones paralelas de esta manera.
Ejecuta el siguiente comando en la sesión 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
Esperarías poder abrir correctamente 64 conexiones paralelas, y la secuencia de comandos debería mostrar lo siguiente:
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Para ver que no podemos ir más allá de las 64 conexiones paralelas, primero espere 2 minutos para permitir que todos los sockets antiguos se borren. Luego, ajusta la línea para lo siguiente y vuelve a ejecutarlo.
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 esperarías 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 disponibilidad de puertos.
Hagamos algo al respecto. Sal de la shell SSH y habilitemos el DPA en la siguiente sección.
8. Habilita el DPA y valida su comportamiento
Ejecuta el siguiente comando de gcloud, que habilita el DPA, establece la asignación de puertos mínima por VM en 64 y la asignación máxima de puertos en 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
Esto da como resultado 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 abreviar)
--- 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 está usando 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 IP de 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"`
Y 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
¿Qué pasó aquí? Cloud NAT acelera la asignación de puertos cuando aumenta el uso de puertos, pero eso tarda un tiempo en programarse en toda la capa de red. 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 con éxito mientras el DPA aumenta las asignaciones de puertos.
Este comportamiento de aumento se puede ver con mayor claridad cuando ejecutamos el bucle para intentos de conexión de 1,024 (de este 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
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
Debido a que Cloud NAT asigna puertos en potencias de 2, lo que, básicamente, duplica las asignaciones en cada paso, vemos los tiempos de espera de conexión destacados alrededor de las potencias de 2 entre 64 y 1,024.
Como configuramos maxPortsPerVM
en 1,024, no esperamos poder usar más de 1,024 conexiones. Para probarlo, volvemos a ejecutar el bucle 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 era de esperar, el resultado muestra que las conexiones superiores a 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
Cuando establecimos maxPortsPerVM
en 1,024, 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 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 puertos asignados. Esto no era fácil de hacer antes de la DPA, y destaca con exactitud la potencia de 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
volvió a su valor mínimo de solo 64 puertos asignados. Esto ilustra la capacidad de la DPA de aumentar las asignaciones de puertos y también liberarlas cuando no estén en uso para que otras instancias detrás de la misma puerta de enlace NAT puedan usarlas.
9. Prueba las reglas de Cloud NAT con DPA
También lanzamos recientemente la funcionalidad de reglas de NAT para Cloud NAT, que permite a los clientes escribir reglas que usan IP de NAT específicas para ciertos destinos externos. Para obtener más información, consulta la página de documentación de las reglas de NAT.
En este ejercicio, observamos la interacción entre las reglas NAT y APD. Primero, definamos una regla de NAT para usar nat-address-2
cuando se acceda a producer-address-2
.
Ejecuta el siguiente comando de gcloud, que crea la regla NAT mediante
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 esperar 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 NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
El resultado debería ser el siguiente:
--- 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 ruleMappings
.
Entonces, ¿qué sucede si una instancia abre muchas conexiones al destino especificado por la regla 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 IP de 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 con 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 esperar 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, replica la prueba anterior. Sal de la sesión SSH de la instancia y volvamos a observar las asignaciones NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
El resultado debería ser el siguiente:
--- 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 para nat-address-1
) aún tiene solo 64 puertos asignados, pero la IP de la regla NAT (IP para nat-address-2
) tiene 1,024 puertos asignados. Mientras tanto, consumer-instance-2
mantuvo sus asignaciones predeterminadas de 64 puertos para todas las IP de NAT.
Como ejercicio, puedes probar el caso inverso. Permite que Cloud NAT anule la asignación de todos los puertos adicionales, luego ejecuta el bucle curl en producerip1
y observa los efectos en el resultado de get-nat-mapping-info
10. Pasos de limpieza
Para evitar cargos recurrentes, debes borrar todos los recursos asociados con este codelab.
Primero, borra todas las instancias.
Desde Cloud Shell:
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. Desde Cloud Shell:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Deberías esperar el siguiente resultado :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Libera todas las direcciones IP externas. Desde Cloud Shell:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Deberías esperar 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 las reglas de firewall de VPC. Desde Cloud Shell:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Deberías esperar 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 las subredes. Desde Cloud Shell:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Deberías esperar 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. Desde Cloud Shell:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Deberías esperar 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 como preparación para 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 del DPA mediante la ejecución de conexiones de salida paralelas
- Cómo agregar reglas de NAT a una puerta de enlace de NAT con DPA habilitado
- Cómo ver el comportamiento del DPA con reglas mediante la ejecución de 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 modificando 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, Inc. or its affiliates. All rights reserved. Do not distribute.