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ạn bật DPA, Cloud NAT sẽ tự động tăng/giảm số lượng cổng được phân bổ cho các phiên bản tuỳ theo nhu cầu của chúng. DPA được định cấu hình với 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 tăng lên quá mức tối đa. Điều này cho phép một số phiên bản đằng sau các cổng NAT tự động tăng số lượng kết nối mà không cần phân bổ thêm cổng cho tất cả các phiên bản đằng sau Cloud NAT.

Nếu không có DPA, tất cả các phiên bản đằng sau Cloud NAT sẽ được phân bổ cùng một số lượng cổng bất kể mức sử dụng, như được xác định bằng tham số minPortsPerVm .

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

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

  • Cách thiết lập một cổng NAT trên đám mây để chuẩn bị cho DPA.
  • Cách kiểm tra việc phân bổ cổng mà không cần DPA.
  • Cách bật và định cấu hình DPA cho một cổng NAT.
  • Cách quan sát hiệu ứng của DPA bằng cách chạy các kết nối truyền dữ liệu song song.
  • Cách thêm quy tắc NAT vào Cổng NAT có bật DPA.
  • Cách xem hành vi của DPA có Quy tắc bằng cách chạy các kết nối xuất dữ liệu đế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 nên hoàn tất một chuyến tham quan về mạng trong Google Cloud, chẳng hạn như phòng thí nghiệm Mạng trong Google Cloud.
  • Một dự án trên Google Cloud đã bật "Quyền truy cập Alpha".
  • Hiểu 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 suốt phòng thực hành 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.png

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một 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.png

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ự mà các API của Google không 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 trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. 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 (thường được xác định là PROJECT_ID). Vì vậy, nếu không thích mã này, bạn có thể tạo một mã ngẫu nhiên khác hoặc thử mã của riêng mình để xem mã đó có dùng được hay không. Sau đó, mã này sẽ "đóng băng" sau khi dự án được tạo.
  • Có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 giá trị này trong tài liệu.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi hướng dẫn này, hãy làm theo mọi hướng dẫn "dọn dẹp" ở 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í trị giá 300 USD.

Khởi động Cloud Shell

Mặc dù 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 trên Cloud.

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

bce75f34b2c53987.png

Quá trình này chỉ mất vài phút để cung cấp và kết nối với môi trường. Khi quá trình này kết thúc, bạn sẽ thấy như sau:

f6ef2b5f13479f3a.png

Máy ảo này được trang bị tất cả các công cụ phát triển mà bạn cần. Nó cung cấp một thư mục chính có dung lượng 5 GB và chạy trên Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Bạn chỉ cần một trình duyệt là có thể thực hiện mọi thao tác trong phòng thí nghiệm này.

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

Trong lớp học lập trình này, bạn sẽ sử dụng một Dự án và tạo 2 VPC có một mạng con trong mỗi VPC. Bạn sẽ đặt trước địa chỉ IP bên ngoài, sau đó tạo và định cấu hình một cổng Cloud NAT (với Cloud Router), 2 phiên bản nhà sản xuất cũng như 2 phiên bản 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 tính năng này. 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à các quy tắc NAT.

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

a21caa6c333909d8.png

4. Dành riêng địa chỉ IP ngoài

Hãy dành riêng tất cả địa chỉ IP ngoài để sử dụng trong phòng thí nghiệm này. Điều 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 cả VPC của người dùng và nhà sản xuất.

Trong 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 sẵ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)"`

Không có đầu ra nào được mong đợi, nhưng để xác nhận rằng các địa chỉ đã được điền đúng cách. Hãy xuất các giá trị của tất cả cá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 các tài nguyên cho tài nguyên của nhà sản xuất. Các phiên bản đang chạy trong VPC của nhà sản xuất sẽ cung cấp dịch vụ hướng đến Internet bằng cách sử dụng hai IP công khai "producer-address-1" và "producer-address-2" .

Trước tiên, hãy tạo VPC. Trong 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. Trong 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 về tường lửa VPC để cho phép các địa chỉ IP NAT truy cập vào các phiên bản nhà sản xuất trên cổng 8080.

