À propos de cet atelier de programmation
1. Présentation
L'allocation dynamique de ports (DPA) est une nouvelle fonctionnalité de Cloud NAT. Lorsque le DPA est activé, Cloud NAT effectue un scaling dynamique des allocations de ports pour les instances en fonction de leurs besoins. Le DPA est configuré avec des limites minimales et maximales de ports de sorte qu'il ne diminue jamais le nombre de ports en dessous de la valeur minimale, ni à la hausse au-delà de la valeur maximale. Cela permet à certaines instances situées derrière des passerelles NAT d'augmenter de manière dynamique le nombre de connexions sans avoir à allouer plus de ports à toutes les instances protégées par Cloud NAT.
Sans DPA, toutes les instances derrière Cloud NAT se voient attribuer le même nombre de ports, quelle que soit leur utilisation, comme défini par le paramètre minPortsPerVm
.
Pour en savoir plus, consultez la section de la documentation sur le DPA NAT .
Points abordés
- Configurer une passerelle Cloud NAT en vue du DPA.
- Inspecter les attributions de ports sans DPA
- Activer et configurer le DPA pour une passerelle NAT
- Comment observer les effets du DPA en exécutant des connexions de sortie parallèles
- Ajouter des règles NAT à une passerelle NAT avec DPA activé
- Comment visualiser le comportement de l'APD avec des règles en exécutant des connexions de sortie vers plusieurs destinations.
Prérequis
- Connaissance de base de Google Compute Engine
- Connaissance de base de la mise en réseau et des protocoles TCP/IP
- Connaissances de base de la ligne de commande Unix/Linux
- Il est utile d'avoir suivi une visite guidée de la mise en réseau dans Google Cloud, par exemple lors de l'atelier Networking in Google Cloud.
- Un projet Google Cloud avec "accès alpha" est activé.
- Comprendre les principes de base de Cloud NAT
2. Utiliser la console Google Cloud et Cloud Shell
Pour interagir avec GCP, nous allons utiliser à la fois la console Google Cloud et Cloud Shell tout au long de cet atelier.
Console Google Cloud
La console Cloud est accessible à l'adresse https://console.cloud.google.com.
Configuration de l'environnement au rythme de chacun
- Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)
- Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères qui n'est pas utilisée par les API Google, et que vous pouvez modifier à tout moment.
- L'ID du projet doit être unique sur l'ensemble des projets Google Cloud et doit être immuable (vous ne pouvez pas le modifier une fois que vous l'avez défini). Cloud Console génère automatiquement une chaîne unique dont la composition importe peu, en général. Dans la plupart des ateliers de programmation, vous devrez référencer l'ID du projet (généralement identifié comme
PROJECT_ID
), donc s'il ne vous convient pas, générez-en un autre au hasard ou définissez le vôtre, puis vérifiez s'il est disponible. Il est ensuite "gelé" une fois le projet créé. - La troisième valeur est le numéro de projet, utilisé par certaines API. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
- Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour arrêter les ressources afin d'éviter qu'elles ne vous soient facturées après ce tutoriel, suivez les instructions de nettoyage indiquées à la fin de l'atelier. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai gratuit pour bénéficier d'un crédit de 300 $.
Démarrer Cloud Shell
Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, nous allons nous servir de Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans le cloud.
Depuis la console GCP, cliquez sur l'icône Cloud Shell de la barre d'outils située dans l'angle supérieur droit :
Le provisionnement et la connexion à l'environnement prennent quelques instants seulement. Une fois l'opération terminée, le résultat devrait ressembler à ceci :
Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser toutes les activités de cet atelier dans un simple navigateur.
3. Mettre en place l'atelier
Dans cet atelier, vous allez utiliser un projet et créer deux VPC comportant chacun un sous-réseau. Vous allez réserver des adresses IP externes, puis créer et configurer une passerelle Cloud NAT (avec un routeur Cloud Router), deux instances de producteur et deux instances client. Après avoir validé le comportement Cloud NAT par défaut, vous activerez l'allocation de ports dynamique et validerez son comportement. Enfin, vous configurerez des règles NAT et observerez les interactions entre l'APD et les règles NAT.
Présentation de l'architecture réseau:
4. Réserver des adresses IP externes
Nous allons réserver toutes les adresses IP externes pour cet atelier. Cela vous aidera à écrire toutes les règles NAT et de pare-feu pertinentes dans les VPC du client et du producteur.
Depuis Cloud Shell:
gcloud compute addresses create nat-address-1 nat-address-2 \ producer-address-1 producer-address-2 --region us-east4
Sortie :
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].
Renseignez les adresses IP réservées en tant que variables d'environnement.
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)"`
Aucun résultat attendu, mais pour confirmer que les adresses ont été correctement renseignées. Nous allons générer les valeurs de toutes les variables d'environnement.
env | egrep '^(nat|producer)ip[1-3]'
Sortie :
producerip1=<Actual Producer IP 1> producerip2=<Actual Producer IP 2> natip1=<NAT IP 1> natip2=<NAT IP 2>
5. Configuration du VPC du producteur et des instances.
Nous allons maintenant créer les ressources pour les ressources du producteur. Les instances exécutées dans le VPC du producteur proposent le service Internet à l'aide de deux adresses IP publiques : "producer-address-1". et "producteur-address-2" pour en savoir plus.
Commençons par créer le VPC. Depuis Cloud Shell:
gcloud compute networks create producer-vpc --subnet-mode custom
Sortie :
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
Créons maintenant le sous-réseau dans la région us-east4. Depuis Cloud Shell:
gcloud compute networks subnets create prod-net-e4 \ --network producer-vpc --range 10.0.0.0/24 --region us-east4
Sortie :
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
Nous allons maintenant créer des règles de pare-feu VPC pour permettre aux adresses IP NAT d'atteindre les instances du producteur sur le port 8080.
Pour la première règle, dans Cloud Shell:
gcloud compute firewall-rules create producer-allow-80 \ --network producer-vpc --allow tcp:80 \ --source-ranges $natip1,$natip2
Sortie :
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
L'étape suivante consiste à créer les deux instances de producteur.
Les instances du producteur vont exécuter un déploiement de proxy nginx simple.
Pour provisionner rapidement les instances avec tous les logiciels nécessaires, nous allons créer les instances avec un script de démarrage qui installe nginx à l'aide du gestionnaire de packages Debian APT.
Pour pouvoir écrire des règles NAT, nous allons provisionner chaque instance avec une adresse IP réservée différente.
Créez la première instance. Depuis 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"
Sortie :
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
Créez ensuite la deuxième instance. Depuis 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"
Sortie :
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. Configurer le VPC client, Cloud NAT et les instances
Maintenant que vous avez créé le service producteur, vous pouvez créer le VPC consommateur et sa passerelle Cloud NAT.
Après avoir créé le VPC et le sous-réseau, nous ajouterons une simple règle de pare-feu d'entrée pour autoriser IAP pour les plages d'adresses IP sources TCP. Cela nous permettra de nous connecter en SSH aux instances client directement à l'aide de gcloud.
Nous créerons ensuite une passerelle Cloud NAT simple en mode d'allocation manuelle et l'adresse réservée "nat-address-1". qui lui est associée. Dans les parties suivantes de l'atelier de programmation, nous mettrons à jour la configuration de la passerelle pour activer l'allocation de ports dynamique. Nous ajouterons ensuite des règles personnalisées.
Commençons par créer le VPC. Depuis Cloud Shell:
gcloud compute networks create consumer-vpc --subnet-mode custom
Sortie :
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
Créons maintenant un sous-réseau dans la région us-east4. Depuis Cloud Shell:
gcloud compute networks subnets create cons-net-e4 \ --network consumer-vpc --range 10.0.0.0/24 --region us-east4
Sortie :
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
Nous allons maintenant créer des règles de pare-feu VPC afin d'autoriser les plages d'adresses IAP à atteindre les instances de clients sur le port 22.
Pour la première règle de pare-feu, exécutez la commande suivante à partir de Cloud Shell:
gcloud compute firewall-rules create consumer-allow-iap \ --network consumer-vpc --allow tcp:22 \ --source-ranges 35.235.240.0/20
Sortie :
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
Avant de créer une passerelle NAT, nous devons d'abord créer une instance Cloud Router (nous utilisons un numéro ASN privé qui n'est pas pertinent pour les activités de cet atelier). Depuis Cloud Shell:
gcloud compute routers create consumer-cr \ --region=us-east4 --network=consumer-vpc \ --asn=65501
Sortie :
Creating router [consumer-cr]...done. NAME REGION NETWORK consumer-cr us-east4 consumer-vpc
Créez ensuite l'instance de passerelle NAT. Depuis 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
Sortie :
Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.
Notez que, par défaut, la passerelle Cloud NAT est créée avec minPortsPerVm
défini sur 64
Créer les instances de test client Nous insérons ici les adresses IP de producteurs réservées afin de pouvoir y faire référence ultérieurement dans l'instance. Depuis 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
Sortie :
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. Vérifier le comportement Cloud NAT par défaut
À ce stade, les instances consommateur utilisent le comportement Cloud NAT par défaut, qui utilise la même adresse IP réservée "nat-address-1". pour communiquer avec toutes les adresses externes. L'APD n'est pas encore activé pour Cloud NAT.
Vérifions les ports sur lesquels Cloud NAT a alloué nos instances clientes en exécutant la commande suivante :
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Exemple de résultat
--- 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
Comme vous pouvez le voir dans le résultat ci-dessus, Cloud NAT a alloué 64 ports par instance à partir de la même adresse IP externe nat-address-1
.
Vérifions le nombre de connexions qu'il est possible d'ouvrir en parallèle avant d'activer le DPA.
Connectez-vous en SSH à la première instance de client. Depuis Cloud Shell:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Vous devriez à présent vous trouver dans le shell de l'instance.
Exemple de résultat (la sortie complète est tronquée pour des raisons de concision)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
À partir de l'instance consommateur, récupérons les deux adresses IP de producteur et ajoutons-les en tant que variables d'environnement.
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"`
Essayez ensuite d'utiliser la commande curl avec les deux instances du producteur pour vous assurer de pouvoir les joindre.
<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>
Essayons maintenant de créer de nombreuses connexions parallèles à l'une des instances de producteur en exécutant curl via une boucle. Rappelez-vous que Cloud NAT n'autorise pas la réutilisation de sockets fermés pendant deux minutes. Par conséquent, tant que nous pouvons boucler toutes les tentatives de connexion en moins de deux minutes, nous pouvons simuler des connexions parallèles de cette façon.
Exécutez la commande suivante dans la session SSH de l'instance
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
Vous vous attendez à ce qu'il puisse ouvrir 64 connexions parallèles et le script devrait afficher ce qui suit :
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Pour vérifier que nous ne pouvons pas dépasser les 64 connexions parallèles, attendez d'abord deux minutes pour permettre à tous les anciens sockets de s'effacer. Ensuite, modifiez la même ligne de texte comme suit et réexécutez-la.
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
Vous devez obtenir le résultat suivant :
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
Cela indique que si les 64 premières connexions ont réussi, les 6 autres connexions ont échoué en raison de l'indisponibilité des ports.
Ensuite, nous allons quitter le shell SSH et activer l'APD dans la section suivante.
8. Activer l'APD et valider son comportement
Exécutez la commande gcloud suivante, qui active le DPA, définit l'allocation de ports minimale par VM sur 64 et l'allocation de ports maximale sur 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
Ce qui renvoie le résultat suivant :
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Exécutons à nouveau get-nat-mapping-info
pour vérifier que les deux instances ne disposent toujours que de 64 ports alloués
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Exemple de sortie (tronqué pour des raisons de concision)
--- 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 ...
Rien n'a changé en termes d'allocation de ports, car l'instance n'utilise pas encore activement de ports.
Reconnectez-vous en SSH à l'instance:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Exportez à nouveau les variables d'environnement IP du producteur.
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"`
Réexécutez la boucle précédente pour simuler des connexions parallèles:
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
Le résultat suivant doit s'afficher :
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 70 successful Loop Done, Sleeping for 150s
Que s'est-il passé ? Cloud NAT augmente l'allocation des ports en fonction de l'augmentation de l'utilisation des ports, mais leur programmation prend un certain temps dans la couche réseau. Par conséquent, nous voyons entre un et trois délais avant expiration de la connexion avant de terminer les autres tentatives de connexion.
Nous avons spécifié un délai avant expiration agressif pour curl (5 secondes), mais les applications avec des délais d'inactivité plus longs devraient pouvoir terminer les connexions avec succès pendant que le DPA augmente les allocations de ports.
Ce comportement d'augmentation est plus clair lorsque nous exécutons la boucle pour 1 024 tentatives de connexion comme ceci
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
Nous nous attendons à présent à la sortie suivante :
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
Comme Cloud NAT alloue des ports en puissances de 2, ce qui double les allocations à chaque étape, nous voyons les délais avant expiration de la connexion mis en évidence autour des puissances 2 entre 64 et 1 024.
Comme nous avons défini maxPortsPerVM
sur 1 024, nous ne nous attendons pas à pouvoir dépasser 1 024 connexions. Nous pouvons tester cela en exécutant à nouveau la boucle curl avec un nombre supérieur à 1 024 (après avoir attendu deux minutes pour réinitialiser les ports obsolètes).
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
Comme prévu, la sortie indique que les connexions après 1024 ne démarrent pas
<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
En définissant maxPortsPerVM
sur 1 024, nous avons demandé à Cloud NAT de ne jamais effectuer un scaling des allocations de ports au-delà de 1 024 par VM.
Si nous quittons la session SSH et réexécutons get-nat-mapping-info
assez rapidement, nous pouvons voir les ports supplémentaires alloués.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Observez le résultat suivant :
--- 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
Notez que 1 024 ports sont alloués pour consumer-instance-1
, mais que 64 ports sont alloués pour consumer-instance-2
. Cela n'était pas facile à réaliser avant l'adoption du DPA, et cela met en évidence la puissance de l'APD pour Cloud NAT.
Si vous attendez deux minutes avant d'exécuter à nouveau la commande get-nat-mapping-info
, vous remarquerez que consumer-instance-1
a retrouvé sa valeur minimale de 64 ports alloués. Illustration de la capacité du DPA à augmenter les allocations de ports, mais aussi à les libérer lorsqu'elles ne sont pas utilisées pour une utilisation potentielle par d'autres instances derrière la même passerelle NAT.
9. Tester les règles Cloud NAT avec l'APD
Nous avons récemment lancé une fonctionnalité de règles NAT pour Cloud NAT, qui permet aux clients d'écrire des règles qui utilisent des adresses IP NAT spécifiques pour certaines destinations externes. Pour en savoir plus, consultez la page de documentation sur les règles NAT.
Dans cet exercice, nous observons l'interaction entre l'APD et les règles NAT. Commençons par définir une règle NAT à utiliser pour nat-address-2
lors de l'accès à producer-address-2
.
Exécutez la commande gcloud suivante, qui crée la règle NAT à l'aide de
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
Vous devriez obtenir le résultat suivant :
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Exécutons à nouveau get-nat-mapping-info
pour observer l'effet de la nouvelle règle NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
Ce qui doit générer le résultat suivant :
--- 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
Notez que des ports supplémentaires sont maintenant alloués (64, le nombre minimal spécifié) spécifiquement pour nat-address-2
sous la hiérarchie ruleMappings
.
Que se passe-t-il si une instance ouvre de nombreuses connexions vers la destination spécifiée par la règle NAT ? Vérifions-le dès maintenant.
Reconnectez-vous en SSH à l'instance:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Exportez à nouveau les variables d'environnement IP du producteur.
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"`
Maintenant, réexécutons la boucle curl sur producerip2
cette fois-ci.
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
Vous devriez obtenir un résultat semblable à celui-ci :
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
En gros, en reproduisant le test précédent. Quittons la session SSH de l'instance et examinons à nouveau les mappages nat.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
Vous devriez obtenir le résultat suivant :
--- 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
Comme vous pouvez le constater ci-dessus, l'adresse IP NAT par défaut de consumer-instance-1
( l'adresse IP de nat-address-1
) n'a toujours que 64 ports alloués, tandis que 1 024 ports sont alloués à l'adresse IP de la règle NAT (adresse IP pour nat-address-2
). Dans le même temps, consumer-instance-2
a conservé ses allocations par défaut de 64 ports pour toutes les adresses IP NAT.
À titre d'exercice, vous pouvez tester le cas inverse. Laissez Cloud NAT désallouer tous les ports supplémentaires, puis exécutez la boucle curl sur producerip1
et observez les effets sur le résultat de get-nat-mapping-info
.
10. Étapes de nettoyage
Pour éviter des frais récurrents, vous devez supprimer toutes les ressources associées à cet atelier de programmation.
Commencez par supprimer toutes les instances.
Depuis Cloud Shell:
gcloud compute instances delete consumer-instance-1 consumer-instance-2 \ producer-instance-1 producer-instance-2 \ --zone us-east4-a --quiet
Résultat attendu :
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].
Supprimez ensuite le routeur Cloud Router. Depuis Cloud Shell:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Vous devez obtenir le résultat suivant :
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Libérez toutes les adresses IP externes. Depuis Cloud Shell:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Vous devez obtenir le résultat suivant :
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].
Supprimer des règles de pare-feu VPC Depuis Cloud Shell:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Vous devez obtenir le résultat suivant :
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].
supprimer des sous-réseaux ; Depuis Cloud Shell:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Vous devez obtenir le résultat suivant :
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].
Enfin, supprimons les VPC. Depuis Cloud Shell:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Vous devez obtenir le résultat suivant :
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. Félicitations !
Vous avez terminé l'atelier DPA Cloud NAT.
Points abordés
- Configurer une passerelle Cloud NAT en vue du DPA.
- Inspecter les attributions de ports sans DPA
- Activer et configurer le DPA pour une passerelle NAT
- Comment observer les effets du DPA en exécutant des connexions de sortie parallèles
- Ajouter des règles NAT à une passerelle NAT avec DPA activé
- Comment visualiser le comportement de l'APD avec des règles en exécutant des connexions de sortie vers plusieurs destinations.
Étapes suivantes
- Parcourez notre page de documentation sur l'allocation de ports dynamique.
- Testez l'ajustement des délais avant expiration NAT et des valeurs d'allocation de ports avec votre application.
- Familiarisez-vous davantage avec la mise en réseau sur Google Cloud Platform.
©Google, Inc. or its affiliates. Tous droits réservés. Ne pas diffuser.