Istioサービスのヘルスチェック
KubernetesのLivenessプローブとReadinessプローブでは、LivenessプローブとReadinessプローブを設定するいくつかの方法について説明しています
コマンドアプローチは変更なしで機能しますが、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 インストールのルートに変更し、次のコマンドを実行してサンプルサービスをデプロイします。
$ 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
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: liveness-grpc
spec:
selector:
matchLabels:
app: liveness-grpc
version: v1
template:
metadata:
labels:
app: liveness-grpc
version: v1
annotations:
sidecar.istio.io/rewriteAppHTTPProbers: "false"
spec:
containers:
- name: etcd
image: registry.k8s.io/etcd:3.5.1-0
command: ["--listen-client-urls", "http://0.0.0.0:2379", "--advertise-client-urls", "http://127.0.0.1:2379", "--log-level", "debug"]
ports:
- containerPort: 2379
livenessProbe:
grpc:
port: 2379
initialDelaySeconds: 10
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