Kết Nối Hai VPC Bằng VPC Peering: Hướng Dẫn Cấu Hình Route Table Thực Tế
Bạn có hai VPC trong cùng một tài khoản và region, và cần cho phép các instance giao tiếp với nhau qua private IP mà không đi ra ngoài internet — đây là bài toán xuất hiện thường xuyên khi tách biệt môi trường (ví dụ: shared-services VPC chứa database cluster, app VPC chứa workload). VPC Peering là cơ chế native của AWS giải quyết đúng vấn đề này, nhưng phần dễ bỏ sót nhất không phải là tạo peering connection — mà là cập nhật route table và security group sau đó.
TL;DR — Kết Nối VPC Peering Nhanh
| Bước | Hành động | Công cụ |
|---|---|---|
| 1 | Tạo VPC Peering Connection | AWS CLI / Console |
| 2 | Chấp nhận Peering Request | AWS CLI / Console |
| 3 | Cập nhật Route Table của VPC-A trỏ đến CIDR của VPC-B | AWS CLI |
| 4 | Cập nhật Route Table của VPC-B trỏ đến CIDR của VPC-A | AWS CLI |
| 5 | Cập nhật Security Group cho phép traffic từ CIDR đối diện | AWS CLI |
| 6 | Kiểm tra kết nối end-to-end | ping / curl / VPC Reachability Analyzer |
VPC Peering Hoạt Động Như Thế Nào
VPC Peering tạo ra một kết nối mạng trực tiếp giữa hai VPC, cho phép traffic định tuyến qua AWS internal network bằng private IPv4 (hoặc IPv6). Không có gateway, VPN tunnel, hay NAT device nào tham gia — đây là điểm khác biệt cốt lõi so với Site-to-Site VPN hay Transit Gateway.
Điều quan trọng cần hiểu: peering connection tự nó không tự động định tuyến traffic. Bạn phải thêm route vào từng route table liên quan ở cả hai phía. Nếu chỉ cập nhật một phía, traffic đi được một chiều nhưng response packet không có đường về — kết quả là connection timeout thay vì connection refused, khiến debug khó hơn nhiều.
VPC Peering cũng không hỗ trợ transitive routing. Nếu VPC-A peer với VPC-B, và VPC-B peer với VPC-C, thì VPC-A không thể reach VPC-C qua VPC-B. Mỗi cặp VPC cần peering connection riêng, hoặc bạn cần chuyển sang Transit Gateway cho topology phức tạp hơn.
- VPC-A (CIDR: 10.0.0.0/16) và VPC-B (CIDR: 10.1.0.0/16) nằm trong cùng account và region.
- Peering Connection là logical link — không phải gateway hay device vật lý.
- Route table của mỗi VPC phải có entry trỏ CIDR của VPC kia về phía peering connection ID (
pcx-xxxxxxxx). - Security Group ở mỗi phía phải cho phép inbound từ CIDR hoặc Security Group của phía kia.
- Traffic đi hoàn toàn qua AWS backbone — không ra internet public.
Chuẩn Bị: Xác Định Thông Tin Cần Thiết
Trước khi bắt đầu, thu thập các giá trị sau. Sẽ dùng chúng xuyên suốt các bước CLI bên dưới.
# Lấy VPC ID và CIDR block của cả hai VPC
aws ec2 describe-vpcs \
--filters 'Name=state,Values=available' \
--query 'Vpcs[*].{VpcId:VpcId,CidrBlock:CidrBlock,Name:Tags[?Key==`Name`]|[0].Value}' \
--output table \
--region us-east-1
# Lấy Route Table ID liên kết với subnet cần giao tiếp trong VPC-A
aws ec2 describe-route-tables \
--filters 'Name=vpc-id,Values=vpc-aaaaaaaaaaaaaaa01' \
--query 'RouteTables[*].{RouteTableId:RouteTableId,Associations:Associations[*].SubnetId}' \
--output table \
--region us-east-1
Ghi lại: VPC_A_ID, VPC_B_ID, CIDR_A (ví dụ: 10.0.0.0/16), CIDR_B (ví dụ: 10.1.0.0/16), RTB_A_ID, RTB_B_ID.
Bước 1: Tạo VPC Peering Connection
Vì cả hai VPC nằm trong cùng account và region, requester và accepter là cùng một account. Lệnh dưới đây tạo peering request từ VPC-A sang VPC-B.
aws ec2 create-vpc-peering-connection \
--vpc-id vpc-aaaaaaaaaaaaaaa01 \
--peer-vpc-id vpc-bbbbbbbbbbbbbbb02 \
--region us-east-1
Output trả về một object chứa VpcPeeringConnectionId (dạng pcx-xxxxxxxxxxxxxxxx) với status pending-acceptance. Lưu lại ID này.
# Xác nhận peering connection vừa tạo và lấy ID
aws ec2 describe-vpc-peering-connections \
--filters 'Name=status-code,Values=pending-acceptance' \
--query 'VpcPeeringConnections[*].{PeeringId:VpcPeeringConnectionId,Status:Status.Code,RequesterCIDR:RequesterVpcInfo.CidrBlock,AccepterCIDR:AccepterVpcInfo.CidrBlock}' \
--output table \
--region us-east-1
Bước 2: Chấp Nhận Peering Request
Vì cùng account, bạn chấp nhận ngay. Với cross-account peering, bước này phải thực hiện từ account của accepter VPC.
aws ec2 accept-vpc-peering-connection \
--vpc-peering-connection-id pcx-xxxxxxxxxxxxxxxx \
--region us-east-1
Sau lệnh này, status chuyển sang active. Kiểm tra lại:
aws ec2 describe-vpc-peering-connections \
--vpc-peering-connection-ids pcx-xxxxxxxxxxxxxxxx \
--query 'VpcPeeringConnections[0].Status.Code' \
--output text \
--region us-east-1
Kết quả phải là active. Nếu vẫn là pending-acceptance sau vài giây, kiểm tra lại region và account.
Bước 3 & 4: Cập Nhật Route Table — Phần Hay Bị Bỏ Sót Nhất
Đây là bước mà hầu hết mọi người quên làm đủ. Peering connection ở trạng thái active nhưng traffic vẫn không đi được vì chưa có route. Cần cập nhật route table ở cả hai phía.
Thêm route vào Route Table của VPC-A — trỏ traffic đến CIDR của VPC-B qua peering connection:
aws ec2 create-route \
--route-table-id rtb-aaaaaaaaaaaaaa01 \
--destination-cidr-block 10.1.0.0/16 \
--vpc-peering-connection-id pcx-xxxxxxxxxxxxxxxx \
--region us-east-1
Thêm route vào Route Table của VPC-B — trỏ traffic đến CIDR của VPC-A qua cùng peering connection:
aws ec2 create-route \
--route-table-id rtb-bbbbbbbbbbbbbbb02 \
--destination-cidr-block 10.0.0.0/16 \
--vpc-peering-connection-id pcx-xxxxxxxxxxxxxxxx \
--region us-east-1
Nếu subnet của bạn dùng custom route table (không phải main route table của VPC), đảm bảo bạn cập nhật đúng route table ID được associate với subnet đó. Một lỗi phổ biến là cập nhật main route table nhưng subnet lại dùng custom route table — traffic vẫn không đi được và không có error message nào rõ ràng.
Xác nhận route đã được tạo đúng:
aws ec2 describe-route-tables \
--route-table-ids rtb-aaaaaaaaaaaaaa01 \
--query 'RouteTables[0].Routes[?VpcPeeringConnectionId!=null]' \
--output table \
--region us-east-1
- Route Table của VPC-A có entry:
10.1.0.0/16 → pcx-xxxxxxxxxxxxxxxx - Route Table của VPC-B có entry:
10.0.0.0/16 → pcx-xxxxxxxxxxxxxxxx - Nếu thiếu một trong hai, traffic một chiều sẽ bị drop ở bước return path.
- Với subnet dùng custom route table, phải cập nhật đúng route table được associate — không phải main route table của VPC.
Bước 5: Cập Nhật Security Group Để Cho Phép Traffic
Route table chỉ định tuyến packet — Security Group mới quyết định packet có được chấp nhận hay không. Đây là layer thứ hai hay bị bỏ qua.
Giả sử instance trong VPC-B chạy web server trên port 80, và instance trong VPC-A cần kết nối đến. Cập nhật Security Group của instance VPC-B để cho phép inbound từ CIDR của VPC-A:
# Lấy Security Group ID của instance trong VPC-B
aws ec2 describe-instances \
--filters 'Name=vpc-id,Values=vpc-bbbbbbbbbbbbbbb02' \
--query 'Reservations[*].Instances[*].{InstanceId:InstanceId,SG:SecurityGroups[*].GroupId}' \
--output table \
--region us-east-1
# Thêm inbound rule cho phép TCP port 80 từ CIDR của VPC-A
aws ec2 authorize-security-group-ingress \
--group-id sg-bbbbbbbbbbbbbbbb1 \
--protocol tcp \
--port 80 \
--cidr 10.0.0.0/16 \
--region us-east-1
Nếu muốn cho phép theo Security Group ID thay vì CIDR (tốt hơn về mặt least privilege khi cả hai VPC trong cùng account):
aws ec2 authorize-security-group-ingress \
--group-id sg-bbbbbbbbbbbbbbbb1 \
--protocol tcp \
--port 80 \
--source-group sg-aaaaaaaaaaaaaaaaa1 \
--region us-east-1
Security Group reference theo Group ID chỉ hoạt động trong cùng VPC hoặc với peered VPC trong cùng region và account. Với cross-account peering, bạn phải dùng CIDR hoặc chỉ định cả account ID khi reference Security Group.
Bước 6: Kiểm Tra Kết Nối End-to-End
Sau khi hoàn tất cả năm bước trên, kiểm tra thực tế từ instance. Cách nhanh nhất là dùng VPC Reachability Analyzer — không cần gửi traffic thật, phân tích tĩnh dựa trên cấu hình.
# Tạo path analysis từ instance trong VPC-A đến instance trong VPC-B
aws ec2 create-network-insights-path \
--source i-aaaaaaaaaaaaaaaaa \
--destination i-bbbbbbbbbbbbbbbbb \
--protocol tcp \
--destination-port 80 \
--region us-east-1
# Chạy analysis (lưu NetworkInsightsPathId từ lệnh trên)
aws ec2 start-network-insights-analysis \
--network-insights-path-id nip-xxxxxxxxxxxxxxxx \
--region us-east-1
# Xem kết quả (đợi vài giây cho analysis hoàn tất)
aws ec2 describe-network-insights-analyses \
--network-insights-analysis-ids nia-xxxxxxxxxxxxxxxx \
--query 'NetworkInsightsAnalyses[0].{Status:Status,NetworkPathFound:NetworkPathFound,ExplanationCodes:Explanations[*].ExplanationCode}' \
--output table \
--region us-east-1
Nếu NetworkPathFound là true, cấu hình đúng. Nếu false, ExplanationCodes sẽ chỉ ra layer nào đang block — thường là missing route hoặc Security Group rule.
Tình Huống Thực Tế: Khi Peering 'Active' Nhưng Vẫn Không Ping Được
Một pattern lỗi hay gặp: peering connection ở trạng thái active, route table đã cập nhật, nhưng ping từ VPC-A sang VPC-B vẫn timeout. Lần đầu gặp, bản năng là kiểm tra lại peering connection — nhưng đó không phải vấn đề.
Nguyên nhân thực tế thường là một trong hai:
- Subnet dùng custom route table chưa được cập nhật. Lệnh
describe-route-tablesvới filtervpc-idtrả về tất cả route table trong VPC — nhưng chỉ route table nào được associate với subnet chứa instance mới có hiệu lực. Kiểm tra bằng cách filter theoassociation.subnet-idthay vìvpc-id. - Security Group chưa cho phép ICMP. Ping dùng ICMP, không phải TCP hay UDP. Nếu rule chỉ mở TCP port 22 hay 80, ping vẫn bị block dù route đúng.
# Kiểm tra route table thực sự associate với subnet của instance
aws ec2 describe-route-tables \
--filters 'Name=association.subnet-id,Values=subnet-xxxxxxxxxxxxxxxxx' \
--query 'RouteTables[0].{RouteTableId:RouteTableId,Routes:Routes[*].{Dest:DestinationCidrBlock,Target:VpcPeeringConnectionId}}' \
--output table \
--region us-east-1
Nếu output không có route nào với VpcPeeringConnectionId, đây là route table cần cập nhật — không phải cái bạn đã cập nhật trước đó.
Lưu Ý Quan Trọng Về CIDR Overlap
VPC Peering không hoạt động nếu CIDR block của hai VPC bị overlap. Đây là hard constraint — AWS sẽ từ chối tạo peering connection. Ví dụ: nếu cả hai VPC đều dùng 10.0.0.0/16, bạn không thể peer chúng.
Kiểm tra trước khi tạo peering:
aws ec2 describe-vpcs \
--vpc-ids vpc-aaaaaaaaaaaaaaa01 vpc-bbbbbbbbbbbbbbb02 \
--query 'Vpcs[*].{VpcId:VpcId,CidrBlock:CidrBlock}' \
--output table \
--region us-east-1
Nếu CIDR overlap và không thể thay đổi, Transit Gateway với static routing hoặc PrivateLink là các lựa chọn thay thế cần xem xét.
Kết Luận & Bước Tiếp Theo Với VPC Peering
Thiết lập VPC Peering để kết nối hai VPC trong cùng account và region gồm sáu bước tuần tự: tạo peering connection, chấp nhận request, cập nhật route table ở cả hai phía, cập nhật security group, và xác minh kết nối. Bước route table là nơi dễ mắc lỗi nhất — đặc biệt khi subnet dùng custom route table thay vì main route table của VPC.
Nếu topology của bạn phát triển lên nhiều VPC hơn (5+), hãy đánh giá Transit Gateway — quản lý N*(N-1)/2 peering connection riêng lẻ sẽ trở nên phức tạp nhanh chóng. Với use case expose một service cụ thể (không phải toàn bộ VPC), AWS PrivateLink là lựa chọn có security boundary tốt hơn.
Glossary — Thuật Ngữ Chính
| Thuật ngữ | Giải thích |
|---|---|
| VPC Peering Connection | Kết nối mạng trực tiếp giữa hai VPC, cho phép traffic đi qua private IP mà không qua internet. Được định danh bằng pcx-xxxxxxxx. |
| Route Table | Tập hợp các rule định tuyến xác định traffic từ subnet đi đến đâu. Mỗi subnet associate với đúng một route table tại một thời điểm. |
| CIDR Block | Dải địa chỉ IP được gán cho VPC hoặc subnet, ví dụ 10.0.0.0/16. Hai VPC peer nhau không được có CIDR overlap. |
| Transitive Routing | Khả năng định tuyến traffic qua một VPC trung gian sang VPC thứ ba. VPC Peering không hỗ trợ transitive routing. |
| Reachability Analyzer | Công cụ phân tích tĩnh của AWS xác định xem traffic có thể đi từ nguồn đến đích hay không, dựa trên cấu hình network hiện tại. |
Nhận xét
Đăng nhận xét