Używanie dynamicznego przydzielania portów w Cloud NAT

1. Omówienie

Dynamic Port Allocation (DPA) to nowa funkcja w Cloud NAT. Po włączeniu DPA Cloud NAT dynamicznie skaluje przydziały portów w górę i w dół dla instancji w zależności od potrzeb. DPA ma skonfigurowany minimalny i maksymalny limit portów, dzięki czemu nigdy nie skaluje portów poniżej wartości minimalnej ani nie skaluje się w górę ponad wartość maksymalną. Dzięki temu niektóre instancje za bramami NAT mogą dynamicznie skalować liczbę połączeń w górę bez konieczności przydzielania większej liczby portów do wszystkich instancji za Cloud NAT.

Bez DPA wszystkie instancje obsługujące Cloud NAT przydzielają taką samą liczbę portów niezależnie od użycia, zgodnie z definicją za pomocą parametru minPortsPerVm .

Więcej informacji znajdziesz w sekcji dokumentacji dotyczącej NAT DPA .

Czego się nauczysz

  • Jak skonfigurować bramę Cloud NAT w ramach przygotowań do udzielenia DPA.
  • Jak sprawdzić przydział portów bez DPA.
  • Jak włączyć i skonfigurować DPA dla bramy NAT.
  • Jak obserwować efekty działania DPA przez uruchamianie równoległych połączeń ruchu wychodzącego.
  • Jak dodać reguły NAT do bramy NAT z włączoną funkcją DPA.
  • Jak sprawdzić działanie DPA za pomocą reguł przez uruchamianie połączeń wychodzących do wielu miejsc docelowych.

Czego potrzebujesz

  • Podstawowa znajomość Google Compute Engine
  • Podstawowa wiedza o sieciach i TCP/IP
  • Podstawowa wiedza na temat wiersza poleceń systemu Unix/Linux.
  • Warto zapoznać się z prezentacją sieci w Google Cloud, na przykład z modułem Sieć w Google Cloud.
  • Projekt Google Cloud z dostępem alfa .
  • Informacje o podstawach Cloud NAT.

2. Korzystanie z konsoli Google Cloud i Cloud Shell

W tym module będziemy używać zarówno konsoli Google Cloud, jak i Cloud Shell.

Konsola Google Cloud

Konsola Cloud jest dostępna na stronie https://console.cloud.google.com.

75eef5f6fd6d7e41.png

Samodzielne konfigurowanie środowiska

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Nazwa projektu jest wyświetlaną nazwą uczestników tego projektu. To ciąg znaków, który nie jest używany przez interfejsy API Google i w każdej chwili możesz go zaktualizować.
  • Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i nie można go zmienić (nie można go zmienić po ustawieniu). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń w Codelabs musisz odwoływać się do identyfikatora projektu (który zwykle nazywa się PROJECT_ID), więc jeśli Ci się nie podoba, wygeneruj kolejny losowy projekt lub wypróbuj swój własny identyfikator i sprawdź, czy jest dostępny. Potem urządzenie jest „zawieszone”. po utworzeniu projektu.
  • Występuje trzecia wartość – numer projektu – używany przez niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w konsoli Cloud, aby móc korzystać z zasobów i interfejsów API Cloud. Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Aby wyłączyć zasoby, aby nie naliczać opłat po zakończeniu tego samouczka, wykonaj czynności „wyczyść” znajdziesz na końcu tego ćwiczenia. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Uruchamianie Cloud Shell

Google Cloud można obsługiwać zdalnie z laptopa, ale w ramach tego ćwiczenia z programowania wykorzystasz Google Cloud Shell – środowisko wiersza poleceń działające w chmurze.

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

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, znacząco zwiększając wydajność sieci i uwierzytelnianie. Wszystkie zadania w tym module możesz wykonać w przeglądarce.

3. Konfiguracja modułu

W tym module wykorzystasz projekt i utworzysz 2 sieci VPC z podsiecią w każdym z nich. Zarezerwujesz zewnętrzne adresy IP, a następnie utworzysz i skonfigurujesz bramę Cloud NAT (z routerem Cloud Router), 2 instancje producenta oraz 2 instancje klienta. Po zweryfikowaniu domyślnego działania Cloud NAT włączysz dynamiczne przydzielanie portów i zweryfikujesz jego działanie. Na koniec skonfigurujesz reguły NAT i będziesz obserwować interakcję między regułami DPA i NAT.

Omówienie architektury sieci:

a21caa6c333909d8.png

4. Zarezerwuj zewnętrzne adresy IP

Zarezerwujmy wszystkie zewnętrzne adresy IP do wykorzystania w tym module. Pomoże Ci to napisać wszystkie istotne reguły NAT i zapory sieciowej w sieciach VPC klienta 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 adresy IP, które zostały zarezerwowane 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 oczekujemy żadnych danych wyjściowych, ale chcemy sprawdzić, czy adresy zostały prawidłowo wypełnione. Teraz możemy wyświetlić 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. Konfiguracja sieci VPC i instancji producenta.

