Sử dụng tính năng Phân bổ cổng động Cloud NAT

1. Tổng quan

Phân bổ cổng động (DPA) là một tính năng mới trong Cloud NAT. Khi bật DPA, Cloud NAT tự động tăng/giảm tỷ lệ phân bổ cổng cho các thực thể tuỳ theo nhu cầu. DPA được định cấu hình theo giới hạn cổng tối thiểu và tối đa để không bao giờ giảm số lượng cổng xuống dưới mức tối thiểu hoặc mở rộng quá mức tối đa. Điều này cho phép một số phiên bản đứng sau cổng NAT chủ động tăng số lượng kết nối mà không cần phải phân bổ thêm cổng cho tất cả các phiên bản phía sau Cloud NAT.

Nếu không có DPA, mọi thực thể phía sau Cloud NAT đều được phân bổ cùng số lượng cổng, bất kể mức sử dụng, như được xác định theo tham số minPortsPerVm .

Để biết thêm thông tin, vui lòng xem mục Tài liệu về NAT DPA .

Kiến thức bạn sẽ học được

  • Cách thiết lập cổng vào Cloud NAT để chuẩn bị cho DPA.
  • Cách kiểm tra quá trình phân bổ cổng mà không cần DPA.
  • Cách bật và định cấu hình DPA cho cổng NAT.
  • Cách quan sát ảnh hưởng của DPA bằng cách chạy các kết nối đầu ra song song.
  • Cách thêm các quy tắc NAT vào NAT Gateway khi bật DPA.
  • Cách xem hành vi của DPA với các Quy tắc bằng cách chạy các kết nối đầu ra đến nhiều đích đến.

Bạn cần có

  • Kiến thức cơ bản về Google Compute Engine
  • Kiến thức cơ bản về mạng và TCP/IP
  • Kiến thức cơ bản về dòng lệnh Unix/Linux
  • Bạn sẽ thấy hữu ích khi hoàn thành chuyến tham quan về mạng lưới trong Google Cloud, chẳng hạn như phòng thí nghiệm Kết nối mạng trong Google Cloud.
  • Một dự án Google Cloud có "Quyền truy cập alpha" bật.
  • Hiểu biết về Kiến thức cơ bản về Cloud NAT.

2. Sử dụng Google Cloud Console và Cloud Shell

Để tương tác với GCP, chúng ta sẽ sử dụng cả Google Cloud Console và Cloud Shell trong phòng thí nghiệm này.

Bảng điều khiển Google Cloud

Bạn có thể truy cập vào Cloud Console tại https://console.cloud.google.com.

75eef5f6fd6d7e41.pngS

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

96a9c957bc475304.pngs

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng và bạn có thể cập nhật chuỗi này bất cứ lúc nào.
  • Mã dự án phải là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này sau khi đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (và mã này thường được xác định là PROJECT_ID). Vì vậy, nếu không thích, bạn có thể tạo một mã ngẫu nhiên khác hoặc bạn có thể thử mã của riêng mình để xem có mã này chưa. Sau đó, video sẽ được "đóng băng" sau khi tạo dự án.
  • Có giá trị thứ ba là Project Number (Số dự án) mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
  1. Tiếp theo, bạn sẽ cần bật tính năng thanh toán trong Cloud Console để sử dụng tài nguyên/API trên Cloud. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên để bạn không phải chịu thanh toán ngoài hướng dẫn này, hãy làm theo mọi thao tác "dọn dẹp" hướng dẫn ở cuối lớp học lập trình. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Khởi động Cloud Shell

Mặc dù bạn có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trong Đám mây.

Trong Bảng điều khiển GCP, hãy nhấp vào biểu tượng Cloud Shell ở thanh công cụ trên cùng bên phải:

bce75f34b2c53987.png

Sẽ chỉ mất một chút thời gian để cấp phép và kết nối với môi trường. Sau khi hoàn tất, bạn sẽ thấy như sau:

f6ef2b5f13479f3a.png

Máy ảo này chứa tất cả các công cụ phát triển mà bạn cần. Phiên bản này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Bạn có thể thực hiện tất cả công việc trong phòng thí nghiệm này chỉ bằng một trình duyệt.

