Cấu hình định tuyến lưu lượng với VirtualService và DestinationRule
Thiết lập DestinationRule cho mTLS và Connection Pool
Trước khi định tuyến, ta cần khai báo DestinationRule để thiết lập chính sách mTLS STRICT và cấu hình pool kết nối cho service đích.
Tại sao: Istio cần biết cách bảo vệ kênh truyền tải (mTLS) và quản lý số lượng socket kết nối tối đa để tránh làm quá tải server đích.
Kết quả mong đợi: Tất cả lưu lượng giữa các pod trong cluster đều được mã hóa và giới hạn số lượng kết nối đồng thời.
File cấu hình đầy đủ: /etc/istio/configs/destination-rule-backend.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: backend-destination-rule
namespace: default
spec:
host: backend-service
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
connectionPool:
tcp:
maxConnections: 100
http:
http2MaxRequests: 1000
maxPendingRequests: 100
Áp dụng cấu hình:
kubectl apply -f /etc/istio/configs/destination-rule-backend.yaml
Verify: Kiểm tra trạng thái áp dụng và cấu hình mTLS.
istioctl analyze
Tạo VirtualService để định tuyến lưu lượng
Sau khi có DestinationRule, ta tạo VirtualService để chỉ định logic định tuyến: tất cả traffic đến host backend sẽ được xử lý theo DestinationRule trên.
Tại sao: VirtualService là bộ não định tuyến, nó quyết định traffic đi đâu dựa trên host, HTTP method, headers, hoặc URL path.
Kết quả mong đợi: Istio Ingress Gateway và Sidecar Proxy bắt đầu định tuyến lưu lượng đến backend-service theo cấu hình.
File cấu hình đầy đủ: /etc/istio/configs/virtual-service-backend.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
http:
- match:
- uri:
prefix: /api
route:
- destination:
host: backend-service
port:
number: 8080
Áp dụng cấu hình:
kubectl apply -f /etc/istio/configs/virtual-service-backend.yaml
Verify: Kiểm tra traffic flow bằng lệnh istioctl.
istioctl proxy-config route deployment/backend-deployment -n default
Thực hiện chiến lược Blue-Green và Canary Release
Chiến lược Blue-Green Deployment
Để thực hiện Blue-Green, ta cần hai phiên bản service: blue (ổn định) và green (phiên bản mới). Ta sẽ dùng VirtualService để chuyển toàn bộ traffic sang green.
Tại sao: Blue-Green cho phép chuyển đổi tức thì giữa hai môi trường mà không gây gián đoạn, dễ dàng rollback nếu green có lỗi.
Kết quả mong đợi: 100% traffic hướng về phiên bản mới (green), hoàn toàn không còn traffic đi về phiên bản cũ (blue).
Giả định: Ta đã deploy 2 service: backend-blue và backend-green cùng expose port 8080.
File cấu hình chuyển đổi Blue-Green: /etc/istio/configs/virtual-service-blue-green.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
http:
- route:
- destination:
host: backend-green
port:
number: 8080
weight: 100
Áp dụng để chuyển toàn bộ sang Green:
kubectl apply -f /etc/istio/configs/virtual-service-blue-green.yaml
Verify: Dùng curl để test endpoint và xem header x-envoy-upstream-service-host để xác nhận pod nào xử lý request.
curl -v http://backend-service.default.svc.cluster.local/api/v1/status
Chiến lược Canary Release (Phân phối tỷ lệ traffic)
Canary Release phân chia traffic theo tỷ lệ phần trăm (ví dụ: 10% cho phiên bản mới, 90% cho phiên bản cũ).
Tại sao: Cho phép kiểm thử phiên bản mới trên một nhóm nhỏ người dùng thực tế để phát hiện lỗi trước khi rollout toàn bộ.
Kết quả mong đợi: 10% request đi về backend-green, 90% request đi về backend-blue.
File cấu hình Canary: /etc/istio/configs/virtual-service-canary.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
http:
- route:
- destination:
host: backend-blue
port:
number: 8080
weight: 90
- destination:
host: backend-green
port:
number: 8080
weight: 10
Áp dụng cấu hình Canary:
kubectl apply -f /etc/istio/configs/virtual-service-canary.yaml
Verify: Gửi nhiều request liên tục và đếm tỷ lệ response từ mỗi phiên bản.
for i in {1..20}; do curl -s http://backend-service.default.svc.cluster.local/api/v1/status | grep "version"; done
Áp dụng Circuit Breaker và Retry Policy
Cấu hình Circuit Breaker để bảo vệ hệ thống
Circuit Breaker ngăn chặn việc gọi service đích khi nó đang quá tải hoặc lỗi liên tục, giúp hệ thống tự phục hồi.
Tại sao: Ngăn "cascade failure" (lỗi lan truyền) khi một service bị sập kéo theo các service phụ thuộc khác bị treo do timeout.
Kết quả mong đợi: Khi backend lỗi > 50% trong 10s, Istio sẽ chặn request mới và trả về lỗi ngay lập tức thay vì chờ timeout.
File cấu hình Circuit Breaker: /etc/istio/configs/destination-rule-cb.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: backend-destination-rule
namespace: default
spec:
host: backend-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 100
maxRequestsPerConnection: 10
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
Áp dụng cấu hình:
kubectl apply -f /etc/istio/configs/destination-rule-cb.yaml
Verify: Giả lập lỗi 5xx liên tục và kiểm tra log của Envoy proxy để thấy thông báo "Host ejected".
kubectl logs -n istio-system -l app=istiod --tail=50 | grep -i "ejection"
Cấu hình Retry Policy cho khả năng phục hồi
Retry Policy tự động thực hiện lại request khi gặp lỗi transient (lỗi tạm thời như mạng chập chờn, 503 Service Unavailable).
Tại sao: Tăng tính sẵn sàng của hệ thống bằng cách tự động xử lý các lỗi không do logic code gây ra.
Kết quả mong đợi: Request lỗi 5xx hoặc timeout sẽ được thử lại tối đa 3 lần với khoảng cách 100ms.
File cấu hình Retry trong VirtualService: /etc/istio/configs/virtual-service-retry.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
http:
- route:
- destination:
host: backend-service
port:
number: 8080
retries:
attempts: 3
perTryTimeout: 2s
retryOn: "5xx,reset,connect-failure,retriable-4xx"
Áp dụng cấu hình Retry:
kubectl apply -f /etc/istio/configs/virtual-service-retry.yaml
Verify: Giả lập service trả về 500 trong lần đầu, sau đó thành công. Kiểm tra xem client có nhận được 200 OK không.
curl -v http://backend-service.default.svc.cluster.local/api/v1/flaky
Kiểm soát Rate Limiting và Quota
Tích hợp Rate Limiting với Envoy Filter
Để giới hạn số lượng request (rate limiting) trên từng service, ta sử dụng Envoy Filter để cấu hình bộ lọc rate limit của Envoy.
Tại sao: Bảo vệ service khỏi bị tấn công DoS hoặc quá tải do lưu lượng đột biến, đảm bảo công bằng giữa các client.
Kết quả mong đợi: Khi client gửi > 10 request/giây, server trả về 429 Too Many Requests.
File cấu hình Envoy Filter: /etc/istio/configs/envoy-filter-rate-limit.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: rate-limit-filter
namespace: default
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.http.connection_manager
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct"
type_url: type.googleapis.com/envoy.config.filter.http.local_ratelimit.v2.LocalRateLimit
value:
stat_prefix: http_local_rate_limit
token_bucket:
max_tokens: 10
tokens_per_fill: 10
fill_interval: 1s
rate_limit_response_headers_to_add:
- append:
key: "X-RateLimit-Limit"
value: "10"
Áp dụng Envoy Filter:
kubectl apply -f /etc/istio/configs/envoy-filter-rate-limit.yaml
Verify: Sử dụng ab (Apache Bench) hoặc wrk để tấn công endpoint với tốc độ cao và đếm số lượng response 429.
ab -n 100 -c 20 http://backend-service.default.svc.cluster.local/api/v1/status
Cấu hình Global Rate Limiting với Istio Ambient (Cilium Egress Gateway)
Nếu cần rate limiting ở mức toàn cục (toàn cluster) thay vì local trên mỗi pod, ta cấu hình chính sách này trên Cilium Egress Gateway hoặc Service Entry.
Tại sao: Local rate limit chỉ áp dụng trên mỗi pod, global rate limit cần một điểm tập trung để đếm tổng số request toàn bộ.
Kết quả mong đợi: Tổng số request đến service backend từ toàn bộ cluster bị giới hạn, vượt quá sẽ bị chặn ngay tại gateway.
File cấu hình Service Entry với rate limit (giả định dùng Envoy Proxy Gateway): /etc/istio/configs/service-entry-rate-limit.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: backend-ext
namespace: default
spec:
hosts:
- backend-service
ports:
- number: 8080
name: http
protocol: HTTP
resolution: DNS
location: MESH_INTERNAL
File cấu hình Envoy Filter cho Gateway (Global): /etc/istio/configs/envoy-filter-global-ratelimit.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: global-rate-limit-filter
namespace: istio-system
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: envoy.http.connection_manager
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct"
type_url: type.googleapis.com/envoy.config.filter.http.local_ratelimit.v2.LocalRateLimit
value:
stat_prefix: http_global_rate_limit
token_bucket:
max_tokens: 100
tokens_per_fill: 100
fill_interval: 1s
Áp dụng cấu hình Global Rate Limit:
kubectl apply -f /etc/istio/configs/service-entry-rate-limit.yaml kubectl apply -f /etc/istio/configs/envoy-filter-global-ratelimit.yaml
Verify: Gửi request từ nhiều pod khác nhau cùng lúc và kiểm tra xem tổng số request bị chặn khi vượt quá 100/s.
kubectl logs -n istio-system -l app=istio-ingressgateway --tail=50 | grep -i "rate limit"
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Service Mesh nội bộ an toàn với Istio, Cilium và eBPF trên Kubernetes để quản lý lưu lượng mạng, bảo mật và quan sát chi tiết
« Phần 3: Tích hợp Istio với Cilium và bật mTLS tự động
Phần 5: Xây dựng chính sách bảo mật Zero Trust với AuthorizationPolicy »