שימוש בהקצאה של יציאות דינמיות ב-Cloud NAT

1. סקירה כללית

הקצאת יציאות דינמית (DPA) היא תכונה חדשה ב-Cloud NAT. כשהתכונה הזו מופעלת, מערכת Cloud NAT מגדילה או מקטינה באופן דינמי את הקצאות היציאות למופעים בהתאם לצורך שלהם. ה-DPA מוגדר עם מגבלות מינימליות ומקסימליות של יציאות, כך שהוא אף פעם לא מצמצם את מספר היציאות מתחת למינימום או מגדיל אותו מעבר למקסימום. כך חלק מהמכונות שמאחורי שערי NAT יכולות להגדיל באופן דינמי את מספר החיבורים שלהן בלי להקצות עוד יציאות לכל המכונות שמאחורי Cloud NAT.

בלי DPA, לכל המופעים שמאחורי Cloud NAT מוקצה אותו מספר יציאות ללא קשר לשימוש, כפי שמוגדר בפרמטר minPortsPerVm .

מידע נוסף מופיע בקטע בנושא NAT DPA .

מה תלמדו

  • איך מגדירים שער Cloud NAT לקראת DPA.
  • איך בודקים הקצאות של ניוד בלי DPA.
  • איך מפעילים ומגדירים DPA לשער NAT.
  • איך בודקים את ההשפעות של DPA על ידי הפעלת חיבורים מקבילים ליציאה.
  • איך מוסיפים כללי NAT ל-NAT Gateway עם DPA מופעל.
  • כדי לראות את ההתנהגות של DPA עם כללים, מריצים חיבורי יציאה לכמה יעדים.

הדרישות

  • ידע בסיסי ב-Google Compute Engine
  • ידע בסיסי ברישות וב-TCP/IP
  • ידע בסיסי בשורת הפקודה של Unix/Linux
  • מומלץ להשלים סיור מודרך ב-Networking in Google Cloud, כמו המעבדה Networking in Google Cloud.
  • פרויקט בענן של Google שמופעלת בו 'גישת אלפא'.
  • הבנה של היסודות של Cloud NAT.

2. שימוש במסוף Google Cloud וב-Cloud Shell

במהלך שיעור ה-Lab הזה נשתמש גם במסוף Google Cloud וגם ב-Cloud Shell כדי ליצור אינטראקציה עם GCP.

Google Cloud Console

אפשר להיכנס ל-Cloud Console בכתובת https://console.cloud.google.com.

75eef5f6fd6d7e41.png

הגדרת סביבה בקצב אישי

  1. נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת של תווים שלא נמצאת בשימוש ב-Google APIs, ואפשר לעדכן אותה בכל שלב.
  • מזהה הפרויקט חייב להיות ייחודי בכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא צריך להתייחס אליה. ברוב סדנאות ה-Codelab, צריך להפנות למזהה הפרויקט (ובדרך כלל הוא מזוהה כ-PROJECT_ID), אז אם לא מוצא חן בעיניכם, אפשר ליצור מזהה אקראי אחר, או לנסות מזהה משלכם ולבדוק אם הוא זמין. אחרי שהפרויקט נוצר, הוא 'קפוא'.
  • יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API. העלות של התרגול הזה לא אמורה להיות גבוהה, ואולי אפילו לא תצטרכו לשלם בכלל. כדי לכבות את המשאבים ולא לחייב אתכם מעבר למה שמוסבר במדריך הזה, צריך לפעול לפי ההוראות לניקוי שמופיעות בסוף ה-Codelab. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

מפעילים את Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה תשתמשו ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.

ב-GCP Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

bce75f34b2c53987.png

יחלפו כמה רגעים עד שההקצאה והחיבור לסביבת העבודה יושלמו. בסיום התהליך, אמור להופיע משהו כזה:

f6ef2b5f13479f3a.png

המכונה הווירטואלית הזו כוללת את כל הכלים שדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-Lab הזה רק באמצעות דפדפן.