3. Thiết lập phòng thí nghiệm

Đối với phòng thí nghiệm này, bạn sẽ sử dụng một Dự án rồi tạo 2 VPC, mỗi VPC có một mạng con. Bạn sẽ đặt trước địa chỉ IP bên ngoài, sau đó tạo và định cấu hình cổng vào Cloud NAT (có Cloud Router), 2 thực thể thực thể sản xuất và 2 thực thể người dùng. Sau khi xác thực hành vi Cloud NAT mặc định, bạn sẽ bật tính năng Phân bổ cổng động và xác thực hành vi của nó. Cuối cùng, bạn cũng sẽ định cấu hình các quy tắc NAT và quan sát sự tương tác giữa DPA và NAT.

Tổng quan về cấu trúc mạng:

a21caa6c333909d8.png

4. Đặt trước địa chỉ IP bên ngoài

Hãy giữ lại tất cả địa chỉ IP bên ngoài sẽ được sử dụng trong phòng thí nghiệm này. Việc này sẽ giúp bạn viết tất cả các quy tắc NAT và tường lửa có liên quan trong VPC của cả người tiêu dùng và nhà sản xuất.

Từ Cloud Shell:

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

Kết quả:

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

Điền các địa chỉ IP đã được đặt trước dưới dạng biến môi trường.

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

Kết quả dự kiến sẽ không xuất hiện, nhưng cần xác nhận rằng các địa chỉ đã được điền đúng cách. Hãy nhập giá trị của tất cả biến môi trường.

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

Kết quả:

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

5. Thiết lập VPC và các phiên bản của nhà sản xuất.

Bây giờ, chúng ta sẽ tạo tài nguyên cho tài nguyên nhà sản xuất. Các thực thể chạy trong VPC của nhà sản xuất sẽ cung cấp dịch vụ kết nối Internet bằng cách sử dụng 2 IP công khai "nhà sản xuất-địa chỉ-1" và "nhà sản xuất-địa chỉ-2" của Google.

Trước tiên, hãy tạo VPC. Từ Cloud Shell:

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

Kết quả:

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

Tiếp theo, hãy tạo mạng con trong us-east4. Từ Cloud Shell:

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

Kết quả:

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

Tiếp theo, hãy tạo các quy tắc tường lửa VPC để cho phép địa chỉ IP NAT kết nối với thực thể sản xuất trên cổng 8080.

Đối với quy tắc đầu tiên của Cloud Shell:

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

Kết quả:

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

Bước tiếp theo là tạo 2 thực thể thực thể sản xuất.

Các thực thể sản xuất sẽ chạy một quá trình triển khai proxy nginx đơn giản.

Để nhanh chóng cung cấp các phiên bản có tất cả phần mềm cần thiết, chúng ta sẽ tạo các phiên bản có tập lệnh khởi động có chức năng cài đặt nginx bằng trình quản lý gói Debian APT.

Để có thể viết các quy tắc NAT, chúng ta sẽ cung cấp cho mỗi thực thể một địa chỉ IP dành riêng khác nhau.

Tạo thực thể đầu tiên. Từ 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"

Kết quả:

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

Sau đó, tạo thực thể thứ hai. Từ 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"

Kết quả:

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. Thiết lập VPC của người tiêu dùng, Cloud NAT và các phiên bản

Giờ đây, khi bạn đã tạo dịch vụ nhà sản xuất, đã đến lúc tạo VPC dành cho người tiêu dùng và cổng Cloud NAT.

Sau khi tạo VPC và mạng con, chúng ta sẽ thêm một quy tắc tường lửa vào đơn giản để cho phép IAP cho dải IP nguồn TCP. Việc này sẽ cho phép chúng tôi kết nối SSH trực tiếp đến các thực thể người dùng thông qua gcloud.

Sau đó chúng ta sẽ tạo một cổng Cloud NAT đơn giản ở chế độ phân bổ thủ công và địa chỉ dành riêng "nat-address-1" liên kết với cuộc trò chuyện đó. Trong các phần tiếp theo của lớp học lập trình, chúng ta sẽ cập nhật cấu hình của cổng vào để bật tính năng Phân bổ cổng động, sau đó thêm các quy tắc tuỳ chỉnh.

