路由
Istio 的高级路由功能可根据各种请求属性对流量进行精细控制。
目录
路由概览
VirtualService 路由规则由匹配条件和路由目标组成。
基本结构
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: routing-example
spec:
hosts:
- myapp.example.com
http:
- match:
- uri:
prefix: "/api/v1"
route:
- destination:
host: api-v1
- match:
- headers:
user-agent:
regex: ".*Mobile.*"
route:
- destination:
host: mobile-app
- route: # Default route (no match)
- destination:
host: web-app匹配条件
匹配条件类型
| 条件 | 描述 | 匹配类型 |
|---|---|---|
| uri | 请求路径 | exact、prefix、regex |
| scheme | HTTP/HTTPS | exact、prefix、regex |
| method | HTTP 方法 | exact、prefix、regex |
| authority | Host Header | exact、prefix、regex |
| headers | HTTP Header | exact、prefix、regex |
| queryParams | 查询参数 | exact、prefix、regex |
| sourceLabels | 来源工作负载标签 | 标签选择器 |
| gateways | Gateway 名称 | 列表 |
匹配类型
yaml
# exact: Exact match
match:
- uri:
exact: "/login"
# prefix: Prefix match
match:
- uri:
prefix: "/api/"
# regex: Regular expression match
match:
- uri:
regex: "^/api/v[0-9]+/.*"组合多个条件
yaml
# AND condition: All conditions must match
http:
- match:
- uri:
prefix: "/api"
headers:
x-api-version:
exact: "v2"
queryParams:
debug:
exact: "true"
route:
- destination:
host: api-debug
# OR condition: Use multiple match blocks
http:
- match:
- uri:
prefix: "/api/v1"
- uri:
prefix: "/api/v2"
route:
- destination:
host: api-service基于 URI 的路由
前缀匹配
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: uri-prefix-routing
spec:
hosts:
- myapp.example.com
http:
# API traffic
- match:
- uri:
prefix: "/api/"
route:
- destination:
host: api-service
port:
number: 8080
# Admin traffic
- match:
- uri:
prefix: "/admin/"
route:
- destination:
host: admin-service
port:
number: 9000
# Static files
- match:
- uri:
prefix: "/static/"
route:
- destination:
host: static-service
port:
number: 8000
# Default traffic
- route:
- destination:
host: frontend-service
port:
number: 3000精确匹配
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: uri-exact-routing
spec:
hosts:
- myapp.example.com
http:
# Login page
- match:
- uri:
exact: "/login"
route:
- destination:
host: auth-service
# Logout
- match:
- uri:
exact: "/logout"
route:
- destination:
host: auth-service
# Health check
- match:
- uri:
exact: "/health"
route:
- destination:
host: health-service正则表达式匹配
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: uri-regex-routing
spec:
hosts:
- myapp.example.com
http:
# API version routing: /api/v1/, /api/v2/, etc.
- match:
- uri:
regex: "^/api/v[0-9]+/.*"
route:
- destination:
host: api-service
# Numeric resource ID: /users/123
- match:
- uri:
regex: "^/users/[0-9]+$"
route:
- destination:
host: user-service
# File extension: .jpg, .png, .gif
- match:
- uri:
regex: ".*\\.(jpg|png|gif)$"
route:
- destination:
host: image-service基于 Header 的路由
基于 User-Agent 的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: header-user-agent-routing
spec:
hosts:
- reviews
http:
# Mobile devices
- match:
- headers:
user-agent:
regex: ".*Mobile.*"
route:
- destination:
host: reviews
subset: mobile
# Tablet devices
- match:
- headers:
user-agent:
regex: ".*(iPad|Tablet).*"
route:
- destination:
host: reviews
subset: tablet
# Desktop (default)
- route:
- destination:
host: reviews
subset: desktop基于自定义 Header 的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: header-custom-routing
spec:
hosts:
- myapp
http:
# Developer/Tester routing
- match:
- headers:
x-dev-user:
exact: "true"
route:
- destination:
host: myapp
subset: dev
# Beta testers
- match:
- headers:
x-beta-tester:
exact: "true"
route:
- destination:
host: myapp
subset: beta
# VIP users
- match:
- headers:
x-user-tier:
exact: "vip"
route:
- destination:
host: myapp
subset: vip
# Regular users
- route:
- destination:
host: myapp
subset: stable基于 API 版本的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: header-api-version-routing
spec:
hosts:
- api.example.com
http:
# API v3
- match:
- headers:
x-api-version:
exact: "v3"
route:
- destination:
host: api-service
subset: v3
# API v2
- match:
- headers:
x-api-version:
exact: "v2"
route:
- destination:
host: api-service
subset: v2
# API v1 (default)
- route:
- destination:
host: api-service
subset: v1基于查询参数的路由
基本查询参数匹配
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: query-param-routing
spec:
hosts:
- search.example.com
http:
# Debug mode: ?debug=true
- match:
- queryParams:
debug:
exact: "true"
route:
- destination:
host: search-service
subset: debug
# Premium search: ?premium=1
- match:
- queryParams:
premium:
exact: "1"
route:
- destination:
host: search-service
subset: premium
# A/B testing: ?variant=b
- match:
- queryParams:
variant:
exact: "b"
route:
- destination:
host: search-service
subset: variant-b
# Default search
- route:
- destination:
host: search-service
subset: standard组合多个查询参数
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: query-param-combined-routing
spec:
hosts:
- api.example.com
http:
# Debug mode + verbose logging
- match:
- queryParams:
debug:
exact: "true"
verbose:
exact: "true"
route:
- destination:
host: api-service
subset: debug-verbose
# Debug mode only
- match:
- queryParams:
debug:
exact: "true"
route:
- destination:
host: api-service
subset: debug
# Normal mode
- route:
- destination:
host: api-service
subset: production基于 HTTP 方法的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: method-based-routing
spec:
hosts:
- api.example.com
http:
# POST requests → Write-only service
- match:
- method:
exact: "POST"
uri:
prefix: "/api/"
route:
- destination:
host: api-write-service
# PUT/PATCH requests → Update service
- match:
- method:
regex: "PUT|PATCH"
uri:
prefix: "/api/"
route:
- destination:
host: api-update-service
# DELETE requests → Delete service
- match:
- method:
exact: "DELETE"
uri:
prefix: "/api/"
route:
- destination:
host: api-delete-service
# GET requests → Read-only service
- match:
- method:
exact: "GET"
uri:
prefix: "/api/"
route:
- destination:
host: api-read-service基于来源的路由
基于 Namespace 的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: source-namespace-routing
namespace: production
spec:
hosts:
- database.production.svc.cluster.local
http:
# Requests from production namespace
- match:
- sourceNamespace: production
route:
- destination:
host: database
subset: production
# Requests from staging namespace
- match:
- sourceNamespace: staging
route:
- destination:
host: database
subset: staging
# Block other namespaces
- route:
- destination:
host: access-denied基于 Service Account 的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: source-sa-routing
spec:
hosts:
- payment-service
http:
# Allow access only from specific Service Account
- match:
- sourceLabels:
app: frontend
version: v2
route:
- destination:
host: payment-service
subset: v2
# Legacy service
- match:
- sourceLabels:
app: frontend
version: v1
route:
- destination:
host: payment-service
subset: v1优先级和回退
匹配规则优先级
Istio 会从上到下评估 VirtualService HTTP 路由规则。
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: priority-example
spec:
hosts:
- myapp.example.com
http:
# Priority 1: Most specific condition
- match:
- uri:
exact: "/api/v2/users/admin"
headers:
x-admin:
exact: "true"
route:
- destination:
host: admin-api-v2
# Priority 2: Medium specificity
- match:
- uri:
prefix: "/api/v2/"
route:
- destination:
host: api-v2
# Priority 3: Less specific
- match:
- uri:
prefix: "/api/"
route:
- destination:
host: api-v1
# Priority 4 (last): Default fallback
- route:
- destination:
host: frontend回退策略
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: fallback-strategy
spec:
hosts:
- myapp
http:
# Requests matching specific conditions
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: myapp
subset: canary
fault:
abort:
percentage:
value: 0
httpStatus: 503
# No fallback on canary failure - return error
# Default requests - with fallback
- route:
- destination:
host: myapp
subset: stable
weight: 100实际示例
示例 1:多租户路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: multi-tenant-routing
spec:
hosts:
- api.example.com
http:
# Tenant A (identified by header)
- match:
- headers:
x-tenant-id:
exact: "tenant-a"
route:
- destination:
host: api-service
subset: tenant-a
# Tenant B (identified by subdomain)
- match:
- authority:
exact: "tenant-b.api.example.com"
route:
- destination:
host: api-service
subset: tenant-b
# Tenant C (identified by path)
- match:
- uri:
prefix: "/tenant-c/"
rewrite:
uri: "/"
route:
- destination:
host: api-service
subset: tenant-c示例 2:基于功能标志的路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: feature-flag-routing
spec:
hosts:
- myapp
http:
# Users with new feature enabled
- match:
- headers:
x-feature-new-ui:
exact: "enabled"
route:
- destination:
host: myapp
subset: new-ui
# Beta feature testers
- match:
- headers:
x-feature-beta:
exact: "enabled"
route:
- destination:
host: myapp
subset: beta
# Experimental features (employees only)
- match:
- headers:
x-feature-experimental:
exact: "enabled"
sourceLabels:
role: employee
route:
- destination:
host: myapp
subset: experimental
# Default (stable version)
- route:
- destination:
host: myapp
subset: stable示例 3:地理路由
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: geo-routing
spec:
hosts:
- content.example.com
http:
# Korean users
- match:
- headers:
x-country-code:
exact: "KR"
route:
- destination:
host: content-service
subset: korea
# Japanese users
- match:
- headers:
x-country-code:
exact: "JP"
route:
- destination:
host: content-service
subset: japan
# US users
- match:
- headers:
x-country-code:
exact: "US"
route:
- destination:
host: content-service
subset: us
# European users
- match:
- headers:
x-country-code:
regex: "DE|FR|UK|IT|ES"
route:
- destination:
host: content-service
subset: europe
# Other regions (global)
- route:
- destination:
host: content-service
subset: global示例 4:API Gateway 模式
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: api-gateway-routing
spec:
hosts:
- api.example.com
gateways:
- api-gateway
http:
# APIs requiring authentication
- match:
- uri:
prefix: "/api/v1/protected/"
headers:
authorization:
regex: "Bearer .*"
route:
- destination:
host: protected-api-service
# Public APIs
- match:
- uri:
prefix: "/api/v1/public/"
route:
- destination:
host: public-api-service
# GraphQL endpoint
- match:
- uri:
exact: "/graphql"
method:
exact: "POST"
route:
- destination:
host: graphql-service
# REST API
- match:
- uri:
prefix: "/api/v1/"
route:
- destination:
host: rest-api-service
# Health check
- match:
- uri:
exact: "/health"
route:
- destination:
host: health-service
# 404 handling
- route:
- destination:
host: error-service故障排除
路由未生效
bash
# 1. Check VirtualService status
kubectl get virtualservice -A
kubectl describe virtualservice <name> -n <namespace>
# 2. Check routing rules
istioctl proxy-config routes <pod-name> -n <namespace>
# 3. Check routing to specific service
istioctl proxy-config routes <pod-name> -n <namespace> --name <route-name> -o json
# 4. Validate configuration
istioctl analyze -n <namespace>调试匹配条件
bash
# Increase Envoy log level
istioctl proxy-config log <pod-name> -n <namespace> --level debug
# Trace requests
kubectl logs -n <namespace> <pod-name> -c istio-proxy -f
# Debug Pilot
kubectl logs -n istio-system -l app=istiod --tail=100常见问题
1. 匹配顺序问题
yaml
# ❌ Wrong order - default route first ignores other rules
http:
- route: # All traffic goes here
- destination:
host: myapp
- match: # Never executed
- uri:
prefix: "/api"
route:
- destination:
host: api-service
# ✅ Correct order
http:
- match: # Specific rules first
- uri:
prefix: "/api"
route:
- destination:
host: api-service
- route: # Default route last
- destination:
host: myapp2. 正则表达式语法错误
yaml
# ❌ Incorrect regex
match:
- uri:
regex: "/api/v[1-3]" # Missing anchor
# ✅ Correct regex
match:
- uri:
regex: "^/api/v[1-3].*"3. Header 大小写敏感问题
yaml
# HTTP headers are case-insensitive
# Istio automatically converts to lowercase
match:
- headers:
X-Custom-Header: # Automatically converted to x-custom-header
exact: "value"最佳实践
1. 将特定规则放在前面
yaml
# ✅ Good example
http:
- match:
- uri:
exact: "/api/v2/admin" # Most specific
route:
- destination:
host: admin-v2
- match:
- uri:
prefix: "/api/v2/" # Medium
route:
- destination:
host: api-v2
- match:
- uri:
prefix: "/api/" # General
route:
- destination:
host: api-v1
- route: # Default
- destination:
host: frontend2. 尽量减少使用正则表达式
yaml
# ❌ Avoid - complex regex degrades performance
match:
- uri:
regex: "^/(api|admin|public)/v[0-9]+/(users|products|orders)/[a-zA-Z0-9_-]+$"
# ✅ Recommended - use prefix or exact
match:
- uri:
prefix: "/api/v1/"3. 清晰命名
yaml
# ✅ Use clear names
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: product-api-routing # Clear name
labels:
app: product-service
purpose: routing
spec:
hosts:
- product-api.example.com4. 文档
yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-routing
annotations:
description: "Routes traffic based on API version and user type"
owner: "platform-team"
spec:
hosts:
- myapp.example.com
http:
# Route VIP users to dedicated instance
- match:
- headers:
x-user-tier:
exact: "vip"
route:
- destination:
host: myapp
subset: vip5. 测试策略
bash
# Routing rule test script
#!/bin/bash
# API v1 test
curl -H "Host: api.example.com" http://$GATEWAY_URL/api/v1/users
# API v2 test
curl -H "Host: api.example.com" http://$GATEWAY_URL/api/v2/users
# Mobile user test
curl -H "User-Agent: Mobile" http://$GATEWAY_URL/
# Header-based test
curl -H "x-canary: true" http://$GATEWAY_URL/