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

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

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

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

למידע נוסף, אפשר לעיין בקטע מסמכי התיעוד בנושא NAT DPA .

מה תלמדו

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

למה תזדקק?

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

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

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

מסוף Google Cloud

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

75eef5f6fd6d7e41.png

הגדרת סביבה בקצב עצמאי

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

הפעלת Cloud Shell

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

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

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

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

3. הגדרה של שיעור Lab

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

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

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

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

המכונות של היצרן יפעילו פריסה פשוטה של שרת 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 ואת רשת המשנה, נוסיף כלל פשוט של חומת אש לתעבורת נתונים נכנסת (ingress) כדי לאפשר את ה-IAP עבור טווחי IP של מקורות TCP. כך נוכל לבצע SSH למכונות לצרכנים ישירות באמצעות gcloud.

לאחר מכן ניצור שער 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 פרטי אבל הוא לא רלוונטי לפעילויות של שיעור ה-Lab הזה). מ-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' לתקשורת עם כל הכתובות החיצוניות. ב-Cloud NAT גם לא הופעל עדיין DPA.

עכשיו כדאי לאמת אילו יציאות 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"`

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

<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, ואת הקצאת היציאות המקסימלית ל-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

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

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, לא נוכל לצפות ליותר מ-1,024 חיבורים. נוכל לבדוק זאת על ידי הרצה מחדש של לולאת ה-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 אף פעם לא להתאים את הקצאות היציאות מעבר ל-1,024 לכל מכונה וירטואלית.

אם נצא מסשן ה-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 ב-Cloud NAT.

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

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

כמו שאפשר לראות למעלה, ל-NAT IP של 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.
  • איך חשוב לשים לב להשפעות של הרשות להגנה על מידע על ידי הפעלה של חיבורי תעבורת נתונים יוצאת (egress) מקבילים.
  • איך מוסיפים כללי NAT לשער NAT כאשר DPA מופעל.
  • איך להציג את ההתנהגות של הרשות להגנה על מידע עם כללים על ידי הרצת חיבורי תעבורת נתונים יוצאת (egress) ליעדים מרובים.

השלבים הבאים

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