Używanie dynamicznego przydzielania portów w Cloud NAT

1. Przegląd

Dynamiczne przydzielanie portów (DPA) to nowa funkcja Cloud NAT. Gdy jest ona włączona, Cloud NAT dynamicznie zwiększa lub zmniejsza przydział portów dla instancji w zależności od ich potrzeb. DPA jest skonfigurowany z minimalnymi i maksymalnymi limitami portów, dzięki czemu nigdy nie zmniejsza liczby portów poniżej minimum ani nie zwiększa jej powyżej maksimum. Dzięki temu niektóre instancje za bramami NAT mogą dynamicznie skalować w górę liczbę połączeń bez konieczności przydzielania większej liczby portów do wszystkich instancji za Cloud NAT.

Bez DPA wszystkie instancje za Cloud NAT mają przydzieloną tę samą liczbę portów niezależnie od wykorzystania, zgodnie z parametrem minPortsPerVm .

Więcej informacji znajdziesz w sekcji dokumentacji poświęconej NAT DPA .

Czego się nauczysz

  • Jak skonfigurować bramę Cloud NAT w ramach przygotowań do DPA.
  • Jak sprawdzać przydziały portów bez DPA.
  • Jak włączyć i skonfigurować DPA dla bramy NAT.
  • Instrukcje: Obserwuj efekty DPA, uruchamiając równoległe połączenia wychodzące.
  • Jak dodać reguły NAT do bramy NAT z włączoną ochroną danych.
  • Jak sprawdzić działanie ochrony danych w ruchu wychodzącym za pomocą reguł, uruchamiając połączenia wychodzące do wielu miejsc docelowych.

Czego potrzebujesz

  • Podstawowa znajomość Google Compute Engine
  • Podstawowa wiedza o sieciach i protokole TCP/IP
  • Podstawowa znajomość wiersza poleceń w systemach Unix i Linux
  • Warto wcześniej zapoznać się z sieciami w Google Cloud, np. w module Networking in Google Cloud.
  • Projekt Google Cloud z włączonym „dostępem do wersji alfa”.
  • Znajomość podstawowych informacji o Cloud NAT.

2. Korzystanie z konsoli Google Cloud i Cloud Shell

Aby korzystać z GCP, w tym module będziemy używać zarówno konsoli Google Cloud, jak i Cloud Shell.

Google Cloud Console

Konsola Cloud jest dostępna pod adresem https://console.cloud.google.com.

75eef5f6fd6d7e41.png

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Możesz go w dowolnym momencie zaktualizować.
  • Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i jest niezmienny (nie można go zmienić po ustawieniu). Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości modułów z kodem musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako PROJECT_ID). Jeśli Ci się nie podoba, wygeneruj inny losowy identyfikator lub spróbuj użyć własnego i sprawdź, czy jest dostępny. Po utworzeniu projektu jest on „zamrażany”.
  • Istnieje też trzecia wartość, czyli numer projektu, którego używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Aby wyłączyć zasoby i uniknąć naliczenia opłat po zakończeniu tego samouczka, postępuj zgodnie z instrukcjami „czyszczenia” na końcu ćwiczenia. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Uruchamianie Cloud Shell

Z Google Cloud można korzystać zdalnie na laptopie, ale w tym module praktycznym będziesz używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.

W konsoli GCP kliknij ikonę Cloud Shell na pasku narzędzi w prawym górnym rogu:

bce75f34b2c53987.png

Uzyskanie dostępu do środowiska i połączenie się z nim powinno zająć tylko kilka chwil. Po zakończeniu powinno wyświetlić się coś takiego:

f6ef2b5f13479f3a.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Wszystkie zadania w tym module możesz wykonać w przeglądarce.

3. Konfiguracja modułu

Na potrzeby tego modułu użyjesz projektu i utworzysz 2 sieci VPC z podsiecią w każdej z nich. Zarezerwujesz zewnętrzne adresy IP, a następnie utworzysz i skonfigurujesz bramę Cloud NAT (z routerem Cloud Router), 2 instancje producenta i 2 instancje konsumenta. Po sprawdzeniu domyślnego działania usługi Cloud NAT włączysz dynamiczną alokację portów i sprawdzisz jej działanie. Na koniec skonfigurujesz reguły NAT i zaobserwujesz interakcję między DPA a regułami NAT.