Trước tiên, hãy tạo VPC. Từ Cloud Shell:

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

Kết quả:

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

Tiếp theo, hãy tạo một mạng con trong us-east4. Từ Cloud Shell:

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

Kết quả:

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

Tiếp theo, hãy tạo một quy tắc tường lửa VPC để cho phép các địa chỉ dải IAP kết nối đến các thực thể người tiêu dùng trên cổng 22.

Đối với quy tắc tường lửa đầu tiên, hãy chạy lệnh sau đây từ Cloud Shell:

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

Kết quả:

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

Trước khi tạo cổng NAT, trước tiên chúng ta cần tạo một thực thể Cloud Router (chúng ta sử dụng số ASN riêng tư nhưng số đó không liên quan đến các hoạt động của phòng thí nghiệm này). Từ Cloud Shell:

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

Kết quả:

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

Sau đó, tạo phiên bản cổng NAT. Từ 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

Kết quả:

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

Xin lưu ý rằng theo mặc định, cổng vào Cloud NAT được tạo với minPortsPerVm được đặt thành 64

Tạo các thực thể kiểm thử thực thể tiêu dùng. Chúng tôi điền sẵn các IP nhà sản xuất được đặt trước vào đây để có thể tham chiếu đến chúng trong thực thể sau này. Từ 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

Kết quả:

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. Xác minh hành vi Cloud NAT mặc định

Tại thời điểm này, các thực thể tiêu dùng sử dụng hành vi Cloud NAT mặc định sử dụng cùng một IP "nat-address-1" dành riêng để giao tiếp với tất cả địa chỉ bên ngoài. Cloud NAT cũng chưa bật DPA.

Hãy xác thực những cổng mà Cloud NAT đã phân bổ cho các thực thể người dùng bằng cách chạy lệnh sau

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

Kết quả đầu ra mẫu

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

Như bạn có thể thấy từ kết quả ở trên, Cloud NAT đã phân bổ 64 cổng cho mỗi đối tượng từ cùng một IP bên ngoài nat-address-1

Hãy xác thực số lượng đường kết nối chúng ta có thể mở song song trước khi bật DPA.

SSH vào phiên bản người dùng đầu tiên. Từ Cloud Shell:

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

Bây giờ, bạn sẽ ở trong môi trường shell thực thể.

Kết quả mẫu (toàn bộ kết quả được cắt ngắn để rút ngắn)

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

Trong thực thể của người dùng, trước tiên, hãy tìm nạp cả hai IP của nhà sản xuất và điền chúng dưới dạng biến môi trường

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

Sau đó, hãy thử cuộn cả hai thực thể thực thể sản xuất để đảm bảo chúng ta có thể truy cập thành công.

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

Bây giờ, hãy thử tạo nhiều kết nối song song với một trong các thực thể thực thể sản xuất bằng cách chạy curl qua một vòng lặp. Hãy nhớ rằng Cloud NAT không cho phép tái sử dụng ổ cắm đã đóng trong vòng 2 phút. Do đó, miễn là có thể lặp lại tất cả các nỗ lực kết nối trong vòng 2 phút, chúng tôi có thể mô phỏng các kết nối song song theo cách này.

Chạy lệnh sau trong phiên SSH của thực thể

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

Bạn sẽ có thể mở 64 kết nối song song thành công và tập lệnh sẽ in ra nội dung sau

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

Để thấy rằng chúng ta không thể kết nối vượt quá 64 kết nối song song, trước tiên hãy đợi 2 phút để cho phép xoá tất cả các ổ cắm cũ. Sau đó, hãy tinh chỉnh cùng một đoạn mã với đoạn mã sau và chạy lại

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

Giờ đây, bạn sẽ nhận được kết quả sau

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

Điều này cho thấy rằng mặc dù 64 kết nối đầu tiên thành công, 6 kết nối còn lại không thành công do không có cổng.

Hãy làm gì đó để giải quyết vấn đề này, thoát khỏi shell SSH và bật DPA trong bước sau.

8. Bật DPA và xác thực hành vi của DPA