Đối với quy tắc đầu tiên, từ 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ể nhà sản xuất.

Các phiên bản nhà sản xuất sẽ chạy một quy 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 bằng một tập lệnh khởi độ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 tôi sẽ cung cấp cho mỗi phiên bản một địa chỉ IP dành riêng khác nhau.

Tạo phiên bản đầu tiên. Trong 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 đó, hãy tạo phiên bản thứ hai. Trong 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 người dùng, Cloud NAT và các phiên bản

Bây giờ bạn đã tạo dịch vụ nhà sản xuất, đã đến lúc tạo VPC người dùng và cổng Cloud NAT của VPC đó.

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

Sau đó, chúng ta sẽ tạo một cổng NAT trên đám mây đơn giản ở chế độ phân bổ thủ công và địa chỉ được đặt trước "nat-address-1" được liên kết với cổng này. 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 để bật tính năng Phân bổ cổng động và sau đó thêm các quy tắc tuỳ chỉnh.

Trước tiên, hãy tạo VPC. Trong 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. Trong 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 các quy tắc về tường lửa VPC để cho phép các địa chỉ trong dải IAP truy cập vào các phiên bản người 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 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 một cổng NAT, trước tiên, chúng ta cần tạo một phiên bản Cloud Router (Bộ định tuyến đám mây) (chúng ta sử dụng số ASN riêng tư nhưng số này không liên quan đến các hoạt động của phòng thí nghiệm này). Trong 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 đó, hãy tạo phiên bản cổng NAT. Trong 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 Cloud NAT được tạo với minPortsPerVm được đặt thành 64

Tạo các phiên bản kiểm thử dành cho người tiêu dùng. Chúng tôi điền sẵn các IP của nhà sản xuất được đặt trước tại đây để có thể tham khảo chúng trong phiên bản sau này. Trong 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 mặc định của Cloud NAT

Tại thời điểm này, các phiên bản người dùng sử dụng hành vi Cloud NAT mặc định, tức là sử dụng cùng một IP dành riêng "nat-address-1" để giao tiếp với tất cả cá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 phiên bản người dùng của chúng ta bằng cách chạy lệnh sau

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

Đoạn nhạc 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 trong kết quả ở trên, Cloud NAT đã phân bổ 64 cổng cho mỗi phiên bản từ cùng một IP bên ngoài nat-address-1

Hãy xác thực số lượng kết nối mà 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. Trong Cloud Shell:

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

Lúc này, bạn sẽ ở trong trình bao của phiên bản.

Đầu ra mẫu (đầu ra đầy đủ bị cắt bớt để ngắn gọn)

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

Từ phiên bản người dùng, trước tiên, hãy tìm nạp cả IP của nhà sản xuất và điền chúng dưới dạng các 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ử curl đến cả hai phiên bản producer để đả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 đến một trong các phiên bản nhà sản xuất bằng cách chạy curl thông qua một vòng lặp. Hãy nhớ rằng Cloud NAT không cho phép sử dụng lại các ổ cắm đã đóng trong 2 phút. Do đó, miễn là có thể lặp lại tất cả các lần kết nối trong vòng 2 phút, chúng ta 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 phiên bản

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 có thể mở thành công 64 kết nối song song 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

Để xem liệu chúng ta có thể vượt quá 64 kết nối song song hay không, trước tiên, hãy đợi 2 phút để tất cả các ổ cắm cũ được xoá. Sau đó, hãy điều chỉnh câu lệnh một dòng đó thành câu lệnh sau rồi 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

Bây giờ, bạn sẽ thấy 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 mặc dù 64 kết nối đầu tiên thành công, như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ì đó để khắc phục vấn đề này, thoát khỏi trình bao SSH và bật DPA trong phần 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 VM là 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ả sẽ như sau

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 rằng cả hai phiên bản vẫn chỉ có 64 cổng được phân bổ

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

Nội dung đầu ra mẫu (đã cắt bớt)

---
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ì phiên bản này chưa sử dụng bất kỳ cổng nào.

