Pod の起動時間
このセクションでは、Pod の起動時間に関する Cloud Service Mesh の一般的な問題とその解決方法について説明します。さらにサポートが必要な場合は、サポートの利用をご覧ください。
Pod の起動と Envoy 構成の同期
一部の Cloud Service Mesh 環境と Istio 環境で Pod の起動中によく発生する問題の一つは、アプリケーションの起動完了と Envoy プロキシの構成の同期に関するものです。この問題は、アプリケーション コンテナと Envoy サイドカーの同時起動によって発生します。アプリケーションは、Envoy プロキシが初期化を完了してコントロール プレーンから構成を受信する前に、起動完了を通知する場合があります。これにより、構成されておらずトラフィックを受信する準備ができていない Envoy プロキシに受信リクエストが転送されるという競合状態が発生します。これには、トラフィックを転送するサイドカーがないため、アプリケーションの起動の初期フェーズでリクエストが破棄される可能性、誤って転送される可能性、誤って処理される可能性があります。
緩和戦略
以降のセクションでは、この問題を軽減する方法について説明します。
グローバル メッシュ構成: holdApplicationUntilProxyStarts
最初の選択肢は、Istio メッシュ構成で holdApplicationUntilProxyStarts: true
を設定することです。デフォルトでは、それがオフになっています。このフラグは、Pod のプロキシがトラフィックを受け入れるまでアプリケーションの起動を遅らせる動作を追加します。
この構成を追加するとこの競合は解消されますが、それが前に有効にされていない場合、新しい Pod に対し、アプリケーションの起動が完了するまでの時間に遅延が生じる可能性があります。
readiness プローブ
もう一つの解決策は、アプリケーションと Envoy のヘルスチェックの両方を組み込んだ readiness プローブを実装することです。readiness プローブは、Pod がトラフィックを受信する準備ができていることを Kubernetes に通知します。重要なのは、readinessProbe のロジックがアプリケーションの準備状況だけでなく、Envoy プロキシのステータスも確認することです。これは、Envoy の管理者ポートにヘルス ステータスをクエリすることで実現できます。両方のチェックを組み合わせることで、Kubernetes は、アプリケーションと Envoy の両方が完全に初期化されて構成されるまで、トラフィックが Pod に転送されないようにします。
この方法には柔軟性があり、起動ロジックと準備ロジックをより込み入ったものにできますが、複雑さが増すというデメリットがあります。
healthcheck.sh
ファイルは、次のコードから作成します。
#!/bin/sh
APP_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8080/health)
ENVOY_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" \
http://localhost:9901/ready)
if [[ "$APP_HEALTH" -eq 200 && "$ENVOY_HEALTH" -eq 200 ]]; then
exit 0
else
exit 1
fi
IP / ポートは、アプリケーション コンテナと Envoy の IP / ポートに置き換えます。
次の YAML ファイルでは、前に作成したスクリプトを使用する readinessProbe を定義しています。
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-envoy
spec:
containers:
- name: application
<…>
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
exec:
command:
- /healthcheck.sh # using the script
- name: envoy
<…>