ServiceEntry
ServiceEntry 会在 Istio service mesh 中注册外部服务,使其能够像内部服务一样被管理。
目录
为什么使用 ServiceEntry?
外部服务管理的必要性
默认情况下,Istio mesh 不控制到外部服务的流量。使用 ServiceEntry:
主要优势
| 功能 | 无 ServiceEntry | 使用 ServiceEntry |
|---|---|---|
| 监控 | 黑洞 | 完整的指标收集 |
| 流量控制 | 不可行 | Timeout、Retry、Circuit Breaker |
| 安全 | 有限 | mTLS、证书管理 |
| 出口控制 | 允许所有外部流量 | 显式允许/阻止 |
| 服务发现 | 手动管理 | 自动 DNS 查找 |
ServiceEntry 概述
ServiceEntry 将外部服务添加到 Istio 服务注册表中。
基本结构
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-api
spec:
hosts: # External service hostname
- api.example.com
ports: # Port and protocol
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL # External/internal location
resolution: DNS # Address resolution method解析模式
ServiceEntry 支持 4 种地址解析模式。
1. DNS 解析
这是最常用的模式,可通过 DNS 动态解析 IP 地址。
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-api-dns
spec:
hosts:
- api.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS # DNS lookup使用场景:
- 公共 API(AWS S3、Google Cloud Storage)
- SaaS 服务(Stripe、SendGrid)
- 云托管服务
2. STATIC 解析
显式指定固定 IP 地址。
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-api-static
spec:
hosts:
- legacy-api.company.internal
addresses:
- 10.10.10.10
- 10.10.10.11
ports:
- number: 8080
name: http
protocol: HTTP
location: MESH_EXTERNAL
resolution: STATIC # Fixed IP
endpoints:
- address: 10.10.10.10
- address: 10.10.10.11使用场景:
- 旧版系统(无 DNS)
- 合规性要求使用固定 IP
- 内部数据中心服务
3. NONE 解析
不执行地址解析,而是按原样使用客户端提供的地址。
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: wildcard-api
spec:
hosts:
- "*.api.example.com" # Wildcard
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: NONE # No address resolution使用场景:
- 通配符域名
- 客户端负载均衡
- TCP/TLS 代理
4. DNS_ROUND_ROBIN 解析(已弃用)
使用 DNS round robin(现已整合到 DNS 模式中)。
位置设置
MESH_EXTERNAL(外部服务)
注册 mesh 之外的服务。
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-service
spec:
hosts:
- external-api.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL # External service
resolution: DNS特性:
- 不应用 mTLS
- 可通过 Egress Gateway 出站
- 被归类为外部流量
MESH_INTERNAL(内部服务)
将其视为 mesh 内部服务(很少使用)。
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: internal-vm-service
spec:
hosts:
- vm-service.internal
ports:
- number: 8080
name: http
protocol: HTTP
location: MESH_INTERNAL # Treat as internal service
resolution: STATIC
endpoints:
- address: 10.0.0.5
labels:
app: vm-service使用场景:
- 将 VM workload 纳入 mesh
- 多集群环境
- 混合云配置
实战示例
1. 注册外部 REST API
场景:支付网关 API
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: payment-gateway-api
namespace: production
spec:
hosts:
- api.payment-gateway.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
# VirtualService: Timeout and Retry settings
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: payment-gateway-routing
namespace: production
spec:
hosts:
- api.payment-gateway.com
http:
- route:
- destination:
host: api.payment-gateway.com
timeout: 10s
retries:
attempts: 3
perTryTimeout: 3s
retryOn: 5xx,reset,connect-failure
---
# DestinationRule: Circuit Breaker
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: payment-gateway-circuit-breaker
namespace: production
spec:
host: api.payment-gateway.com
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 10
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 3
interval: 30s
baseEjectionTime: 120s
tls:
mode: SIMPLE # TLS connection2. 注册外部数据库
场景:AWS RDS MySQL
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: aws-rds-mysql
spec:
hosts:
- mydb.abc123.us-west-2.rds.amazonaws.com
ports:
- number: 3306
name: tcp
protocol: TCP
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: aws-rds-mysql-circuit-breaker
spec:
host: mydb.abc123.us-west-2.rds.amazonaws.com
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
connectTimeout: 5s
outlierDetection:
consecutiveErrors: 5
interval: 60s
baseEjectionTime: 60s3. 注册通配符域名
场景:AWS S3 Bucket 访问
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: aws-s3-buckets
spec:
hosts:
- "*.s3.amazonaws.com"
- "*.s3.*.amazonaws.com"
- "*.s3-*.amazonaws.com"
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: NONE # Use NONE for wildcards4. 具有多个 endpoint 的外部服务
场景:多区域 API
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: multi-region-api
spec:
hosts:
- api.global-service.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: multi-region-routing
spec:
hosts:
- api.global-service.com
http:
# Region-based routing
- match:
- headers:
x-region:
exact: "us-west"
route:
- destination:
host: api.global-service.com
headers:
request:
set:
Host: us-west.api.global-service.com
- match:
- headers:
x-region:
exact: "eu-central"
route:
- destination:
host: api.global-service.com
headers:
request:
set:
Host: eu-central.api.global-service.com
# Default routing
- route:
- destination:
host: api.global-service.com5. 注册 TCP 服务
场景:外部 Redis Cluster
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-redis
spec:
hosts:
- redis.external-cluster.com
addresses:
- 203.0.113.10
- 203.0.113.11
ports:
- number: 6379
name: tcp
protocol: TCP
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: 203.0.113.10
labels:
instance: primary
- address: 203.0.113.11
labels:
instance: replica
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: external-redis-lb
spec:
host: redis.external-cluster.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
connectionPool:
tcp:
maxConnections: 50
connectTimeout: 3s结合 Egress Gateway
通过 Egress Gateway 集中控制外部流量。
基本 Egress Gateway 配置
yaml
# ServiceEntry: Register external service
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-api
spec:
hosts:
- api.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
# Gateway: Egress Gateway configuration
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: egress-gateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- api.example.com
tls:
mode: PASSTHROUGH
---
# VirtualService: Mesh internal -> Egress Gateway
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: direct-api-through-egress
spec:
hosts:
- api.example.com
gateways:
- mesh
- egress-gateway
http:
- match:
- gateways:
- mesh
port: 443
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 443
- match:
- gateways:
- egress-gateway
port: 443
route:
- destination:
host: api.example.com
port:
number: 443TLS Origination(内部 HTTP,外部 HTTPS)
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-http-to-https
spec:
hosts:
- api.secure-service.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: originate-tls
spec:
host: api.secure-service.com
trafficPolicy:
portLevelSettings:
- port:
number: 80
tls:
mode: SIMPLE # HTTP -> HTTPS conversion安全与 TLS
到外部服务的 mTLS
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: mtls-external-service
spec:
hosts:
- mtls-api.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: mtls-external-tls
spec:
host: mtls-api.example.com
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/client-cert.pem
privateKey: /etc/certs/client-key.pem
caCertificates: /etc/certs/ca-cert.pemSNI 路由
yaml
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: egress-sni-gateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: tls
protocol: TLS
hosts:
- api.example.com
- api2.example.com
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: sni-routing
spec:
hosts:
- api.example.com
- api2.example.com
gateways:
- mesh
- egress-sni-gateway
tls:
- match:
- gateways:
- mesh
port: 443
sniHosts:
- api.example.com
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 443
- match:
- gateways:
- egress-sni-gateway
port: 443
sniHosts:
- api.example.com
route:
- destination:
host: api.example.com
port:
number: 443监控与控制
指标收集
bash
# Check ServiceEntry traffic
kubectl exec -it <pod-name> -c istio-proxy -- \
curl localhost:15000/stats/prometheus | grep "api.example.com"
# Egress traffic metrics
istio_requests_total{destination_service_name="api.example.com"}Prometheus 查询
yaml
# External service request count
sum(rate(istio_requests_total{destination_service_namespace="",destination_service_name="api.example.com"}[5m]))
# External service error rate
sum(rate(istio_requests_total{destination_service_name="api.example.com",response_code=~"5.."}[5m])) /
sum(rate(istio_requests_total{destination_service_name="api.example.com"}[5m]))
# External service response time
histogram_quantile(0.95,
sum(rate(istio_request_duration_milliseconds_bucket{destination_service_name="api.example.com"}[5m])) by (le)
)阻止出口流量
yaml
# Block all Egress by default
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
name: default
namespace: default
spec:
egress:
- hosts:
- "./*" # Allow only same namespace
- "istio-system/*" # Allow istio-system
outboundTrafficPolicy:
mode: REGISTRY_ONLY # Allow only those registered in ServiceEntry最佳实践
1. 显式注册 ServiceEntry
yaml
# Good example: Explicit registration
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: payment-api
namespace: production
annotations:
description: "Payment gateway API"
owner: "payments-team"
sla: "99.9%"
spec:
hosts:
- api.payment.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS2. 始终应用 Circuit Breaker
yaml
# Always apply Circuit Breaker for external services
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: external-api-protection
spec:
host: api.example.com
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 10
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 3
interval: 30s
baseEjectionTime: 120s3. Timeout 设置
yaml
# Set explicit Timeout for external services
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: external-api-timeout
spec:
hosts:
- api.example.com
http:
- route:
- destination:
host: api.example.com
timeout: 10s # Explicit Timeout
retries:
attempts: 2
perTryTimeout: 5s4. 使用 Egress Gateway(生产环境)
yaml
# Control external traffic through Egress Gateway in production
# - Centralized monitoring
# - Easy IP whitelist management
# - Consistent security policies5. Namespace 隔离
yaml
# Isolate ServiceEntry by namespace
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
name: default
namespace: team-a
spec:
egress:
- hosts:
- "team-a/*" # Only own namespace
- "istio-system/*"
- "external/*" # Shared external services
outboundTrafficPolicy:
mode: REGISTRY_ONLY6. 文档模板
yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-service
annotations:
# Service information
service-description: "Third-party payment API"
service-owner: "payments-team@company.com"
service-documentation: "https://wiki.company.com/payment-api"
# SLA information
sla-availability: "99.9%"
sla-latency-p95: "500ms"
rate-limit: "1000 req/min"
# Cost information
cost-per-request: "$0.01"
monthly-budget: "$10000"
# Incident response
oncall: "payments-oncall"
escalation: "CTO"
fallback-strategy: "Use cached data"