Chuyển đến nội dung chính

LESSON 25: ISTIO TRAFFIC MANAGEMENT — VIRTUALSERVICE & DESTINATIONRULE

Configure traffic routing with VirtualService, DestinationRule, canary deployment, A/B testing, circuit breaking, retry, timeout, and fault injection.

🔒 DevSecOps — Lesson 25 LESSON 25: ISTIO TRAFFIC MANAGEMENT — VIRTUALSERVICE & DESTINATIONRULE

Deploy Microservices On-Premises with Kubernetes HA

Part 6: Service Mesh & Ingress with Istio

xdev.asia

🎯 LESSON OBJECTIVE__HTMLTAG_68___
  • ✅ VirtualService: routing rules, header-based routing__HTMLTAG_71___
  • ✅ DestinationRule: subsets, load balancing, connection pool
  • ✅ Canary deployment with traffic splitting
  • ✅ Circuit breaking and outlier detection
  • ✅ Retry, timeout, fault injection
  • ✅ Rate limiting with EnvoyFilter

PART 1: VIRTUALSERVICE


Traffic Flow:

Client → Gateway → VirtualService → DestinationRule → Pod (subset)

VirtualService: "WHERE to route" (rules)
DestinationRule: "HOW to route" (policies, subsets)

1.1. Basic Routing

# virtualservice-order.yaml:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: order-service
  namespace: default
spec:
  hosts:
    - order-service              # K8s service name
  http:
    - match:
        - headers:
            x-api-version:
              exact: "v2"
      route:
        - destination:
            host: order-service
            subset: v2
            port:
              number: 8080
    - route:                     # Default route
        - destination:
            host: order-service
            subset: v1
            port:
              number: 8080
      timeout: 10s
      retries:
        attempts: 3
        perTryTimeout: 3s
        retryOn: 5xx,reset,connect-failure,refused-stream

1.2. Canary Deployment (Traffic Splitting)

# canary-rollout.yaml:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: order-service
  namespace: default
spec:
  hosts:
    - order-service
  http:
    - route:
        - destination:
            host: order-service
            subset: v1
          weight: 90             # 90% → v1 (stable)
        - destination:
            host: order-service
            subset: v2
          weight: 10             # 10% → v2 (canary)

Gradual rollout:

Step 1: 90/10 → monitor errors

Step 2: 70/30 → monitor latency

Step 3: 50/50 → load test

Step 4: 0/100 → full rollout

1.3. A/B Testing (Header-Based)

# ab-testing.yaml:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: frontend
  namespace: default
spec:
  hosts:
    - frontend
  http:
    # Users with beta cookie → v2:
    - match:
        - headers:
            cookie:
              regex: ".*beta=true.*"
      route:
        - destination:
            host: frontend
            subset: v2
    # Internal team (user-agent header):
    - match:
        - headers:
            x-team:
              exact: "internal"
      route:
        - destination:
            host: frontend
            subset: v2
    # Everyone else → v1:
    - route:
        - destination:
            host: frontend
            subset: v1

PART 2: DESTINATIONRULE

# destination-rule-order.yaml:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: order-service
  namespace: default
spec:
  host: order-service
  
  trafficPolicy:
    # Load balancing:
    loadBalancer:
      simple: LEAST_REQUEST     # ROUND_ROBIN | LEAST_REQUEST | RANDOM
    
    # Connection pool:
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 5s
      http:
        h2UpgradePolicy: DEFAULT
        http1MaxPendingRequests: 100
        http2MaxRequests: 1000
        maxRequestsPerConnection: 10
        maxRetries: 3
    
    # Outlier detection (circuit breaking):
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
      minHealthPercent: 50

  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

PART 3: CIRCUIT BREAKING


Circuit Breaker States:

  CLOSED ──────────► OPEN ──────────► HALF-OPEN
  (normal)          (reject all)      (test few)
      ▲                                  │
      │          success                 │ 
      └──────────────────────────────────┘
                 (close again)

Istio Outlier Detection:
- consecutive5xxErrors: 5  → 5 errors → eject pod
- interval: 10s            → check every 10s
- baseEjectionTime: 30s   → eject for 30s minimum
- maxEjectionPercent: 50  → max 50% pods ejected
# Circuit breaker + connection limits:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: payment-service
  namespace: default
spec:
  host: payment-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 50        # Max concurrent TCP connections
      http:
        http1MaxPendingRequests: 50  # Max queued requests
        http2MaxRequests: 100        # Max concurrent requests
        maxRequestsPerConnection: 5
    outlierDetection:
      consecutive5xxErrors: 3
      interval: 5s
      baseEjectionTime: 60s
      maxEjectionPercent: 100     # Can eject all pods

PART 4: FAULT INJECTION (CHAOS TESTING)

# Inject delay + abort for testing:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: payment-service
  namespace: default
spec:
  hosts:
    - payment-service
  http:
    - fault:
        delay:
          percentage:
            value: 10.0           # 10% requests get 5s delay
          fixedDelay: 5s
        abort:
          percentage:
            value: 5.0            # 5% requests get HTTP 503
          httpStatus: 503
      route:
        - destination:
            host: payment-service
            subset: v1

PART 5: TRAFFIC MIRRORING (SHADOW TESTING)

# Mirror production traffic to new version:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: order-service
  namespace: default
spec:
  hosts:
    - order-service
  http:
    - route:
        - destination:
            host: order-service
            subset: v1
          weight: 100              # 100% traffic to v1
      mirror:
        host: order-service
        subset: v2                 # Mirror copy to v2
      mirrorPercentage:
        value: 100.0               # Mirror 100% traffic
    # → v2 receives copy, responses are discarded
    # → Test v2 with real traffic, zero risk!

PART 6: RATE LIMITING

# Rate limiting với Istio (EnvoyFilter):
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: rate-limit-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: envoy.filters.network.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.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
            value:
              stat_prefix: http_local_rate_limiter
              token_bucket:
                max_tokens: 100
                tokens_per_fill: 100
                fill_interval: 60s    # 100 requests/minute
              filter_enabled:
                runtime_key: local_rate_limit_enabled
                default_value:
                  numerator: 100
                  denominator: HUNDRED
              filter_enforced:
                runtime_key: local_rate_limit_enforced
                default_value:
                  numerator: 100
                  denominator: HUNDRED
              response_headers_to_add:
                - append_action: OVERWRITE_IF_EXISTS_OR_ADD
                  header:
                    key: x-local-rate-limit
                    value: "true"

💡 KEY TAKEAWAYS

  1. VirtualService: Routing rules — WHERE traffic goes
  2. DestinationRule: Policies — HOW traffic is handled (LB, circuit breaker)
  3. Canary: weight-based traffic splitting, gradual rollout
  4. Circuit breaker: outlierDetection ejects unhealthy pods
  5. Fault injection: Test resilience with delays and errors
  6. Traffic mirroring: Shadow test new versions with real traffic

🎯 EXERCISES__HTMLTAG_138___

Exercise 1: Canary Deployment

  • Deploy v1 and v2 of a service__HTMLTAG_143___
  • Configure 90/10 traffic split
  • Monitor error rate in Kiali
  • Gradually shift to 0/100

Exercise 2: Circuit Breaking__HTMLTAG_152___
  • Configure outlier detection (3 errors → eject)
  • Use Fortio to load test__HTMLTAG_157___
  • Observe ejection/recovery in Envoy admin

📚 NEXT POST

In Lesson 26: Istio Gateway and Ingress for Production, we will configure external access, TLS termination, and multi-domain hosting.