3. הגדרת מעבדה

בשיעור ה-Lab הזה תשתמשו בפרויקט ותיצרו שתי רשתות VPC עם תת-רשת בכל אחת מהן. תשמרו כתובות IP חיצוניות, ואז תיצרו ותגדירו שער Cloud NAT (עם Cloud Router), שני מופעים של יצרן ושני מופעים של צרכן. אחרי שמאמתים את התנהגות ברירת המחדל של Cloud NAT, מפעילים הקצאת יציאות דינמית ומאמתים את ההתנהגות שלה. לבסוף, תגדירו גם כללי NAT ותראו את האינטראקציה בין DPA לבין כללי NAT.

סקירה כללית על ארכיטקטורת הרשת:

a21caa6c333909d8.png

4. שמירת כתובות IP חיצוניות

נשמור את כל כתובות ה-IP החיצוניות לשימוש ב-Lab הזה. כך תוכלו לכתוב את כל כללי ה-NAT וחומת האש הרלוונטיים ב-VPC של הצרכן וב-VPC של היצרן.

מתוך Cloud Shell:

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

פלט:

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

מאכלסים את כתובות ה-IP שהוזמנו כמשתני סביבה.

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

לא צפוי פלט, אבל כדי לוודא שהכתובות מולאו בצורה תקינה. נציג את הערכים של כל משתני הסביבה.

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

פלט:

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

5. הגדרה של VPC ומכונות של היוצר.

עכשיו ניצור את המשאבים למשאבי המפיק. האינסטנסים שפועלים ב-VPC של הספק יציעו את השירות שפונה לאינטרנט באמצעות שתי כתובות IP ציבוריות: producer-address-1 ו-producer-address-2.

קודם ניצור את ה-VPC. מתוך Cloud Shell:

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

פלט:

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

בשלב הבא, ניצור את רשת המשנה באזור us-east4. מתוך Cloud Shell:

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

פלט:

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

בשלב הבא, ניצור כללי חומת אש של VPC כדי לאפשר לכתובות ה-IP של NAT להגיע למכונות המפיקות ביציאה 8080.

לכלל הראשון, מ-Cloud Shell:

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

פלט:

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

השלב הבא הוא ליצור את שני מופעי היצרן.

מופעי ה-Producer יפעילו פריסת proxy פשוטה של nginx.

כדי להקצות במהירות את המופעים עם כל התוכנות הנדרשות, ניצור את המופעים עם סקריפט הפעלה שמתקין את nginx באמצעות מנהל החבילות Debian APT.

כדי שנוכל לכתוב כללי NAT, נספק לכל מכונה כתובת IP שמורה שונה.

יוצרים את המופע הראשון. מתוך 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"

פלט:

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

לאחר מכן יוצרים את המכונה השנייה. מתוך 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"

פלט:

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. הגדרה של VPC לצרכן, Cloud NAT ומכונות

אחרי שיצרתם את השירות של הבעלים, הגיע הזמן ליצור את ה-VPC של הצרכן ואת שער Cloud NAT שלו.

אחרי שיוצרים את ה-VPC ואת תת-הרשת, מוסיפים כלל פשוט של חומת אש לתעבורת נתונים נכנסת כדי לאפשר ל-IAP טווחי כתובות IP של מקור TCP. כך נוכל להשתמש ב-gcloud כדי לבצע SSH ישירות למכונות הצרכן.

לאחר מכן ניצור שער Cloud NAT פשוט במצב הקצאה ידנית, ואת הכתובת השמורה nat-address-1 שמשויכת אליו. בחלקים הבאים של ה-codelab, נעדכן את ההגדרה של השער כדי להפעיל הקצאת יציאות דינמית, ומאוחר יותר נוסיף כללים מותאמים אישית.

קודם ניצור את ה-VPC. מתוך Cloud Shell:

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

פלט:

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

בשלב הבא, ניצור רשת משנה באזור us-east4. מתוך Cloud Shell:

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

פלט:

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