Teraz utworzymy zasoby dla zasobów producenta. Instancje działające w produkcyjnej sieci VPC będą oferować usługę dostępną z internetu przy użyciu 2 publicznych adresów IP „producent-adres-1” i „adres-producenta-2” ,

Najpierw utwórzmy 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

Utwórzmy 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

Teraz utworzymy reguły zapory sieciowej VPC, które umożliwią adresom IP NAT dotarcie do instancji producenta na porcie 8080.

W przypadku pierwszej reguły z 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 uruchomią proste wdrożenie serwera proxy nginx.

Aby szybko udostępnić instancje z pełnym wymaganym oprogramowaniem, utworzymy instancje za pomocą skryptu startowego, który zainstaluje nginx przy użyciu menedżera pakietów Debian APT.

Aby możliwe było pisanie reguł NAT, każda instancja będzie miała 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. Skonfiguruj konsumencką sieć VPC, Cloud NAT i instancje

Po utworzeniu usługi producenta czas utworzyć sieć VPC klienta i jej bramę Cloud NAT.

Po utworzeniu sieci VPC i podsieci dodamy prostą regułę zapory sieciowej dla ruchu przychodzącego, aby zezwolić na IAP dla zakresów źródłowych adresów IP TCP. Pozwoli nam to bezpośrednio połączyć się z instancjami konsumenta za pomocą gcloud.

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

Najpierw utwórzmy 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

Utwórzmy 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

Teraz utworzymy reguły zapory sieciowej VPC, które pozwolą na dotarcie adresów zakresów IAP do instancji konsumenta 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 utworzysz bramę NAT, musimy najpierw utworzyć instancję Cloud Router (używamy prywatnego numeru ASN, ale nie ma on znaczenia w przypadku działań w tym module). 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.

Zwróć uwagę, że domyślnie brama Cloud NAT jest tworzona z ustawieniem minPortsPerVm ustawionym na 64.

Utwórz instancje testowe konsumenta. Tutaj wypełniamy zarezerwowane adresy IP producenta, aby można było odwołać się do nich później w 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. Sprawdź domyślne działanie Cloud NAT

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

Sprawdźmy, które porty Cloud NAT przydzieliły nasze instancje klientów, uruchamiając następujące polecenie

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

Przykładowe wyniki

---
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ć powyżej, usługa Cloud NAT przydzieliła 64 porty na instancję z tego samego zewnętrznego adresu IP nat-address-1

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

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

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

Powinno być teraz w powłoce instancji.

Przykładowe dane wyjściowe (pełne dane wyjściowe obcięte dla zwięzłości)

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

Z poziomu instancji konsumenta pobierz najpierw oba adresy IP producenta i uzupełnij 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"`

Potem spróbuj utworzyć polecenie curl do obu instancji producenta, aby upewnić się, że możemy 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, wykonując curl w pętli. Pamiętaj, że Cloud NAT nie zezwala na ponowne użycie zamkniętych gniazd przez 2 minuty. Jeśli więc uda nam się zapętlić wszystkie próby nawiązania połączenia w ciągu 2 minut, możemy w ten sposób symulować połączenia równoległe.

Uruchom poniższe polecenie w sesji SSH instancji

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

Można oczekiwać, że uda się otworzyć 64 połączenia równoległe, a skrypt powinien wyświetlić następujący

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

Jeśli chcesz sprawdzić, czy nie możemy przekroczyć liczby 64 połączeń równoległych, poczekaj 2 minuty, aby umożliwić czyszczenie wszystkich starych gniazdek. Następnie popraw ten sam wiersz w następujący sposób i uruchom go 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

Teraz otrzymasz następujące dane wyjściowe

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 chociaż udało się zrealizować pierwsze 64 połączenia, pozostałe 6 nie udało się zrealizować z powodu niedostępności portów.

Zróbmy to teraz, wyjdź z powłoki SSH i włącz DPA w następnej sekcji.

8. Włącz DPA i zweryfikuj jego działanie

Uruchom to polecenie gcloud, które włącza DPA. Ustawia minimalny przydział portów na maszynę wirtualną na 64, a maksymalny przydział portów 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

Powoduje to wyświetlenie tych informacji:

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

Teraz uruchommy ponownie polecenie get-nat-mapping-info, aby sprawdzić, czy do obu instancji nadal zostały przydzielone tylko 64 porty

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

Przykładowe dane wyjściowe (skrócone dla zwięzłości)

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

Niewiele się zmieniło w kwestii przydziału portów, ponieważ instancja nie używa jeszcze żadnych portów.

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

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

Ponownie wyeksportuj zmienne środowiskowe 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"`

Ponownie uruchom wcześniejszą pętlę, aby symulować 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ć następujące dane wyjściowe:

Connection # 64 successful
Connection # 65 failed

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

Co się stało? Cloud NAT zwiększa przydział portów zgodnie ze wzrostem wykorzystania portów, ale zaprogramowanie tego w całej warstwie sieciowej wymaga trochę czasu. Dlatego przed ukończeniem pozostałych prób nawiązania połączenia następuje od 1 do 3 przekroczeń czasu oczekiwania na połączenie.