Omówienie architektury sieci:

a21caa6c333909d8.png

4. Rezerwowanie zewnętrznych adresów IP

Zarezerwujmy wszystkie zewnętrzne adresy IP, które będą używane w tym module. Pomoże Ci to napisać wszystkie odpowiednie reguły NAT i zapory sieciowej w sieciach VPC konsumenta i producenta.

W Cloud Shell:

gcloud compute addresses  create nat-address-1 nat-address-2 \
 producer-address-1 producer-address-2 --region us-east4

Dane wyjściowe:

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

Wypełnij zarezerwowane adresy IP jako zmienne środowiskowe.

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)"`

Nie oczekuje się żadnych danych wyjściowych, ale można sprawdzić, czy adresy zostały prawidłowo wypełnione. Wyświetlmy wartości wszystkich zmiennych środowiskowych.

env | egrep '^(nat|producer)ip[1-3]'

Dane wyjściowe:

producerip1=<Actual Producer IP 1>
producerip2=<Actual Producer IP 2>
natip1=<NAT IP 1>
natip2=<NAT IP 2>

5. Konfigurowanie sieci VPC producenta i instancji.

Teraz utworzymy zasoby dla zasobów producenta. Instancje działające w sieci VPC producenta będą oferować usługę dostępną z internetu za pomocą 2 publicznych adresów IP: „producer-address-1” i „producer-address-2”.

Najpierw utwórzmy sieć VPC. W Cloud Shell:

gcloud compute networks create producer-vpc --subnet-mode custom

Dane wyjściowe:

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

Następnie utwórz podsieć w regionie us-east4. W Cloud Shell:

gcloud compute networks subnets create prod-net-e4 \
   --network producer-vpc --range 10.0.0.0/24 --region us-east4

Dane wyjściowe:

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

Następnie utwórz reguły zapory sieciowej VPC, aby umożliwić adresom IP NAT dotarcie do instancji producenta na porcie 8080.

W przypadku pierwszej reguły w Cloud Shell:

gcloud compute firewall-rules create producer-allow-80 \
  --network producer-vpc --allow tcp:80 \
  --source-ranges $natip1,$natip2

Dane wyjściowe:

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

Następnym krokiem jest utworzenie 2 instancji producenta.

Instancje producenta będą uruchamiać proste wdrożenie serwera proxy nginx.

Aby szybko udostępnić instancje z wymaganym oprogramowaniem, utworzymy je za pomocą skryptu uruchamiania, który instaluje nginx przy użyciu menedżera pakietów Debian APT.

Aby umożliwić pisanie reguł NAT, przypiszemy do każdej instancji inny zarezerwowany adres IP.

Utwórz pierwszą instancję. W 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"

Dane wyjściowe:

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

Następnie utwórz drugą instancję. W 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"

Dane wyjściowe:

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. Konfigurowanie sieci VPC klienta, Cloud NAT i instancji

Po utworzeniu usługi producenta możesz utworzyć sieć VPC konsumenta i jej bramę Cloud NAT.

Po utworzeniu sieci VPC i podsieci dodamy prostą regułę zapory sieciowej ruchu przychodzącego, aby zezwolić na zakresy adresów IP źródła IAP dla protokołu TCP. Umożliwi nam to bezpośrednie łączenie się z instancjami klienta przez SSH za pomocą gcloud.

Następnie utworzymy prostą bramę Cloud NAT w trybie ręcznej alokacji i powiązany z nią zarezerwowany adres „nat-address-1”. W kolejnych częściach tego laboratorium zaktualizujemy konfigurację bramy, aby włączyć dynamiczną alokację portów, a później dodamy reguły niestandardowe.

Najpierw utwórzmy sieć VPC. W Cloud Shell:

gcloud compute networks create consumer-vpc --subnet-mode custom

Dane wyjściowe:

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

Następnie utwórz podsieć w regionie us-east4. W Cloud Shell:

gcloud compute networks subnets create cons-net-e4 \
   --network consumer-vpc --range 10.0.0.0/24 --region us-east4

