Istio の一般的なエラーと解決策
対応バージョン: Istio 1.28 最終更新: February 19, 2026
このドキュメントでは、Istio の使用時に発生する最も一般的なエラーとその解決策をまとめます。
目次
- Pod 終了時の接続エラー
- Sidecar インジェクションの問題
- mTLS 接続の失敗
- VirtualService ルーティングの失敗
- Gateway 設定の問題
- メモリとパフォーマンスの問題
- 証明書の有効期限切れ
- DNS 解決の失敗
- Envoy 初期化タイムアウト
- デバッグツール
Pod 終了時の接続エラー
問題の説明
pod が終了すると、Envoy Sidecar がアプリケーションより先に終了し、接続エラーが発生します。
症状:
Connection reset by peer
Broken pipe
EOF
HTTP 503 Service Unavailable根本原因
根本原因:
- Envoy とアプリケーションが同時に SIGTERM を受信する
- Envoy がアプリケーションより速く終了する
- アプリケーションがリクエストを処理中にもかかわらず Envoy がすでに終了しており、接続が失敗する
解決策
方法 1: Envoy Proxy の preStop Hook を設定する(推奨)
Istio Proxy コンテナに preStop Hook を設定し、すべてのアクティブな接続が閉じるまで待機させます。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
# Envoy waits for active connections to close
proxy.istio.io/config: |
terminationDrainDuration: 30s
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080仕組み:
方法 2: Pod Annotation で Envoy の終了動作を制御する
Pod ごとに Envoy の終了動作を細かく調整できます。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
# Envoy waits for application startup
proxy.istio.io/config: |
holdApplicationUntilProxyStarts: true
terminationDrainDuration: 30s
# Envoy termination timeout
sidecar.istio.io/terminationGracePeriodSeconds: "60"
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myapp
image: myapp:latest設定の説明:
holdApplicationUntilProxyStarts: true: Envoy はアプリケーションより先に起動するterminationDrainDuration: 30s: Envoy は終了時に 30 秒間 Drain を実行するterminationGracePeriodSeconds: 60: pod 終了時の合計猶予期間
方法 3: グローバル設定(IstioOperator)
クラスター全体に一貫した終了ポリシーを適用します。
yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-controlplane
spec:
meshConfig:
defaultConfig:
terminationDrainDuration: 30s
holdApplicationUntilProxyStarts: true
values:
global:
proxy:
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- |
# Start Envoy drain
curl -X POST http://localhost:15000/drain_listeners?graceful
# Wait for active connections
while [ $(netstat -plunt | grep tcp | grep -v TIME_WAIT | wc -l | xargs) -ne 0 ]; do
sleep 1;
done推奨設定:
terminationDrainDuration: 30 秒(アクティブな接続の Drain 時間)terminationGracePeriodSeconds: 60 秒(SIGKILL 前の猶予期間)- Envoy がアクティブな接続を確認し、グレースフルシャットダウンを実行する
検証方法
bash
# 1. Check logs during pod termination
kubectl logs -f <pod-name> -c istio-proxy --previous
# 2. Check connection status during termination
kubectl exec <pod-name> -c istio-proxy -- netstat -an | grep ESTABLISHED
# 3. Check termination events
kubectl get events --field-selector involvedObject.name=<pod-name>ベストプラクティス
yaml
# Recommended configuration template
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
# Envoy termination behavior control
proxy.istio.io/config: |
holdApplicationUntilProxyStarts: true
terminationDrainDuration: 30s
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
# Optional: application graceful shutdown
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- |
# Disable readiness (optional)
touch /tmp/not-ready
# Wait for application requests to complete
sleep 5チェックリスト:
- Envoy の terminationDrainDuration を設定する(最重要)
- holdApplicationUntilProxyStarts: true(起動順序を保証)
- terminationGracePeriodSeconds を十分に設定する(最小 60 秒)
- ReadinessProbe を設定する(終了時に素早く非正常状態へ移行する)
- アプリケーションのグレースフルシャットダウンを実装する(任意)
- モニタリングとロギングを設定する
重要なポイント:
- アプリケーションコンテナに sleep を追加しないでください。
- Envoy を Drain モードでグレースフルシャットダウンするよう設定してください。
Sidecar インジェクションの問題
問題 1: Sidecar がインジェクトされない
症状:
bash
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].name}'
# Output: myapp (no istio-proxy)原因と解決策:
1. Namespace Label がない
bash
# Check
kubectl get namespace <namespace> --show-labels
# Solution
kubectl label namespace <namespace> istio-injection=enabled2. Pod Annotation によりインジェクションが無効化されている
yaml
# Incorrect configuration
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/inject: "false" # <- Injection disabled解決策:
yaml
# Correct configuration
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/inject: "true"3. Istio Sidecar Injector の動作を確認する
bash
# Check sidecar injector webhook
kubectl get mutatingwebhookconfigurations
# Check Istio injector logs
kubectl logs -n istio-system -l app=sidecar-injector問題 2: Sidecar のリソース不足
症状:
OOMKilled
CrashLoopBackOff
Error: container has runAsNonRoot and image has non-numeric user解決策:
yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/proxyCPU: "200m"
sidecar.istio.io/proxyMemory: "256Mi"
sidecar.istio.io/proxyCPULimit: "1000m"
sidecar.istio.io/proxyMemoryLimit: "512Mi"
spec:
containers:
- name: myapp
image: myapp:latestmTLS 接続の失敗
問題の説明
症状:
upstream connect error or disconnect/reset before headers
503 Service Unavailable
SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER原因 1: PeerAuthentication モードの不一致
解決策:
yaml
# Apply consistent mTLS policy across namespace
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT # All services STRICT mode原因 2: DestinationRule と PeerAuthentication の競合
yaml
# Incorrect example
---
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
trafficPolicy:
tls:
mode: DISABLE # <- Conflict!解決策:
yaml
# Correct example
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
trafficPolicy:
tls:
mode: ISTIO_MUTUAL # Matches PeerAuthenticationデバッグコマンド
bash
# 1. Check mTLS status
istioctl x describe pod <pod-name> -n <namespace>
# 2. Check PeerAuthentication policies
kubectl get peerauthentication -A
# 3. Check DestinationRule TLS settings
kubectl get destinationrule -A -o yaml | grep -A 5 "tls:"
# 4. Check Envoy cluster TLS settings
istioctl proxy-config clusters <pod-name> -n <namespace> --fqdn <service-name>VirtualService ルーティングの失敗
問題 1: トラフィックがルーティングされない
症状:
404 Not Found
default backend - 404原因と解決策:
Host の不正な一致
yaml
# Incorrect example
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com # <- DNS name
http:
- route:
- destination:
host: myapp # <- Kubernetes Service name解決策:
yaml
# Correct example
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
namespace: default
spec:
hosts:
- myapp # Exactly matches Kubernetes Service name
- myapp.default.svc.cluster.local # Also add FQDN
http:
- route:
- destination:
host: myapp問題 2: Subset が見つからない
症状:
no healthy upstream
subset not found原因:
yaml
# VirtualService exists but DestinationRule is missing
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
http:
- route:
- destination:
host: myapp
subset: v1 # <- Subset not defined解決策:
yaml
# Add DestinationRule
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2デバッグ
bash
# 1. Validate VirtualService
istioctl analyze -n <namespace>
# 2. Check routing rules
istioctl proxy-config routes <pod-name> -n <namespace>
# 3. Check VirtualService status
kubectl get virtualservice <name> -n <namespace> -o yamlGateway 設定の問題
問題 1: トラフィックが Gateway に到達しない
症状:
bash
curl: (7) Failed to connect to example.com port 443: Connection refused原因と解決策:
1. Gateway Service を確認する
bash
# Check Gateway Service status
kubectl get svc -n istio-system istio-ingressgateway
# Check External IP
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'2. Gateway と VirtualService の接続を確認する
yaml
# Incorrect example
---
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: myapp-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "example.com"
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "example.com"
gateways:
- my-gateway # <- Gateway name typo!解決策:
yaml
# Correct example
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "example.com"
gateways:
- myapp-gateway # Exactly matches Gateway name問題 2: HTTPS 証明書エラー
症状:
SSL certificate problem: self signed certificate解決策:
yaml
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: myapp-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: myapp-tls-secret # <- Specify exact Secret name
hosts:
- "example.com"bash
# Create TLS Secret
kubectl create secret tls myapp-tls-secret \
--cert=path/to/cert.pem \
--key=path/to/key.pem \
-n istio-systemメモリとパフォーマンスの問題
問題 1: Envoy のメモリ使用量増加
症状:
OOMKilled
Memory usage > 1GB per pod原因:
- 作成される listener/cluster が多すぎる
- 大きな ConfigMap/Secret
- メモリリーク
解決策:
yaml
# Limit scope with Sidecar resource
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
name: default
namespace: default
spec:
egress:
- hosts:
- "./*" # Same namespace only
- "istio-system/*" # istio-system onlyyaml
# Envoy resource limits
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/proxyMemory: "512Mi"
sidecar.istio.io/proxyMemoryLimit: "1Gi"問題 2: 高レイテンシー
症状:
- P99 レイテンシーが 1 秒を超える
- タイムアウトエラーが頻発する
解決策:
yaml
# Set timeout in VirtualService
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
http:
- route:
- destination:
host: myapp
timeout: 5s # Total request timeout
retries:
attempts: 3
perTryTimeout: 2s # Timeout per retry証明書の有効期限切れ
問題の説明
症状:
x509: certificate has expired
SSL handshake failed原因:
- Istio CA 証明書の有効期限切れ(デフォルトは 10 年)
- Workload 証明書の有効期限切れ(デフォルトは 24 時間、自動更新)
解決策:
bash
# 1. Check CA certificate
kubectl get secret istio-ca-secret -n istio-system -o jsonpath='{.data.ca-cert\.pem}' | base64 -d | openssl x509 -noout -dates
# 2. Check workload certificates
istioctl proxy-config secret <pod-name> -n <namespace>
# 3. Regenerate CA certificate
istioctl x ca rootDNS 解決の失敗
問題の説明
症状:
no such host
DNS resolution failed解決策:
yaml
# Register external service with ServiceEntry
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: DNSEnvoy 初期化タイムアウト
問題の説明
症状:
waiting for Envoy proxy to be ready
Readiness probe failed解決策:
yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
proxy.istio.io/config: |
holdApplicationUntilProxyStarts: true
spec:
containers:
- name: myapp
image: myapp:latest
readinessProbe:
initialDelaySeconds: 10 # Wait for Envoy initializationデバッグツール
istioctl コマンド
bash
# 1. Analyze pod status
istioctl x describe pod <pod-name> -n <namespace>
# 2. Validate configuration
istioctl analyze -A
# 3. Check Envoy configuration
istioctl proxy-config all <pod-name> -n <namespace>
# 4. Change Envoy log level
istioctl proxy-config log <pod-name> --level debug
# 5. Generate bug report
istioctl bug-reportEnvoy Admin API
bash
# Port-forward to Envoy admin port
kubectl port-forward <pod-name> 15000:15000
# 1. Check cluster status
curl localhost:15000/clusters
# 2. Check statistics
curl localhost:15000/stats/prometheus
# 3. Configuration dump
curl localhost:15000/config_dump
# 4. Change logging level
curl -X POST localhost:15000/logging?level=debug一般的なログ確認
bash
# Application logs
kubectl logs <pod-name> -c <container-name>
# Envoy logs
kubectl logs <pod-name> -c istio-proxy
# Previous container logs (if restarted)
kubectl logs <pod-name> -c istio-proxy --previous
# Real-time logs
kubectl logs -f <pod-name> -c istio-proxy参考資料
公式ドキュメント
関連ドキュメント
最終更新: November 27, 2025