Service Mesh (ASM) インスタンスにアプリケーションを追加した後、サイドカープロキシがアプリケーションの Pod に挿入されます。サイドカープロキシは、アプリケーションに送信されたすべてのリクエストをインターセプトします。この場合にアプリケーションの HTTP または TCP ヘルスチェックを有効にすると、ヘルスチェックが期待どおりに機能しない可能性があります。たとえば、ヘルスチェックが常に失敗する可能性があります。このトピックでは、ASM インスタンス内のアプリケーションの HTTP または TCP ヘルスチェックリクエストのリダイレクトを設定する方法について説明します。
背景情報
ASM インスタンス内のアプリケーションの TCP または HTTP ヘルスチェックでは、次の問題が発生する可能性があります。これらの問題を解決するには、アノテーションを使用して、ASM インスタンス内のアプリケーションのヘルスチェックリクエストのリダイレクトを設定する必要があります。
種類 | 説明 |
HTTP ヘルスチェックリクエスト | kubelet サービスは、Kubernetes クラスタ内の Pod にヘルスチェックリクエストを送信します。ASM インスタンスに対して相互トランスポート層セキュリティ (mTLS) を有効にした場合、ASM インスタンス内のアプリケーションは TLS を使用して相互に通信する必要があります。 kubelet サービスは ASM インスタンスの一部ではありません。その結果、kubelet サービスは ASM によって発行された TLS 証明書を提供できません。この場合、すべての HTTP ヘルスチェックリクエストはアプリケーションによって拒否され、ヘルスチェックは常に失敗します。 説明 ASM インスタンスに対して mTLS を有効にしない場合、アプリケーションの Pod で HTTP ヘルスチェックを正常に実行できます。この場合、ヘルスチェックリクエストのリダイレクトを設定しなくても、アプリケーションの HTTP ヘルスチェックを有効にできます。 |
TCP ヘルスチェックリクエスト | サイドカープロキシは、ASM インスタンス内の Pod のすべてのポートをリッスンして、リクエストをインターセプトします。アプリケーションの TCP ヘルスチェックを有効にすると、kubelet サービスは、Pod の指定されたポートがアプリケーションによってリッスンされているかどうかを確認します。はいの場合、ヘルスチェックは成功です。 サイドカープロキシが Pod に挿入され、期待どおりに機能する場合、アプリケーションが正常かどうか regardless of に関係なく、ヘルスチェックは常に成功します。たとえば、アプリケーションに無効なポートを設定した場合、ヘルスチェックは失敗し、Pod は準備完了状態にならないはずです。ただし、Pod のヘルスチェックは常に成功します。 |
デフォルトでは、ASM インスタンス内のアプリケーションのヘルスチェックリクエストの呼び出しは、メッシュトポロジに表示されます。ただし、ヘルスチェックが期待どおりに機能しない場合、ヘルスチェックリクエストによってトラフィック統計が不正確になる可能性があります。トラフィック統計の正確性を確保するために、ヘルスチェックリクエストのリダイレクトを設定できます。
HTTP ヘルスチェックリクエストのリダイレクトを設定する
この例では、NGINX アプリケーションが使用されています。 NGINX アプリケーションが存在する ASM インスタンスに対して mTLS を有効にした後、NGINX アプリケーションの HTTP ヘルスチェックは常に失敗します。この場合、NGINX アプリケーションのヘルスチェックリクエストのリダイレクトを設定できます。次に、NGINX アプリケーションの Pod のイベントを確認します。ヘルスチェックの失敗を示すイベントが存在せず、Pod が準備完了状態になっている場合、ヘルスチェックリクエストのリダイレクトがアプリケーションに有効になります。
手順 1:ASM インスタンスのグローバル mTLS モードを有効にする
[ASM コンソール] にログインします。
左側のナビゲーションペインで、 を選択します。
[メッシュ管理] ページで、構成する ASM インスタンスを見つけます。[管理] 列で、ASM インスタンスの名前をクリックするか、[アクション] をクリックします。
ASM インスタンスの詳細ページで、左側のナビゲーションペインの を選択します。
[peerauthentication] ページの上部にある [Namespace] ドロップダウンリストから名前空間を選択し、[グローバル Mtls モードを設定] をクリックします。
[グローバル Mtls モードを設定] ページで、厳格 - Mtls を厳格に適用[mtls モード (名前空間全体)] パラメータに 作成 を選択し、 をクリックします。
手順 2:NGINX アプリケーションをデプロイする
クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続します。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
NGINX アプリケーションをデプロイします。
次の内容を含む http-liveness.yaml ファイルを作成します。
readinessProbe フィールドの httpGet フィールドを指定して、NGINX アプリケーションの HTTP ヘルスチェックを有効にします。
次のコマンドを実行して、NGINX アプリケーションをデプロイします。
kubectl apply -f http-liveness.yaml
NGINX アプリケーションのヘルスチェック結果を表示します。
次のコマンドを実行して、NGINX アプリケーションを実行する Pod の名前を表示します。
kubectl get pod| grep nginx
次のコマンドを実行して、Pod のイベントを表示します。
kubectl describe pod <Pod name>
予期される出力:
Warning Unhealthy 45s kubelet Readiness probe failed: Get "http://172.23.64.22:80/index.html": read tcp 172.23.64.1:54130->172.23.64.22:80: read: connection reset by peer
出力は、Pod の HTTP ヘルスチェックが失敗したことを示しています。この場合、Pod は準備完了状態ではありません。
手順 3:NGINX アプリケーションのヘルスチェックリクエストのリダイレクトを設定する
次のコマンドを実行して、http-liveness.yaml ファイルを開きます。
vim http-liveness.yaml
template
フィールドに次の内容を追加します。annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"
アノテーションを追加した後の http-liveness.yaml ファイルの例を次に示します。
次のコマンドを実行して、NGINX アプリケーションをデプロイします。
kubectl apply -f http-liveness.yaml
手順 4:ヘルスチェック結果が期待どおりであることを確認する
Pod のヘルスチェック結果を表示します。
次のコマンドを実行して、NGINX アプリケーションを実行する Pod の名前を表示します。
kubectl get pod| grep nginx
次のコマンドを実行して、Pod のイベントを表示します。
kubectl describe pod <Pod name>
コマンド出力には、Pod のヘルスチェックの失敗を示すイベントは存在しません。Pod は準備完了状態です。これは、HTTP ヘルスチェックリクエストのリダイレクトがアプリケーションに有効であることを示しています。
次のコマンドを実行して、ヘルスチェックリクエストのリダイレクトを設定した後の Pod の YAML ファイルを表示します。
kubectl get pod nginx-deployment-676f85f66b-7vxct -o yaml
ヘルスチェックリクエストのリダイレクトを設定した後、ヘルスチェックポートはポート 80 からポート 15020 に変更され、ヘルスチェックパスは /index.html から /app-health/nginx/readyz に変更されます。さらに、
ISTIO_KUBE_APP_PROBERS
という名前の環境変数が Pod のサイドカーコンテナに追加されます。この環境変数の値は、JSON 形式の元のヘルスチェック設定からシリアル化されます。ASM にデプロイされたアプリケーションの場合、ポート 15020 は ASM の可観測性専用に使用されます。ポート 15020 に送信されたリクエストは、サイドカープロキシによってインターセプトされません。したがって、ヘルスチェックリクエストは mTLS モードの要件の影響を受けません。ヘルスチェックリクエストのリダイレクトを設定した後、サイドカーコンテナで実行されている pilot-agent サービスはポート 15020 をリッスンします。 pilot-agent サービスは kubelet サービスからヘルスチェックリクエストを受信し、
ISTIO_KUBE_APP_PROBERS
環境変数の値に基づいてこれらのリクエストをアプリケーションコンテナにリダイレクトします。これにより、HTTP ヘルスチェックが期待どおりに機能することが保証されます。
TCP ヘルスチェックリクエストのリダイレクトを設定する
この例では、NGINX アプリケーションが使用され、NGINX アプリケーションに無効なポートが設定されています。 NGINX アプリケーションの TCP ヘルスチェックを有効にすると、失敗するはずの TCP ヘルスチェックは常にアプリケーションに対して成功します。ヘルスチェックリクエストのリダイレクトを設定した後、Pod の TCP ヘルスチェックは失敗します。これは、TCP ヘルスチェックリクエストのリダイレクトが NGINX アプリケーションに有効であることを示しています。
手順 1:NGINX アプリケーションをデプロイする
クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続します。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
NGINX アプリケーションをデプロイします。
次の内容を含む tcp-liveness.yaml ファイルを作成します。
ポート 2940 は、NGINX アプリケーションのヘルスチェックポートとして設定されています。ただし、NGINX アプリケーションはポート 2940 をリッスンしていません。通常のケースでは、NGINX アプリケーションのヘルスチェックは失敗し、Pod は準備完了状態になりません。
readinessProbe フィールドの tcpSocket フィールドを指定して、NGINX アプリケーションの TCP ヘルスチェックを有効にします。
次のコマンドを実行して、NGINX アプリケーションをデプロイします。
kubectl apply -f tcp-liveness.yaml
NGINX アプリケーションのヘルスチェック結果を表示します。
次のコマンドを実行して、NGINX アプリケーションを実行する Pod の名前を表示します。
kubectl get pod| grep nginx
次のコマンドを実行して、Pod のイベントを表示します。
kubectl describe pod <Pod name>
コマンド出力には、ヘルスチェックの失敗を示すイベントは存在しません。この場合、Pod は準備完了状態です。これは期待どおりではありません。
手順 2:NGINX アプリケーションのヘルスチェックリクエストのリダイレクトを設定する
次のコマンドを実行して、tcp-liveness.yaml ファイルを編集します。
vim tcp-liveness.yaml
template
tcp-liveness.yaml ファイルの フィールドに次の内容を追加します。annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"
アノテーションを追加した後の tcp-liveness.yaml ファイルの例を次に示します。
次のコマンドを実行して、NGINX アプリケーションをデプロイします。
kubectl apply -f tcp-liveness.yaml
手順 3:ヘルスチェック結果が期待どおりであることを確認する
NGINX アプリケーションのヘルスチェック結果を表示します。
次のコマンドを実行して、NGINX アプリケーションを実行する Pod の名前を表示します。
kubectl get pod| grep nginx
次のコマンドを実行して、Pod のイベントを表示します。
kubectl describe pod <Pod name>
予期される出力:
Warning Unhealthy 45s kubelet Readiness probe failed: HTTP probe failed with statuscode: 500
出力は、Pod の TCP ヘルスチェックが失敗したことを示しています。これは期待どおりです。
次のコマンドを実行して、ヘルスチェックリクエストのリダイレクトを設定した後の Pod の YAML ファイルを表示します。
kubectl get pod nginx-deployment-746458cdc9-m9t9q -o yaml
ヘルスチェックリクエストのリダイレクトを設定した後、元の TCP リクエストは HTTP リクエストに変換されます。さらに、ヘルスチェックポートはポート 80 からポート 15020 に変更され、パス /app-health/nginx/readyz が HTTP ヘルスチェックに自動的に追加されます。
ISTIO_KUBE_APP_PROBERS
という名前の環境変数が Pod のサイドカーコンテナに追加されます。この環境変数の値は、JSON 形式の元の TCP ヘルスチェック設定からシリアル化されます。ポート 15020 は、変換された HTTP ヘルスチェックリクエストを受信するために使用されます。これは、HTTP ヘルスチェックリクエストのリダイレクト設定と同じです。ヘルスチェックリクエストのリダイレクトを設定した後、サイドカーコンテナで実行されている pilot-agent サービスはポート 15020 をリッスンします。 pilot-agent サービスは kubelet サービスからヘルスチェックリクエストを受信し、
ISTIO_KUBE_APP_PROBERS
環境変数の値に基づいてアプリケーションコンテナに設定されている TCP ヘルスチェックポートの状態を確認します。 TCP ヘルスチェックが失敗した場合、pilot-agent サービスは 500 ステータスコードを返します。このステータスコードは、ヘルスチェックの失敗を示します。