Dane wyjściowe:

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

Następnie utwórz reguły zapory sieciowej VPC, aby zezwolić zakresom adresów IAP na dostęp do instancji klienta na porcie 22.

W przypadku pierwszej reguły zapory sieciowej uruchom w Cloud Shell to polecenie:

gcloud compute firewall-rules create consumer-allow-iap \
  --network consumer-vpc --allow tcp:22 \
  --source-ranges 35.235.240.0/20

Dane wyjściowe:

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

Zanim utworzymy bramę NAT, musimy najpierw utworzyć instancję routera Cloud Router (używamy prywatnego numeru ASN, ale nie ma to znaczenia w przypadku działań w tym laboratorium). W Cloud Shell:

gcloud compute routers create consumer-cr \
--region=us-east4 --network=consumer-vpc \
 --asn=65501

Dane wyjściowe:

Creating router [consumer-cr]...done.
NAME         REGION       NETWORK
consumer-cr  us-east4  consumer-vpc

Następnie utwórz instancję bramy NAT. W 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

Dane wyjściowe:

Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.

Pamiętaj, że domyślnie brama Cloud NAT jest tworzona z wartością minPortsPerVm ustawioną na 64.

Utwórz instancje testowe konsumenta. Wypełniamy tutaj zarezerwowane adresy IP producenta, aby móc się do nich później odwoływać w ramach instancji. W 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

Dane wyjściowe:

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. Sprawdzanie domyślnego działania Cloud NAT

W tym momencie instancje klienta korzystają z domyślnego działania Cloud NAT, które używa tego samego zarezerwowanego adresu IP „nat-address-1” do komunikacji ze wszystkimi adresami zewnętrznymi. Usługa Cloud NAT nie ma jeszcze włączonej umowy DPA.

Sprawdźmy, jakie porty Cloud NAT przydzielił naszym instancjom klienta, uruchamiając to polecenie:

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

Przykładowe dane wyjściowe

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

Jak widać w powyższych danych wyjściowych, Cloud NAT przydzielił 64 porty na instancję z tego samego zewnętrznego adresu IP.nat-address-1

Zanim włączymy DPA, sprawdźmy, ile połączeń możemy otworzyć równolegle.

Połącz się przez SSH z pierwszą instancją klienta. W Cloud Shell:

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

Powinna teraz być widoczna powłoka instancji.

Przykładowe dane wyjściowe (pełne dane wyjściowe skrócone z uwagi na długość)

External IP address was not found; defaulting to using IAP tunneling.
...
...
<username>@consumer-instance-1:~$

Najpierw pobierzmy adresy IP producenta z instancji konsumenckiej i wypełnijmy je jako zmienne środowiskowe.

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

Następnie spróbuj użyć polecenia curl w przypadku obu instancji producenta, aby sprawdzić, czy można się z nimi połączyć.

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

Teraz spróbujmy utworzyć wiele równoległych połączeń z jedną z instancji producenta, uruchamiając curl w pętli. Pamiętaj, że Cloud NAT nie zezwala na ponowne użycie zamkniętych gniazd przez 2 minuty. Dlatego, o ile możemy wykonać wszystkie próby połączenia w ciągu 2 minut, możemy w ten sposób symulować połączenia równoległe.

W sesji SSH instancji uruchom to polecenie:

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

Powinno się udać otworzyć 64 połączenia równoległe, a skrypt powinien wyświetlić te informacje:

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

Aby sprawdzić, że nie możemy przekroczyć 64 połączeń równoległych, najpierw poczekaj 2 minuty, aż wszystkie stare gniazda zostaną wyczyszczone. Następnie zmień to polecenie na to poniżej i uruchom je ponownie:

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

Powinny się wówczas wyświetlić następujące wyniki:

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

Oznacza to, że pierwsze 64 połączenia zostały nawiązane, ale pozostałych 6 nie udało się nawiązać z powodu niedostępności portów.

Zróbmy coś z tym problemem. Zamknij powłokę SSH i włącz DPA w następnej sekcji.

8. Włączanie DPA i sprawdzanie jego działania

Uruchom to polecenie gcloud, które włącza dynamiczne przydzielanie portów i ustawia minimalną liczbę portów na maszynę wirtualną na 64, a maksymalną na 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