בשלב הבא, ניצור כללים בחומת האש של ה-VPC כדי לאפשר לכתובות בטווח IAP להגיע למכונות הצרכן ביציאה 22.

כדי ליצור את כלל חומת האש הראשון, מריצים את הפקודה הבאה מ-Cloud Shell:

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

פלט:

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

לפני שיוצרים שער NAT, צריך ליצור קודם מופע של Cloud Router (אנחנו משתמשים במספר ASN פרטי, אבל הוא לא רלוונטי לפעילויות במעבדה הזו). מתוך Cloud Shell:

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

פלט:

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

לאחר מכן יוצרים את מופע שער ה-NAT. מתוך 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

פלט:

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

שימו לב: כברירת מחדל, שער Cloud NAT נוצר עם minPortsPerVm שמוגדר ל-64

יוצרים את מופעי הבדיקה של הצרכנים. אנחנו מאכלסים כאן את כתובות ה-IP השמורות של המפיק כדי שנוכל להתייחס אליהן במופע מאוחר יותר. מתוך 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

פלט:

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. אימות התנהגות ברירת המחדל של Cloud NAT

בשלב הזה, המופעים של הלקוח משתמשים בהתנהגות ברירת המחדל של Cloud NAT, שבה נעשה שימוש באותה כתובת IP שמורה nat-address-1 לתקשורת עם כל הכתובות החיצוניות. בנוסף, עדיין לא הופעל DPA ב-Cloud NAT.

כדי לוודא אילו יציאות הוקצו למופעי הצרכן שלנו ב-Cloud NAT, מריצים את הפקודה הבאה

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

פלט לדוגמה

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

כפי שאפשר לראות בפלט שלמעלה, ‏Cloud NAT הקצה 64 יציאות לכל מכונה מאותה כתובת IP חיצונית nat-address-1

לפני שמפעילים את DPA, כדאי לבדוק כמה חיבורים אפשר לפתוח במקביל.

מתחברים באמצעות SSH למופע הצרכן הראשון. מתוך Cloud Shell:

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

עכשיו אתם אמורים להיות במעטפת של המופע.

פלט לדוגמה (פלט מלא שקוצר לצורך נוחות)

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

מתוך מופע הצרכן, קודם צריך לאחזר את כתובות ה-IP של היצרן ולאכלס אותן כמשתני סביבה

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

לאחר מכן, מנסים להשתמש בפקודה curl בשני מופעי ה-producer כדי לוודא שאפשר להגיע אליהם בהצלחה.

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

עכשיו ננסה ליצור הרבה חיבורים מקבילים לאחד ממופעי היצרן על ידי הפעלת curl דרך לולאה. כדאי לזכור ש-Cloud NAT לא מאפשר שימוש חוזר בשקעים סגורים למשך 2 דקות. לכן, כל עוד אנחנו יכולים לעבור על כל ניסיונות החיבור תוך 2 דקות, אנחנו יכולים לדמות חיבורים מקבילים בדרך הזו.

מריצים את הפקודה הבאה בסשן ה-SSH של המופע

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

הייתם מצפים לפתוח בהצלחה 64 חיבורים מקבילים, והסקריפט אמור להדפיס את הפלט הבא

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

כדי לראות שלא ניתן לחרוג מ-64 חיבורים מקבילים, צריך קודם לחכות 2 דקות כדי לאפשר לכל השקעים הישנים להתפנות. לאחר מכן משנים את הפקודה בשורה אחת כך שתיראה כמו הפקודה הבאה ומריצים אותה מחדש

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

הפלט הבא אמור להתקבל:

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

המשמעות היא ש-64 החיבורים הראשונים הצליחו, אבל 6 החיבורים הנותרים נכשלו כי היציאות לא היו זמינות.

במקרה כזה, צריך לצאת ממעטפת ה-SSH ולהפעיל את DPA בקטע הבא.

8. הפעלת DPA ואימות ההתנהגות שלו

