ドライラン
このタスクでは、新しい実験的なアノテーションistio.io/dry-run
を使用して、ポリシーを実際に適用せずにドライランすることで、Istioの認可ポリシーを設定する方法を示します。
ドライランのアノテーションを使用すると、認可ポリシーを本番トラフィックに適用する前に、その効果をより良く理解できます。これにより、誤った認可ポリシーによって本番トラフィックが中断するリスクを軽減できます。
始める前に
このタスクを開始する前に、次のことを行ってください。
Istioの認可の概念を読んでください。
Istioのインストールガイドに従ってIstioをインストールしてください。
ドライランのトレース結果を確認するためにZipkinをデプロイします。Zipkinタスクに従って、クラスターにZipkinをインストールしてください。
ドライランのメトリック結果を確認するためにPrometheusをデプロイします。Prometheusタスクに従って、クラスターにPrometheusをインストールしてください。
テストワークロードをデプロイします
このタスクでは、
httpbin
とcurl
の2つのワークロードを使用します。どちらも名前空間foo
にデプロイされます。両方のワークロードはEnvoyプロキシサイドカーで実行されます。次のコマンドでfoo
名前空間を作成し、ワークロードをデプロイします。$ kubectl create ns foo $ kubectl label ns foo istio-injection=enabled $ kubectl apply -f @samples/httpbin/httpbin.yaml@ -n foo $ kubectl apply -f @samples/curl/curl.yaml@ -n foo
ドライランのログ結果を確認するためにプロキシのデバッグレベルのログを有効にします
$ istioctl proxy-config log deploy/httpbin.foo --level "rbac:debug" | grep rbac rbac: debug
次のコマンドで
curl
がhttpbin
にアクセスできることを確認します$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" 200
ドライランポリシーの作成
次のコマンドで、ドライランのアノテーション
"istio.io/dry-run": "true"
を使用して認可ポリシーを作成します$ kubectl apply -n foo -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: deny-path-headers annotations: "istio.io/dry-run": "true" spec: selector: matchLabels: app: httpbin action: DENY rules: - to: - operation: paths: ["/headers"] EOF
次のコマンドを使用すると、既存の認可ポリシーをすばやくドライランモードに変更することもできます
$ kubectl annotate --overwrite authorizationpolicies deny-path-headers -n foo istio.io/dry-run='true'
ポリシーがドライランモードで作成されているため、パス
/headers
へのリクエストが許可されていることを確認します。次のコマンドを実行して、curl
からhttpbin
に20件のリクエストを送信します。このリクエストには、常にZipkinトレースをトリガーするためのヘッダーX-B3-Sampled: 1
が含まれています$ for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/headers -H "X-B3-Sampled: 1" -s -o /dev/null -w "%{http_code}\n"; done 200 200 200 ...
プロキシログでのドライラン結果の確認
ドライランの結果は、shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
の形式でプロキシのデバッグログにあります。次のコマンドを実行してログを確認します
$ kubectl logs "$(kubectl -n foo -l app=httpbin get pods -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo | grep "shadow denied"
2021-11-19T20:20:48.733099Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
2021-11-19T20:21:45.502199Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
2021-11-19T20:22:33.065348Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
...
ログの詳細については、トラブルシューティングガイドも参照してください。
Prometheus を使用したメトリクスでのドライラン結果の確認
次のコマンドでPrometheusダッシュボードを開きます
$ istioctl dashboard prometheus
Prometheusダッシュボードで、次のメトリックを検索します
envoy_http_inbound_0_0_0_0_80_rbac{authz_dry_run_action="deny",authz_dry_run_result="denied"}
クエリされたメトリックの結果を次のように確認します
envoy_http_inbound_0_0_0_0_80_rbac{app="httpbin",authz_dry_run_action="deny",authz_dry_run_result="denied",instance="10.44.1.11:15020",istio_io_rev="default",job="kubernetes-pods",kubernetes_namespace="foo",kubernetes_pod_name="httpbin-74fb669cc6-95qm8",pod_template_hash="74fb669cc6",security_istio_io_tlsMode="istio",service_istio_io_canonical_name="httpbin",service_istio_io_canonical_revision="v1",version="v1"} 20
クエリされたメトリックの値は
20
です(送信したリクエスト数によっては異なる値になる場合があります。値が0より大きければ問題ありません)。これは、ポート80
のhttpbin
ワークロードに適用されたドライランポリシーが1つのリクエストに一致したことを意味します。ポリシーがドライランモードでなかった場合、そのリクエストは拒否されます。以下はPrometheusダッシュボードのスクリーンショットです
Prometheusダッシュボード
Zipkin を使用したトレーシングでのドライラン結果の確認
次のコマンドでZipkinダッシュボードを開きます
$ istioctl dashboard zipkin
curl
からhttpbin
へのリクエストのトレース結果を見つけます。Zipkinの遅延によりトレース結果が表示されない場合は、さらにリクエストを送信してみてください。トレース結果では、名前空間
foo
のドライランポリシーdeny-path-headers
によってリクエストが拒否されたことを示す次のカスタムタグが見つかるはずですistio.authorization.dry_run.deny_policy.name: ns[foo]-policy[deny-path-headers]-rule[0] istio.authorization.dry_run.deny_policy.result: denied
以下はZipkinダッシュボードのスクリーンショットです
Zipkinダッシュボード
まとめ
プロキシのデバッグログ、Prometheusメトリック、Zipkinトレースの結果は、ドライランポリシーがリクエストを拒否することを示しています。ドライランの結果が期待どおりでない場合は、ポリシーをさらに変更できます。
より多くの本番トラフィックでテストできるように、ドライランポリシーをしばらく維持することをお勧めします。
ドライランの結果に確信が持てたら、ドライランモードを無効にして、ポリシーが実際にリクエストを拒否するように開始できます。これは、次のいずれかの方法で実現できます
ドライランのアノテーションを完全に削除します。または
ドライランのアノテーションの値を
false
に変更します。
制限事項
ドライランのアノテーションは現在実験段階であり、次の制限があります
ドライランのアノテーションは現在、ALLOWポリシーとDENYポリシーのみをサポートしています。
プロキシでALLOWポリシーとDENYポリシーが別々に適用されるという事実により、ALLOWポリシーとDENYポリシーに対して2つの個別のドライラン結果(つまり、ログ、メトリック、トレースタグ)があります。リクエストはALLOWポリシーによって許可される可能性があっても、別のDENYポリシーによって拒否される可能性があるため、両方のドライラン結果を考慮する必要があります。
プロキシログ、メトリック、トレースのドライラン結果は手動トラブルシューティング用であり、事前の通知なしにいつでも変更される可能性があるため、APIとして使用しないでください。
クリーンアップ
構成から名前空間
foo
を削除します$ kubectl delete namespace foo
不要になった場合はPrometheusとZipkinを削除します。