Określiliśmy agresywny limit czasu curl (5 sekund), ale aplikacje z dłuższym limitem czasu powinny mieć możliwość nawiązywania połączeń, podczas gdy DPA zwiększa przydział portów.

Działanie optymalizacyjne jest wyraźniejsze, gdy uruchamiamy pętlę dla prób nawiązania połączenia 1024.

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

Spodziewamy się, że zobaczymy następujące 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 2, co zasadniczo podwaja przydziały w każdym kroku, dlatego limity czasu połączenia są podświetlone wokół potęg 2 z zakresu od 64 do 1024.

Ustawiliśmy maxPortsPerVM na 1024, więc prawdopodobnie uda nam się uzyskać więcej niż 1024 połączenia. Możemy to sprawdzić, ponownie uruchamiając pętlę curl z liczbą wyższą niż 1024 (po odczekaniu 2 minut w związku z resetowaniem 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ą kończyć się niepowodzeniem

<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

Dzięki ustawieniu maxPortsPerVM na 1024 poinstruowaliśmy Cloud NAT, aby nigdy nie skalować przydziałów portów powyżej 1024 na maszynę wirtualną.

Jeśli zamkniemy sesję SSH i wystarczająco szybko ponownie uruchomimy get-nat-mapping-info, zobaczymy przydzielone dodatkowe porty

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

Zwróć uwagę na następujące 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 usługa consumer-instance-1 ma przydzielonych 1024 porty, ale consumer-instance-2 – tylko 64. Przed DPA nie było to łatwe do rozwiązania i dokładnie podkreśla potencjał tej funkcji dla Cloud NAT.

Jeśli poczekasz 2 minuty, zanim ponownie uruchomisz polecenie get-nat-mapping-info, zauważysz, że consumer-instance-1 powróci do minimalnej wartości, która wynosi tylko 64 przypisane porty. Ilustracja nie tylko możliwości zwiększania przydziałów portów przez organ ochrony danych, ale również zwalniania ich, gdy nie są używane do potencjalnego użycia przez inne instancje obsługujące tę samą bramę NAT.

9. Testowanie reguł Cloud NAT z użyciem DPA

Niedawno opublikowaliśmy też funkcję reguł NAT dla Cloud NAT, która umożliwia klientom pisanie reguł korzystających z określonych adresów IP NAT w określonych zewnętrznych miejscach docelowych. Więcej informacji znajdziesz na stronie dokumentacji reguł NAT.

W tym ćwiczeniu obserwujemy interakcję między regułami DPA i NAT. Najpierw zdefiniujmy regułę NAT, która będzie używać nat-address-2 przy dostępie do producer-address-2.

Uruchom poniższe polecenie gcloud, aby utworzyć 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

Możesz spodziewać się następujących danych wyjściowych

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

Teraz uruchommy ponownie polecenie get-nat-mapping-info, aby sprawdzić efekt nowej reguły NAT.

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

Co powinno zwrócić te wyniki:

---
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 przypisaliśmy dodatkowe porty (także na poziomie 64 (określone minimum) specjalnie dla usługi nat-address-2 w hierarchii ruleMappings.

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

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

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

Ponownie wyeksportuj zmienne środowiskowe 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"`

A teraz ponownie wykonajmy pętlę curl z użyciem elementu 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

Powinny pojawić się dane wyjściowe podobne do tych poniżej.

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

Powielam poprzedni test. Zakończmy sesję SSH instancji i ponownie przyjrzyjmy się mapowaniu NAt.

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

Co powinno zwrócić te wyniki:

---
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 consumer-instance-1 ( adres IP dla nat-address-1) nadal ma przydzielone tylko 64 porty, ale adres IP reguły NAT (dla nat-address-2) ma przydzielonych 1024 porty. W tym czasie usługa consumer-instance-2 zachowała domyślne przydziały 64 portów dla wszystkich adresów IP NAT.

W ramach ćwiczenia możesz przetestować odwrotność sytuacji. Pozwól Cloud NAT na anulowanie wszystkich dodatkowych portów, a następnie uruchom pętlę curl względem instancji producerip1 i obserwuj efekty jej działania na danych wyjściowych get-nat-mapping-info

10. Etapy czyszczenia

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

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

Możesz spodziewać się następujących danych wyjściowych :

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

Możesz spodziewać się następujących danych wyjściowych :

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

Możesz spodziewać się następujących danych wyjściowych :

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

Możesz spodziewać się następujących danych wyjściowych :

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

Możesz spodziewać się następujących danych wyjściowych :

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!

Udało Ci się ukończyć laboratorium DPA Cloud NAT.

Omawiane tematy

  • Jak skonfigurować bramę Cloud NAT w ramach przygotowań do udzielenia DPA.
  • Jak sprawdzić przydział portów bez DPA.
  • Jak włączyć i skonfigurować DPA dla bramy NAT.
  • Jak obserwować efekty działania DPA przez uruchamianie równoległych połączeń ruchu wychodzącego.
  • Jak dodać reguły NAT do bramy NAT z włączoną funkcją DPA.
  • Jak sprawdzić działanie DPA za pomocą reguł przez uruchamianie połączeń wychodzących do wielu miejsc docelowych.

Następne kroki

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