Chạy lệnh gcloud sau đây để bật DPA, đặt mức phân bổ cổng tối thiểu cho mỗi máy ảo thành 64 và mức phân bổ cổng tối đa là 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

Kết quả nào sau đây

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

Bây giờ, hãy chạy lại get-nat-mapping-info để xác nhận cả hai phiên bản vẫn chỉ phân bổ 64 cổng

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

Kết quả mẫu (được cắt ngắn để ngắn gọn)

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

Không có nhiều thay đổi về việc phân bổ cổng vì thực thể này chưa chủ động sử dụng bất kỳ cổng nào.

Hãy tạo SSH lại phiên bản này:

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

Xuất lại các biến môi trường IP của nhà sản xuất.

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

Và chạy lại vòng lặp trước đó để mô phỏng các kết nối song song:

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

Bây giờ, chúng ta sẽ thấy kết quả sau

Connection # 64 successful
Connection # 65 failed

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

Vậy điều gì đã xảy ra ở đây? Cloud NAT chuyển sang phân bổ cổng khi mức sử dụng cổng tăng lên, nhưng quá trình này mất chút thời gian để được lập trình qua lớp kết nối mạng. Do đó, chúng ta thấy hết thời gian chờ kết nối 1-3 trước khi hoàn tất thành công các lần kết nối còn lại.

Chúng tôi đã chỉ định thời gian chờ linh hoạt cho curl (5 giây) nhưng các ứng dụng có thời gian chờ dài hơn có thể hoàn tất thành công các kết nối trong khi DPA (cơ quan bảo vệ dữ liệu) đang tăng mức phân bổ cổng.

Hành vi tăng dần này có thể được nhìn thấy rõ hơn khi chúng ta chạy vòng lặp cho 1024 nỗ lực kết nối như vậy

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

Bây giờ, chúng tôi hy vọng sẽ thấy kết quả sau đây

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

Do Cloud NAT phân bổ các cổng theo nguồn 2, về cơ bản là tăng gấp đôi phân bổ trong mỗi bước, chúng ta thấy thời gian chờ kết nối được tô sáng xung quanh luỹ thừa của 2 trong khoảng từ 64 đến 1024.

Vì chúng ta đặt maxPortsPerVM thành 1024, nên chúng ta không thể có nhiều hơn 1024 kết nối. Chúng ta có thể kiểm tra điều đó bằng cách chạy lại vòng lặp curl với số lượng cao hơn 1024 (sau khi đợi 2 phút để đặt lại các cổng cũ).

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

Và đúng như mong đợi, kết quả cho thấy các kết nối sau thời gian 1024 bắt đầu không thành công

<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

Bằng cách đặt maxPortsPerVM thành 1024, chúng tôi đã hướng dẫn Cloud NAT không bao giờ mở rộng quy mô phân bổ cổng vượt quá 1024 cho mỗi máy ảo.

Nếu thoát khỏi phiên SSH và chạy lại get-nat-mapping-info đủ nhanh, chúng ta có thể thấy các cổng bổ sung đã phân bổ

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

Và quan sát kết quả sau

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

Hãy lưu ý cách consumer-instance-1 được phân bổ 1024 cổng, nhưng consumer-instance-2 chỉ được phân bổ 64 cổng. Điều này không dễ thực hiện được trước khi có DPA và nêu bật chính xác sức mạnh của DPA đối với Cloud NAT.

Nếu đợi 2 phút rồi mới chạy lại lệnh get-nat-mapping-info, bạn sẽ thấy consumer-instance-1 quay lại giá trị tối thiểu chỉ là 64 cổng được phân bổ. Minh hoạ không chỉ khả năng của DPA trong việc tăng khả năng phân bổ cổng mà còn giải phóng các cổng đó khi không sử dụng được cho các thực thể khác trong cùng một Cổng NAT.

9. Kiểm thử quy tắc Cloud NAT bằng DPA

Gần đây, chúng tôi cũng đã phát hành chức năng quy tắc NAT cho Cloud NAT, cho phép khách hàng viết các quy tắc có sử dụng IP NAT cụ thể cho một số đích đến bên ngoài nhất định. Để biết thêm thông tin, vui lòng tham khảo trang tài liệu về Quy tắc NAT.

