サイドカーはメッシュアプリケーションが受信するリクエストをインターセプトするため、Alibaba Cloud Service Mesh (ASM) でサイドカーがインジェクトされたアプリケーションの HTTP および TCP ヘルスチェックは、HTTP ヘルスチェックが一貫して失敗するなど、予期しない動作をする可能性があります。ヘルスチェックリダイレクトを有効にすることで、ヘルスチェックが期待どおりに機能するようになります。
背景情報
メッシュ内のアプリケーションにおける HTTP ヘルスチェックと TCP ヘルスチェックの予期しない動作を、次の表に示します。ヘルスチェックを正常に動作させるには、アノテーションを追加してヘルスチェックリダイレクションを有効にする必要があります。
|
タイプ |
説明 |
|
HTTP ヘルスチェック |
Kubernetes クラスターでは、kubelet がすべての Pod のヘルスチェックリクエストを送信します。相互 TLS (mTLS) モードが有効になると、メッシュ内のアプリケーションは TLS 経由で通信する必要があります。kubelet はメッシュの一部ではないため、ASM がアプリケーションに発行する証明書を保持していません。その結果、HTTP ヘルスチェックリクエストは拒否され、ヘルスチェックは一貫して失敗します。 |
|
TCP ヘルスチェック |
リクエストをインターセプトするため、サイドカーはメッシュ内アプリケーションの Pod の全ポートをリッスンします。TCP ヘルスチェックでは、kubelet はアプリケーションが Pod に設定されたポートをリッスンしているかを確認し、アプリケーションのヘルスステータスを判断します。 このため、サイドカーがアプリケーションにインジェクトされ実行されている限り、アプリケーションの実際の状態に関係なく、ヘルスチェックは常に成功します。たとえば、アプリケーションに誤ったポートを設定した場合、Pod のヘルスチェックは常に失敗して Pod を NotReady ステータスに維持するべきですが、実際には成功してしまいます。 |
ASM で mTLS モードを有効にしない場合、ヘルスチェックリダイレクションを設定しなくても、アプリケーション Pod で HTTP ヘルスチェックを使用できます。
デフォルトでは、メッシュトポロジグラフにアプリケーションサービスのヘルスチェックリクエストが表示されます。多くの場合、これらのリクエストがトラフィック統計のノイズとなる可能性があります。メッシュ内のアプリケーションでヘルスチェックリダイレクションを有効にすると、これらの内部的なヘルスチェックリクエストは統計から除外されます。
ヘルスチェックリダイレクションの仕組み
ヘルスチェックリダイレクションは、ワークロードの Pod テンプレートにある 1 つのアノテーションによって制御されます。sidecar.istio.io/rewriteAppHTTPProbers: "true" を template.metadata.annotations の下に追加し、ワークロードを適用してください。これにより、ASM はアプリケーションコンテナに設定されたヘルスチェックを、ポート 15020 での HTTP ヘルスチェックとして書き換えます。
メッシュ内のアプリケーションにとって、15020 はメッシュの可観測性に使われる特別なポートです。このポートに送信されるトラフィックはサイドカーにインターセプトされないため、TLS モードの要件を満たす必要はありません。ヘルスチェックリダイレクションが有効になると、サイドカーコンテナで実行されている pilot-agent サービスがポート 15020 をリッスンし、kubelet からのヘルスチェックを受信します。ISTIO_KUBE_APP_PROBERS 環境変数内のヘルスチェック設定に基づき、pilot-agent サービスはヘルスチェックリクエストをアプリケーションコンテナに転送します。これにより、HTTP ヘルスチェックが期待どおりに実行されます。
TCP ヘルスチェックの場合も、ASM のヘルスチェックリダイレクションは同じ処理を行い、ポート 15020 での HTTP ヘルスチェックとして書き換えます。ISTIO_KUBE_APP_PROBERS 環境変数内の TCP ヘルスチェック設定に基づき、pilot-agent サービスはアプリケーションコンテナに設定された TCP ヘルスチェックポートをプローブします。実際の TCP ヘルスチェックが失敗した場合、pilot-agent サービスはステータスコード 500 を返し、ヘルスチェックが失敗したことを示します。
前提条件
-
アプリケーションが ASM に追加され、サイドカーがアプリケーション Pod にインジェクトされていること。
-
kubectl がアプリケーションを実行するクラスターに接続されていること。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
HTTP ヘルスチェックリダイレクションの有効化
次の例では、Nginx アプリケーションを使用して HTTP ヘルスチェックリダイレクションを有効にします。mTLS モードが有効になると、Nginx アプリケーションに設定された HTTP ヘルスチェックは一貫して失敗します。その後、Nginx アプリケーションに対してヘルスチェックリダイレクションを有効にします。Pod イベントにヘルスチェックの失敗イベントが含まれず、Pod が Ready ステータスであれば、アプリケーションの HTTP ヘルスチェックリダイレクションは有効になっています。
手順1:名前空間の STRICT mTLS モードの有効化
ASM コンソールで、対象の ASM インスタンスの [PeerAuthentication] ページで mTLS モードを設定します。この手順で設定する mTLS モードは、選択した名前空間に適用されます。
ASM コンソール にログオンします。
左側のナビゲーションウィンドウで、 を選択します。
[メッシュ管理] ページで、構成する ASM インスタンスを見つけます。[管理] 列で ASM インスタンスの名前をクリックするか、[アクション] をクリックします。
ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウの を選択します。
-
ピア身分認証 (Peer Authentication) ページの上部で、名前空間を選択し、次に グローバル双方向 TLS モードの設定 をクリックします。
-
グローバル双方向 TLS モードの設定 パネルで、mTLS モード (名前空間レベル) (名前空間全体) を STRICT - 双方向 TLS 認証に厳格に準拠します に設定し、作成 をクリックします。
手順2:Nginx アプリケーションのデプロイ
-
Nginx アプリケーションをデプロイします。
-
次の内容で http-liveness.yaml という名前のファイルを作成します。
readinessProbe パラメーターにある httpGet フィールドは、アプリケーションに対する HTTP ヘルスチェックを定義します。
-
次のコマンドを実行して、Nginx アプリケーションをデプロイします。
kubectl apply -f http-liveness.yaml
-
-
アプリケーションのヘルスチェックステータスを表示します。
-
次のコマンドを実行して、Nginx アプリケーションの Pod 名を表示します。
kubectl get pod | grep nginx -
次のコマンドを実行して、ポッドイベントを表示します。
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 が NotReady ステータスのままであることを示しています。
-
手順3:Nginx アプリケーションのヘルスチェックリダイレクションの有効化
-
次のコマンドを実行して http-liveness.yaml を編集します。
vim http-liveness.yamltemplateパラメーターの下に、以下の内容を追加します。annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"以下のコードは、アノテーションが追加された後の http-liveness.yaml ファイルです。
-
次のコマンドを実行して、Nginx アプリケーションをデプロイします。
kubectl apply -f http-liveness.yaml
手順4:ヘルスチェック結果の確認
-
Pod のヘルスチェックステータスを確認する。
-
次のコマンドを実行して、Nginx アプリケーションのポッド名を表示します。
kubectl get pod | grep nginx -
次のコマンドを実行して、Pod イベントを表示します。
kubectl describe pod <pod_name>出力にはヘルスチェックの失敗イベントは含まれず、Pod は Ready ステータスです。HTTP ヘルスチェックは期待どおりに機能しています。
-
-
次のコマンドを実行して、ヘルスチェックのリダイレクト後のポッドの YAML ファイルを表示します。
kubectl get pod <pod_name> -o yamlヘルスチェックリダイレクトが有効になると、ヘルスチェックポートは 80 から 15020 に、ヘルスチェックパスは /index.html から /app-health/nginx/readyz に変更されます。また、Pod 内のサイドカーコンテナに
ISTIO_KUBE_APP_PROBERS環境変数が追加されます。この変数の値は、ヘルスチェックが書き換えられる前のヘルスチェック設定を JSON 形式でシリアル化したものです。
TCP ヘルスチェックリダイレクションの有効化
次の例では、Nginx アプリケーションを使用して TCP ヘルスチェックリダイレクションを有効にします。手順は HTTP ヘルスチェックリダイレクションの場合と同様ですが、プローブ設定と期待される結果のみが異なります。Nginx アプリケーションには誤ったポートが設定されていますが、TCP ヘルスチェックはアプリケーション Pod で成功してしまい、これは期待される動作ではありません。Nginx アプリケーションのヘルスチェックリダイレクションを有効にすると、TCP ヘルスチェックはアプリケーション Pod で失敗するようになります。これは期待どおりの動作であり、アプリケーションの TCP ヘルスチェックリダイレクションが有効になったことを示します。
手順1:Nginx アプリケーションのデプロイ
-
Nginx アプリケーションをデプロイします。
-
次の内容で tcp-liveness.yamlという名前のファイルを作成します。
次の内容では、ヘルスチェックポートとして 2940 を設定していますが、これは誤りです。Nginx アプリケーションはポート 2940 をリッスンしていません。したがって、アプリケーションがデプロイされた後、ヘルスチェックは常に失敗し、Pod は NotReady ステータスに留まるはずです。
readinessProbe パラメーター配下の tcpSocket フィールドは、アプリケーションの TCP ヘルスチェックを定義します。
-
次のコマンドを実行して Nginx アプリケーションをデプロイします。
kubectl apply -f tcp-liveness.yaml
-
-
アプリケーションのヘルスチェックステータスを表示します。
-
Nginx アプリケーションのポッド名を表示するには、次のコマンドを実行します。
kubectl get pod | grep nginx -
次のコマンドを実行して、ポッドのイベントを表示します。
kubectl describe pod <pod_name>出力にはヘルスチェックの失敗イベントは含まれず、Pod は Ready ステータスです。これは期待される動作ではありません。
-
手順2:Nginx アプリケーションのヘルスチェックリダイレクションの有効化
-
次のコマンドを実行して、tcp-liveness.yaml ファイルを編集します。
vim tcp-liveness.yamltcp-liveness.yaml ファイルで、
templateパラメーターの下に次の内容を追加します。annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"アノテーションを追加した後、tcp-liveness.yaml ファイルは次のようになります。
-
次のコマンドを実行して Nginx アプリケーションをデプロイします。
kubectl apply -f tcp-liveness.yaml
手順3:ヘルスチェック結果の確認
-
アプリケーションのヘルスチェックステータスを表示します。
-
次のコマンドを実行して Nginx アプリケーションのポッド名を表示します。
kubectl get pod | grep nginx -
次のコマンドを実行して、ポッドのイベントを表示します。
kubectl describe pod <pod_name>期待される出力:
Warning Unhealthy 45s kubelet Readiness probe failed: HTTP probe failed with statuscode: 500出力はヘルスチェックが失敗したことを示しており、これは期待される動作です。
-
-
次のコマンドを実行して、ヘルスチェックリダイレクト後のアプリケーションポッドの YAML コンテンツを表示します。
kubectl get pod <pod_name> -o yamlヘルスチェックリダイレクトが有効化されると、元の TCP ヘルスチェックは HTTP ヘルスチェックとして書き換えられます。ヘルスチェックポートは 2940 から 15020 に変更され、HTTP ヘルスチェックのパスは /app-health/nginx/readyz に設定されます。
ISTIO_KUBE_APP_PROBERS環境変数も Pod 内のサイドカーコンテナに追加されます。この変数の値は、ヘルスチェックが書き換えられる前の TCP ヘルスチェック設定を JSON シリアル化したものです。