Định tuyến Traffic Database với VirtualService
Chúng ta cần tạo tài nguyên VirtualService trong Istio để định hướng lưu lượng truy cập từ các ứng dụng phía trước (frontend) đến dịch vụ PostgreSQL. Trong bối cảnh Database Mesh, VirtualService đóng vai trò như bảng định tuyến logic, cho phép chúng ta tách biệt traffic đi đến các bản sao (replica) khác nhau hoặc định tuyến dựa trên header HTTP/gRPC.
Tạo file cấu hình /etc/istio/db-virtualservice.yaml với nội dung hoàn chỉnh dưới đây. File này sẽ ánh xạ service name postgres-svc đến cổng 5432.
cat > /etc/istio/db-virtualservice.yaml
Kết quả mong đợi: Istio Ingress/Envoy sẽ nhận diện traffic đến postgres-svc:5432 và áp dụng quy tắc định tuyến này, chuyển tiếp gói tin đến endpoint Pod PostgreSQL thực tế.
Áp dụng cấu hình vào cluster Kubernetes bằng lệnh:
kubectl apply -f /etc/istio/db-virtualservice.yaml
Kiểm tra trạng thái áp dụng:
kubectl get virtualservice postgres-routing -n default
Kết quả mong đợi: Xuất hiện dòng trạng thái postgres-routing với thời gian tạo gần nhất, xác nhận tài nguyên đã được tạo thành công.
Cấu hình Load Balancing và mTLS với DestinationRule
Dịch vụ Database cần cơ chế cân bằng tải (Load Balancing) hiệu quả để phân phối các kết nối từ nhiều ứng dụng vào các Pod PostgreSQL. Ngoài ra, chúng ta cần bật DestinationRule để kích hoạt giao thức mTLS (mutual TLS) ở tầng Envoy Proxy, đảm bảo mã hóa hai chiều giữa client và database.
Tạo file /etc/istio/db-destinationrule.yaml với nội dung:
cat > /etc/istio/db-destinationrule.yaml
Giải thích cấu trúc: mode: ISTIO_MUTUAL bắt buộc Envoy thực hiện handshake mTLS. ROUND_ROBIN phân phối đều traffic. maxConnections giới hạn số lượng kết nối TCP đồng thời để tránh quá tải Database.
Áp dụng cấu hình:
kubectl apply -f /etc/istio/db-destinationrule.yaml
Verify kết quả bằng cách kiểm tra trạng thái DestinationRule:
kubectl get destinationrule postgres-dr -n default
Kết quả mong đợi: Tài nguyên được hiển thị, xác nhận chính sách cân bằng tải và bảo mật đã được đăng ký trong control plane của Istio.
Thiết lập PeerAuthentication cho Database Service
Để đảm bảo rằng dịch vụ Database chỉ chấp nhận kết nối đã được mã hóa mTLS, chúng ta cần cấu hình PeerAuthentication ở cấp độ namespace hoặc workload. Bước này xác định "chính sách mặc định" cho việc xác thực peer (bên gửi) khi traffic đi vào Pod PostgreSQL.
Tạo file /etc/istio/db-peerauth.yaml để áp dụng chính sách STRICT (chỉ cho phép mTLS) cho workload PostgreSQL:
cat > /etc/istio/db-peerauth.yaml
Giải thích: selector nhắm mục tiêu vào Pod có label app: postgres. mode: STRICT nghĩa là Envoy sidecar bên trong Pod PostgreSQL sẽ từ chối bất kỳ kết nối nào không có chứng chỉ hợp lệ (non-mTLS).
Áp dụng cấu hình:
kubectl apply -f /etc/istio/db-peerauth.yaml
Verify kết quả:
kubectl get peerauthentication postgres-mtls -n default
Kết quả mong đợi: Tài nguyên được tạo, xác nhận Pod PostgreSQL sẽ bắt buộc sử dụng mTLS cho mọi kết nối.
Áp dụng AuthorizationPolicy để Kiểm soát Truy cập
Ngay cả khi đã có mTLS, chúng ta cần kiểm soát ai được phép truy cập vào Database. AuthorizationPolicy cho phép chúng ta định nghĩa chính sách dựa trên nguồn gốc (source principal) hoặc action (allow/deny). Chúng ta sẽ cấu hình để chỉ cho phép service backend-app truy cập vào postgres-svc.
Tạo file /etc/istio/db-authzpolicy.yaml với nội dung:
cat > /etc/istio/db-authzpolicy.yaml
Giải thích: selector áp dụng cho PostgreSQL. action: ALLOW là chính sách mặc định (thường dùng với default deny). principals chỉ định service account backend-app trong namespace default là được phép. ports giới hạn chỉ cổng 5432.
Áp dụng cấu hình:
kubectl apply -f /etc/istio/db-authzpolicy.yaml
Verify kết quả:
kubectl get authorizationpolicy postgres-authz -n default
Kết quả mong đợi: Tài nguyên được tạo. Nếu có service khác cố gắng kết nối vào cổng 5432, Envoy sẽ trả về lỗi PERMISSION_DENIED (HTTP 403 hoặc TCP reset).
Verify Tổng thể và Kiểm tra Kết nối
Sau khi đã áp dụng VirtualService, DestinationRule, PeerAuthentication và AuthorizationPolicy, chúng ta cần kiểm tra xem toàn bộ luồng traffic có hoạt động đúng như thiết kế hay không.
Đầu tiên, kiểm tra xem Envoy sidecar bên trong Pod PostgreSQL đã nhận được cấu hình mới chưa bằng cách xem logs:
kubectl logs -n default $(kubectl get pod -l app=postgres -o jsonpath='{.items[0].metadata.name}') -c istio-proxy | grep -i "peer_authentication\|destination_rule" | head -n 5
Kết quả mong đợi: Xuất hiện các log xác nhận Envoy đã load cấu hình peer_authentication với mode STRICT và destination_rule với ISTIO_MUTUAL.
Thử nghiệm kết nối từ một Pod giả lập là backend-app (nếu đã tồn tại) hoặc dùng lệnh curl từ Pod khác để kiểm tra quyền truy cập:
kubectl exec -n default $(kubectl get pod -l app=backend-app -o jsonpath='{.items[0].metadata.name}') -- pg_isready -h postgres-svc -p 5432 -U postgres
Kết quả mong đợi: Nếu cấu hình đúng, lệnh trả về accepting connections. Nếu bạn chạy lệnh này từ một Pod không có trong danh sách principals của AuthorizationPolicy, lệnh sẽ bị từ chối hoặc timeout do Policy chặn.
Để debug chi tiết traffic đang đi qua, sử dụng lệnh istioctl (nếu đã cài đặt trong cluster hoặc local client):
istioctl analyze -n default
Kết quả mong đợi: Không có cảnh báo (warning) hoặc lỗi (error) liên quan đến cấu hình security hoặc networking của postgres-svc.
Điều hướng series:
Mục lục: Series: Triển khai Database Mesh với Envoy và Istio trên Ubuntu 24.04
« Phần 4: Triển khai Database Mesh với PostgreSQL và Envoy Proxy
Phần 6: Giám sát, Debug và Troubleshooting Database Mesh »