Hãy SSH trở lại phiên bản:

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 chuyện gì đã xảy ra ở đây? Cloud NAT tăng tốc phân bổ cổng khi mức sử dụng cổng tăng lên, nhưng cần một khoảng thời gian để lập trình trên toàn bộ lớp mạng. Do đó, chúng ta thấy 1-3 lần hết thời gian chờ kết nối trước khi hoàn tất thành công các lần thử kết nối còn lại.

Chúng tôi đã chỉ định thời gian chờ tối đa cho curl (5 giây), nhưng các ứng dụng có thời gian chờ lâu hơn sẽ có thể hoàn tất kết nối thành công trong khi DPA tăng số lượng cổng được phân bổ.

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

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

Giờ đây, chúng ta sẽ thấy kết quả 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ì Cloud NAT phân bổ các cổng theo luỹ thừa của 2, về cơ bản là tăng gấp đôi số lượng phân bổ trong mỗi bước, nên chúng ta thấy thời gian chờ kết nối được đánh dấu xung quanh các luỹ thừa của 2 trong khoảng từ 64 đến 1024.

Vì đã đặ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 lớn hơn 1024 (sau khi chờ 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à như dự kiến, đầu ra cho thấy các kết nối vượt quá 1024 bắt đầu gặp lỗi

<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 ta đã hướng dẫn Cloud NAT không bao giờ mở rộng việc phân bổ cổng vượt quá 1024 cổng cho mỗi VM.

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 được phân bổ thêm

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

Lưu ý rằng consumer-instance-1 có 1024 cổng được phân bổ, nhưng consumer-instance-2 chỉ có 64 cổng được phân bổ. Trước DPA, việc này không dễ thực hiện và chính xác cho thấy sức mạnh của DPA đối với Cloud NAT.

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

9. Kiểm thử quy tắc NAT trên đám mây 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 sử dụng IP NAT cụ thể cho một số đích đến bên ngoài. Để 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 ta sẽ quan sát sự tương tác giữa DPA và Quy tắc NAT. Trước tiên, hãy xác định một quy tắc NAT để sử dụng nat-address-2 khi truy cập vào 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ẽ thấy 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 ứng của quy tắc NAT mới.

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

Lệnh này sẽ xuất 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 tại, chúng ta đã phân bổ thêm các cổng (cũng ở mức tối thiểu được chỉ định là 64) 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 phiên bản mở nhiều kết nối đến đích đến do quy tắc NAT chỉ định? Hãy cùng tìm hiểu.

Hãy SSH trở lại phiên bản:

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

Bây giờ, hãy chạy lại vòng lặp curl đối với 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ẽ thấy 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, đây là bản sao của bài kiểm thử trước. Hãy thoát khỏi phiên SSH của phiên bản và xem lại các ánh xạ NAT.

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

Lệnh này sẽ xuất 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ể thấy ở 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 suốt thời gian đó, consumer-instance-2 vẫn giữ nguyên chế độ phân bổ mặc định là 64 cổng cho tất cả các IP NAT.

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

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

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

Trước tiên, hãy xoá tất cả các phiên bản.

Trong 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á Bộ định tuyến đám mây. Trong Cloud Shell:

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

Bạn sẽ thấy kết quả sau :

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

Giải phóng tất cả IP ngoài. Trong 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ẽ thấy kết quả sau :

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. Trong Cloud Shell:

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

Bạn sẽ thấy kết quả sau :

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. Trong Cloud Shell:

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

Bạn sẽ thấy kết quả sau :

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. Trong Cloud Shell:

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

Bạn sẽ thấy kết quả sau :

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 bài thực hành DPA của Cloud NAT!

Nội dung bạn đã học

  • Cách thiết lập một cổng NAT trên đám mây để chuẩn bị cho DPA.
  • Cách kiểm tra việc phân bổ cổng mà không cần DPA.
  • Cách bật và định cấu hình DPA cho một cổng NAT.
  • Cách quan sát hiệu ứng của DPA bằng cách chạy các kết nối truyền dữ liệu song song.
  • Cách thêm quy tắc NAT vào Cổng NAT có bật DPA.
  • Cách xem hành vi của DPA có Quy tắc bằng cách chạy các kết nối xuất dữ liệu đến nhiều đích đến.

Các 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.