מריצים את הפקודה הבאה ב-gcloud, שמפעילה את DPA, מגדירה את הקצאת היציאות המינימלית לכל מכונה וירטואלית ל-64 ואת הקצאת היציאות המקסימלית ל-1, 024.

gcloud alpha compute routers nats update consumer-nat-gw --router=consumer-cr \
--region=us-east4 --min-ports-per-vm=64 --max-ports-per-vm=1024 \
--enable-dynamic-port-allocation

שמפיק את הפלט הבא

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

עכשיו נריץ מחדש את get-nat-mapping-info כדי לוודא שבשתי המכונות עדיין מוקצים רק 64 פורטים

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

פלט לדוגמה (חלק מהפלט הושמט כדי שהדוגמה תהיה קצרה יותר)

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

לא חלו הרבה שינויים בהקצאות של יציאות, כי המופע עדיין לא משתמש באופן פעיל באף יציאה.

נחזור למכונה באמצעות SSH:

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

מייצאים מחדש את משתני הסביבה של כתובות ה-IP של היצרן.

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

ומריצים מחדש את הלולאה הקודמת כדי לדמות חיבורים מקבילים:

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

עכשיו אמור להופיע הפלט הבא

Connection # 64 successful
Connection # 65 failed

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

אז מה קרה כאן? הקצאת היציאות ב-Cloud NAT מתגברת עם העלייה בשימוש ביציאות, אבל לוקח זמן לתכנת את זה בשכבת הרשת. לכן אנחנו רואים 1-3 פסק זמן לחיבור לפני שאנחנו משלימים בהצלחה את שאר ניסיונות החיבור.

הגדרנו זמן קצוב לתפוגה אגרסיבי ל-curl (5 שניות), אבל אפליקציות עם זמן קצוב לתפוגה ארוך יותר אמורות להצליח להשלים את החיבורים בזמן שהקצאות הפורטים גדלות.

התנהגות ההגדלה הזו נראית בצורה ברורה יותר כשמריצים את הלולאה ל-1,024 ניסיונות חיבור, כמו בדוגמה הבאה

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

עכשיו אנחנו מצפים לראות את הפלט הבא

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 מקצה יציאות בחזקות של 2, כלומר מכפיל את ההקצאות בכל שלב, אנחנו רואים את פסק הזמן של החיבורים מודגש סביב החזקות של 2 בין 64 ל-1024.

מכיוון שהגדרנו את maxPortsPerVM ל-1024, אנחנו לא מצפים שנוכל להגיע ליותר מ-1024 חיבורים. כדי לבדוק את זה, אפשר להריץ מחדש את לולאת curl עם מספר גבוה מ-1,024 (אחרי שמחכים 2 דקות כדי לאפס יציאות לא פעילות).

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

וכצפוי, בפלט מוצגים חיבורים מעל 1024 שמתחילים להיכשל

<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

הגדרנו את maxPortsPerVM ל-1024, ולכן Cloud NAT לא יקצה יותר מ-1024 יציאות לכל מכונה וירטואלית.

אם נצא מסשן ה-SSH ונריץ את הפקודה get-nat-mapping-info מספיק מהר, נוכל לראות את היציאות הנוספות שהוקצו

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

הפלט הבא יוצג

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

שימו לב של-consumer-instance-1 הוקצו 1,024 יציאות, אבל ל-consumer-instance-2 הוקצו רק 64 יציאות. לפני DPA, לא הייתה אפשרות כזו בקלות, והיא ממחישה בדיוק את העוצמה של DPA עבור Cloud NAT.

אם תחכו 2 דקות לפני שתריצו מחדש את הפקודה get-nat-mapping-info, תראו ש-consumer-instance-1 חזר לערך המינימלי שלו, כלומר הוקצו רק 64 יציאות. הדוגמה הזו ממחישה לא רק את היכולת של DPA להגדיל את הקצאות היציאות, אלא גם את היכולת לשחרר אותן כשהן לא בשימוש, כדי שמופעים אחרים מאחורי אותו שער NAT יוכלו להשתמש בהן.