Trong bài tập này, chúng tôi quan sát sự tương tác giữa DPA và NAT. Trước tiên, hãy xác định quy tắc NAT để sử dụng nat-address-2 khi truy cập producer-address-2.

Chạy lệnh gcloud sau đây để tạo quy tắc NAT bằng cách sử dụng

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

Bạn sẽ nhận được kết quả sau

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

Bây giờ, hãy chạy lại get-nat-mapping-info để xem hiệu quả của quy tắc NAT mới.

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

Điều gì sẽ cho ra kết quả sau

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

Xin lưu ý rằng hiện chúng ta đã phân bổ các cổng bổ sung (cũng ở mức 64, mức tối thiểu được chỉ định) dành riêng cho nat-address-2 trong hệ phân cấp ruleMappings.

Vậy điều gì sẽ xảy ra nếu một thực thể mở nhiều kết nối đến đích được chỉ định theo quy tắc NAT? Hãy cùng tìm hiểu.

Hãy tạo SSH lại phiên bản này:

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

Xuất lại các biến môi trường IP của trình tạo.

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

Bây giờ, hãy chạy lại vòng lặp dựa trên producerip2 lần này

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

Bạn sẽ nhận được kết quả tương tự như sau

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

Về cơ bản, phản chiếu hoạt động kiểm thử trước đó. Hãy thoát khỏi phiên SSH của thực thể đó và xem lại mối liên kết nat.

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

Điều gì sẽ cho ra kết quả sau

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

Như bạn có thể quan sát ở trên, IP NAT mặc định của consumer-instance-1 ( IP cho nat-address-1) vẫn chỉ có 64 cổng được phân bổ, nhưng IP của quy tắc NAT (IP cho nat-address-2) có 1024 cổng được phân bổ. Trong khi đó, consumer-instance-2 vẫn giữ nguyên cơ cấu phân bổ 64 cổng mặc định cho tất cả IP NAT.

Như một bài tập, bạn có thể kiểm thử trường hợp ngược. Để Cloud NAT phân bổ tất cả các cổng bổ sung, sau đó chạy vòng lặp curl dựa trên producerip1 và quan sát các hiệu ứng đối với dữ liệu đầu ra của get-nat-mapping-info

10. Các bước dọn dẹp

Để tránh các khoản phí định kỳ, bạn nên xoá tất cả tài nguyên liên kết với lớp học lập trình này.

Trước tiên, hãy xoá mọi phiên bản.

Từ Cloud Shell:

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

Kết quả đầu ra dự kiến :

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

Tiếp theo, hãy xoá Cloud Router. Từ Cloud Shell:

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

Bạn sẽ nhận được kết quả sau đây :

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

Huỷ bỏ tất cả địa chỉ IP bên ngoài. Từ Cloud Shell:

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

Bạn sẽ nhận được kết quả sau đây :

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

Xoá các quy tắc tường lửa VPC. Từ Cloud Shell:

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

Bạn sẽ nhận được kết quả sau đây :

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

Xoá mạng con. Từ Cloud Shell:

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

Bạn sẽ nhận được kết quả sau đây :

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

Cuối cùng, hãy xoá các VPC. Từ Cloud Shell:

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

Bạn sẽ nhận được kết quả sau đây :

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. Xin chúc mừng!

Bạn đã hoàn thành Phòng thí nghiệm Cloud NAT DPA!

Nội dung bạn đã đề cập

  • Cách thiết lập cổng vào Cloud NAT để chuẩn bị cho DPA.
  • Cách kiểm tra quá trình phân bổ cổng mà không cần DPA.
  • Cách bật và định cấu hình DPA cho cổng NAT.
  • Cách quan sát ảnh hưởng của DPA bằng cách chạy các kết nối đầu ra song song.
  • Cách thêm các quy tắc NAT vào NAT Gateway khi bật DPA.
  • Cách xem hành vi của DPA với các Quy tắc bằng cách chạy các kết nối đầu ra đến nhiều đích đến.

Bước tiếp theo

©Google, Inc. hoặc các đơn vị liên kết của Google. Bảo lưu mọi quyền. Không được phân phối.