Która z tych funkcji daje następujący wynik:

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

Teraz ponownie uruchom get-nat-mapping-info, aby potwierdzić, że obie instancje nadal mają przydzielone tylko 64 porty.

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

Przykładowe dane wyjściowe (skrócone z uwagi na długość)

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

W przypadku przydziałów portów niewiele się zmieniło, ponieważ instancja nie używa jeszcze żadnych portów.

Połączmy się ponownie z instancją przez SSH:

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

Ponownie wyeksportuj zmienne środowiskowe adresu IP producenta.

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

Następnie ponownie uruchom poprzednią pętlę, aby zasymulować połączenia równoległe:

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

Powinny się wyświetlić te dane wyjściowe:

Connection # 64 successful
Connection # 65 failed

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

Co się tu stało? Cloud NAT zwiększa przydział portów wraz ze wzrostem ich wykorzystania, ale zaprogramowanie tego w warstwie sieciowej zajmuje trochę czasu. Dlatego przed pomyślnym zakończeniem pozostałych prób połączenia widzimy 1–3 przekroczenia limitu czasu połączenia.

Określiliśmy agresywny czas oczekiwania dla curl (5 sekund), ale aplikacje z dłuższymi czasami oczekiwania powinny być w stanie pomyślnie nawiązywać połączenia, gdy DPA zwiększa przydział portów.

To zachowanie można lepiej zaobserwować, gdy uruchomimy pętlę 1024 razy, jak poniżej:

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

Teraz powinny się wyświetlić te dane wyjściowe:

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

Cloud NAT przydziela porty w potęgach liczby 2, co w zasadzie podwaja przydział w każdym kroku. Dlatego widzimy, że przekroczenia limitu czasu połączenia są zaznaczone w potęgach liczby 2 między 64 a 1024.

Ponieważ ustawiliśmy wartość maxPortsPerVM na 1024, nie spodziewamy się, że będziemy mogli nawiązać więcej niż 1024 połączenia. Możemy to sprawdzić, ponownie uruchamiając pętlę curl z liczbą większą niż 1024 (po odczekaniu 2 minut na zresetowanie nieaktualnych portów).

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

Zgodnie z oczekiwaniami dane wyjściowe pokazują, że połączenia powyżej 1024 zaczynają się nie powodzić.

<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

Ustawiając wartość maxPortsPerVM na 1024, instruujemy Cloud NAT, aby nigdy nie skalował przydziałów portów powyżej 1024 na maszynę wirtualną.

Jeśli zakończymy sesję SSH i ponownie uruchomimy polecenie get-nat-mapping-info wystarczająco szybko, zobaczymy dodatkowe przydzielone porty.

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

i sprawdź, czy wyświetlają się te dane wyjściowe:

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

Zwróć uwagę, że consumer-instance-1 ma przypisane 1024 porty, a consumer-instance-2 tylko 64 porty. Przed wprowadzeniem DPA nie było to łatwe, co pokazuje, jak przydatne jest DPA w przypadku Cloud NAT.

Jeśli przed ponownym uruchomieniem polecenia get-nat-mapping-info odczekasz 2 minuty, zauważysz, że consumer-instance-1 wróciło do minimalnej wartości 64 przydzielonych portów. Ilustruje to nie tylko możliwość zwiększania przydziałów portów przez DPA, ale także zwalniania ich, gdy nie są używane, aby mogły być wykorzystywane przez inne instancje za tą samą bramą NAT.

9. Testowanie reguł Cloud NAT za pomocą DPA

Niedawno udostępniliśmy też funkcję reguł NAT dla Cloud NAT, która umożliwia klientom tworzenie reguł używających określonych adresów IP NAT w przypadku niektórych miejsc docelowych. Więcej informacji znajdziesz na stronie dokumentacji dotyczącej reguł NAT.

W tym ćwiczeniu przyjrzymy się interakcji między DPA a regułami NAT. Najpierw zdefiniujmy regułę NAT, aby używać nat-address-2 podczas uzyskiwania dostępu do producer-address-2.

Uruchom to polecenie gcloud, które tworzy regułę NAT za pomocą

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