9. בדיקת כללי Cloud NAT באמצעות DPA

לאחרונה השקנו גם את הפונקציונליות של כללי NAT ב-Cloud NAT, שמאפשרת ללקוחות לכתוב כללים שמשתמשים בכתובות IP ספציפיות של NAT ליעדים חיצוניים מסוימים. מידע נוסף מופיע בדף התיעוד בנושא כללי NAT.

בתרגיל הזה נבחן את האינטראקציה בין DPA לבין כללי NAT. קודם נגדיר כלל NAT לשימוש ב-nat-address-2 כשניגשים ל-producer-address-2.

מריצים את הפקודה הבאה ב-gcloud, שיוצרת את כלל ה-NAT באמצעות

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

הפלט הבא אמור להתקבל

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

עכשיו נריץ מחדש את get-nat-mapping-info כדי לראות את ההשפעה של כלל ה-NAT החדש.

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

הפלט שמתקבל הוא

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

שימו לב שעכשיו יש לנו הקצאה של יציאות נוספות (גם ב-64, המינימום שצוין) במיוחד עבור nat-address-2 בהיררכיה של ruleMappings.

אז מה קורה אם מופעלים הרבה חיבורים לכתובת היעד שצוינה בכלל ה-NAT? בואו נגלה.

נחזור למכונה באמצעות SSH:

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

מייצאים מחדש את משתני הסביבה של כתובות ה-IP של היצרן.

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

עכשיו נריץ מחדש את לולאת curl מול 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

הפלט שיתקבל אמור להיות דומה לזה שמופיע בהמשך

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

בעצם משקף את הבדיקה הקודמת. נצא מסשן ה-SSH של המופע ונבדוק שוב את מיפויי ה-NAT.

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

הפלט שמתקבל הוא

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

כפי שאפשר לראות למעלה, לכתובת ה-IP של NAT שמוגדרת כברירת מחדל ב-consumer-instance-1 ( כתובת ה-IP של nat-address-1) עדיין מוקצים רק 64 פורטים, אבל לכתובת ה-IP של כלל NAT (כתובת ה-IP של nat-address-2) מוקצים 1,024 פורטים. במהלך התהליך, consumer-instance-2 שמר על הקצאות ברירת המחדל של 64 יציאות לכל כתובות ה-IP של NAT.

כדי להתאמן, אפשר לבדוק את המקרה ההפוך. מאפשרים ל-Cloud NAT לבטל את ההקצאה של כל היציאות הנוספות, ואז מריצים את לולאת curl מול producerip1 ומתבוננים בהשפעות על הפלט של get-nat-mapping-info

10. שלבים לניקוי נתונים

כדי להימנע מחיובים חוזרים, מומלץ למחוק את כל המשאבים שמשויכים ל-codelab הזה.

קודם צריך למחוק את כל המופעים.

מתוך Cloud Shell:

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

הפלט הצפוי :

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

לאחר מכן מוחקים את Cloud Router. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

משחררים את כל כתובות ה-IP החיצוניות. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

מחיקת כללים של חומת אש ב-VPC. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

מחיקת תת-רשתות. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

לבסוף, נמחק את רשתות ה-VPC. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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. מעולה!

השלמת את שיעור ה-Lab בנושא Cloud NAT DPA!

מה כיסיתם

  • איך מגדירים שער Cloud NAT לקראת DPA.
  • איך בודקים הקצאות של ניוד בלי DPA.
  • איך מפעילים ומגדירים DPA לשער NAT.
  • איך בודקים את ההשפעות של DPA על ידי הפעלת חיבורים מקבילים ליציאה.
  • איך מוסיפים כללי NAT ל-NAT Gateway עם DPA מופעל.
  • כדי לראות את ההתנהגות של DPA עם כללים, מריצים חיבורי יציאה לכמה יעדים.

השלבים הבאים

‫©Google, Inc. או השותפים העצמאיים שלה. כל הזכויות שמורות. אין להפיץ.