ServiceEntry
ServiceEntry は、外部サービスを Istio service mesh に登録し、内部サービスと同様に管理できるようにします。
目次
- ServiceEntry が必要な理由
- ServiceEntry の概要
- 名前解決モード
- ロケーション設定
- 実践例
- Egress Gateway との組み合わせ
- セキュリティと TLS
- モニタリングと制御
- ベストプラクティス
ServiceEntry が必要な理由
外部サービス管理の必要性
デフォルトでは、Istio mesh は外部サービスへのトラフィックを制御しません。ServiceEntry を使用すると、次のことが可能になります。
主な利点
| 機能 | ServiceEntry なし | ServiceEntry あり |
|---|---|---|
| モニタリング | ブラックホール | 完全なメトリクス収集 |
| トラフィック制御 | 不可能 | Timeout、Retry、Circuit Breaker |
| セキュリティ | 限定的 | mTLS、証明書管理 |
| Egress 制御 | すべての外部トラフィックを許可 | 明示的な許可/ブロック |
| Service Discovery | 手動管理 | 自動 DNS ルックアップ |
ServiceEntry の概要
ServiceEntry は、外部サービスを Istio service registry に追加します。
基本構造
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 proxy
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 の登録
シナリオ: Payment Gateway 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 Service の登録
シナリオ: 外部 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: 3sEgress 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)
)Egress トラフィックのブロック
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"