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.

Thiết lập môi trường theo tốc độ của riêng bạn
- Đă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.



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

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:

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:

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
- Duyệt xem trang tài liệu về tính năng Phân bổ cổng động
- Thử nghiệm điều chỉnh thời gian chờ NAT và giá trị phân bổ cổng bằng ứng dụng của bạn.
- Tìm hiểu thêm về Mạng trên Google Cloud Platform
©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.