Istioサービスのヘルスチェック

KubernetesのLivenessプローブとReadinessプローブでは、LivenessプローブとReadinessプローブを設定するいくつかの方法について説明しています

  1. コマンド
  2. HTTPリクエスト
  3. TCPプローブ
  4. gRPCプローブ

コマンドアプローチは変更なしで機能しますが、HTTPリクエスト、TCPプローブ、およびgRPCプローブでは、IstioがPod設定を変更する必要があります。

`liveness-http`サービスへのヘルスチェックリクエストは、Kubeletによって送信されます。これは、KubeletがIstio発行の証明書を持っていないため、相互TLSが有効になっている場合に問題になります。そのため、ヘルスチェックリクエストは失敗します。

Istioはすべての着信トラフィックをサイドカーにリダイレクトするため、すべてのTCPポートが開いているように見えるため、TCPプローブチェックは特別な処理が必要です。 Kubeletは、指定されたポートでリスニングしているプロセスがあるかどうかを確認するだけなので、サイドカーが実行されている限り、プローブは常に成功します。

Istioは、プローブリクエストがサイドカーエージェントに送信されるように、アプリケーションの`PodSpec` readiness / livenessプローブを書き換えることで、これらの両方の問題を解決します。

Livenessプローブ書き換えの例

readiness / livenessプローブがアプリケーションの`PodSpec`レベルでどのように書き換えられるかを示すために、liveness-http-same-portサンプルを使用してみましょう。

まず、サンプルの名前空間を作成してラベル付けします

$ kubectl create namespace istio-io-health-rewrite
$ kubectl label namespace istio-io-health-rewrite istio-injection=enabled

次に、サンプルアプリケーションをデプロイします

$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-http
  namespace: istio-io-health-rewrite
spec:
  selector:
    matchLabels:
      app: liveness-http
      version: v1
  template:
    metadata:
      labels:
        app: liveness-http
        version: v1
    spec:
      containers:
      - name: liveness-http
        image: docker.io/istio/health:example
        ports:
        - containerPort: 8001
        livenessProbe:
          httpGet:
            path: /foo
            port: 8001
          initialDelaySeconds: 5
          periodSeconds: 5
EOF

デプロイ後、Podのアプリケーションコンテナを調べて、変更されたパスを確認できます

$ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o json | jq '.spec.containers[0].livenessProbe.httpGet'
{
  "path": "/app-health/liveness-http/livez",
  "port": 15020,
  "scheme": "HTTP"
}

元の`livenessProbe`パスは、サイドカーコンテナの環境変数`ISTIO_KUBE_APP_PROBERS`の新しいパスにマップされています

$ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o=jsonpath="{.spec.containers[1].env[?(@.name=='ISTIO_KUBE_APP_PROBERS')]}"
{
  "name":"ISTIO_KUBE_APP_PROBERS",
  "value":"{\"/app-health/liveness-http/livez\":{\"httpGet\":{\"path\":\"/foo\",\"port\":8001,\"scheme\":\"HTTP\"},\"timeoutSeconds\":1}}"
}

HTTP および gRPC リクエストの場合、サイドカーエージェントはリクエストをアプリケーションにリダイレクトし、レスポンスボディを取り除き、レスポンスコードのみを返します。TCP プローブの場合、サイドカーエージェントはトラフィックのリダイレクトを回避しながらポートチェックを実行します。

問題のあるプローブの書き換えは、すべての組み込み Istio 構成プロファイル でデフォルトで有効になっていますが、以下で説明するように無効にすることができます。

コマンドアプローチを使用したLivenessプローブとReadinessプローブ

Istio は、このアプローチを実装する liveness サンプル を提供しています。相互 TLS が有効になっている状態で動作することを示すために、まずサンプル用の名前空間を作成します。

$ kubectl create ns istio-io-health

厳密な相互 TLS を構成するには、以下を実行します。

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-io-health"
spec:
  mtls:
    mode: STRICT
EOF

次に、ディレクトリを Istio インストールのルートに変更し、次のコマンドを実行してサンプルサービスをデプロイします。

Zip
$ kubectl -n istio-io-health apply -f <(istioctl kube-inject -f @samples/health-check/liveness-command.yaml@)

liveness プローブが機能していることを確認するには、サンプルポッドのステータスを確認して、実行中であることを確認します。

$ kubectl -n istio-io-health get pod
NAME                             READY     STATUS    RESTARTS   AGE
liveness-6857c8775f-zdv9r        2/2       Running   0           4m

HTTP、TCP、およびgRPCアプローチを使用したLivenessプローブとReadinessプローブ

前述のように、Istio はデフォルトでプローブの書き換えを使用して HTTP、TCP、および gRPC プローブを実装します。この機能は、特定のポッドに対して、またはグローバルに無効にすることができます。

Podのプローブ書き換えを無効にする

ポッドに sidecar.istio.io/rewriteAppHTTPProbers: "false"アノテーションを付ける ことで、プローブの書き換えオプションを無効にすることができます。アノテーションは ポッドリソース に追加してください。他の場所(たとえば、囲んでいるデプロイメントリソース)では無視されます。

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-http
spec:
  selector:
    matchLabels:
      app: liveness-http
      version: v1
  template:
    metadata:
      labels:
        app: liveness-http
        version: v1
      annotations:
        sidecar.istio.io/rewriteAppHTTPProbers: "false"
    spec:
      containers:
      - name: liveness-http
        image: docker.io/istio/health:example
        ports:
        - containerPort: 8001
        livenessProbe:
          httpGet:
            path: /foo
            port: 8001
          initialDelaySeconds: 5
          periodSeconds: 5
EOF

このアプローチにより、Istio を再インストールすることなく、個々のデプロイメントでヘルスチェックプローブの書き換えを段階的に無効にすることができます。

プローブ書き換えをグローバルに無効にする

--set values.sidecarInjectorWebhook.rewriteAppHTTPProbe=false を使用して Istio をインストール することで、プローブの書き換えをグローバルに無効にすることができます。**または**、Istio サイドカーインジェクターの構成マップを更新します。

$ kubectl get cm istio-sidecar-injector -n istio-system -o yaml | sed -e 's/"rewriteAppHTTPProbe": true/"rewriteAppHTTPProbe": false/' | kubectl apply -f -

クリーンアップ

サンプルに使用した名前空間を削除します。

$ kubectl delete ns istio-io-health istio-io-health-rewrite
この情報は役に立ちましたか?
改善のための提案はありますか?

フィードバックありがとうございます!