Powinny się wyświetlić te dane wyjściowe:

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

Uruchommy ponownie polecenie get-nat-mapping-info, aby zobaczyć efekt nowej reguły NAT.

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

Powinny się wyświetlić te dane wyjściowe:

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

Zwróć uwagę, że teraz mamy dodatkowe porty (również na poziomie 64, czyli określonego minimum) przydzielone specjalnie do nat-address-2 w hierarchii ruleMappings.

Co się stanie, jeśli instancja otworzy wiele połączeń z miejscem docelowym określonym przez regułę NAT? Zaraz się dowiemy.

Połączmy się ponownie z instancją przez SSH:

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

Ponownie wyeksportuj zmienne środowiskowe adresu IP producenta.

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

Teraz ponownie uruchomimy pętlę curl, tym razem w odniesieniu do producerip2.

while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip2/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

Dane wyjściowe powinny wyglądać podobnie do tych:

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

W zasadzie odzwierciedla poprzedni test. Zakończmy sesję SSH instancji i ponownie przyjrzyjmy się mapowaniom NAT.

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

Powinny się wyświetlić te dane wyjściowe:

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

Jak widać powyżej, domyślny adres IP NAT usługi consumer-instance-1 ( adres IP usługi nat-address-1) ma nadal tylko 64 przydzielone porty, ale adres IP reguły NAT (adres IP usługi nat-address-2) ma 1024 przydzielone porty. W tym czasie consumer-instance-2 zachowało domyślne przydziały 64 portów dla wszystkich adresów IP NAT.

Możesz przetestować przypadek odwrotny. Zezwól usłudze Cloud NAT na zwolnienie wszystkich dodatkowych portów, a następnie uruchom pętlę curl względem producerip1 i obserwuj efekty na danych wyjściowych get-nat-mapping-info.

10. Procedura czyszczenia

Aby uniknąć naliczania opłat, usuń wszystkie zasoby powiązane z tym ćwiczeniem.

Najpierw usuń wszystkie instancje.

W Cloud Shell:

gcloud compute instances delete consumer-instance-1 consumer-instance-2 \
 producer-instance-1 producer-instance-2 \
 --zone us-east4-a --quiet

Oczekiwane dane wyjściowe :

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

Następnie usuń router Cloud Router. W Cloud Shell:

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

Powinny się wyświetlić te dane wyjściowe :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].

Zwolnij wszystkie zewnętrzne adresy IP. W Cloud Shell:

gcloud compute addresses delete nat-address-1 \
 nat-address-2 producer-address-1 \
 producer-address-2 --region us-east4 --quiet

Powinny się wyświetlić te dane wyjściowe :

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

Usuń reguły zapory sieciowej VPC. W Cloud Shell:

gcloud compute firewall-rules delete consumer-allow-iap \
 producer-allow-80 --quiet

Powinny się wyświetlić te dane wyjściowe :

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

Usuń podsieci. W Cloud Shell:

gcloud compute networks subnets delete cons-net-e4 \
 prod-net-e4 --region=us-east4 --quiet

Powinny się wyświetlić te dane wyjściowe :

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

Na koniec usuńmy sieci VPC. W Cloud Shell:

gcloud compute networks delete consumer-vpc \
 producer-vpc --quiet

Powinny się wyświetlić te dane wyjściowe :

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. Gratulacje!

Laboratorium dotyczące usługi Cloud NAT DPA zostało ukończone.

Omówione tematy

  • Jak skonfigurować bramę Cloud NAT w ramach przygotowań do DPA.
  • Jak sprawdzać przydziały portów bez DPA.
  • Jak włączyć i skonfigurować DPA dla bramy NAT.
  • Instrukcje: Obserwuj efekty DPA, uruchamiając równoległe połączenia wychodzące.
  • Jak dodać reguły NAT do bramy NAT z włączoną ochroną danych.
  • Jak sprawdzić działanie ochrony danych w ruchu wychodzącym za pomocą reguł, uruchamiając połączenia wychodzące do wielu miejsc docelowych.

Następne kroki

© Google, Inc. lub jej podmioty stowarzyszone. Wszelkie prawa zastrzeżone. Nie rozpowszechniać.