Istioctl Describe でメッシュを理解する

Istio 1.3 では、istioctl experimental describe コマンドが導入されました。この CLI コマンドは、Pod に影響を与える設定を理解するために必要な情報を提供します。このガイドでは、この実験的なサブコマンドを使用して、Podがメッシュ内にあるかどうかを確認し、その構成を検証する方法を説明します。

コマンドの基本的な使い方は次のとおりです。

$ istioctl experimental describe pod <pod-name>[.<namespace>]

Pod名に名前空間を追加することは、デフォルト以外の名前空間を指定するために istioctl-n オプションを使用するのと同じ効果があります。

このガイドでは、メッシュにBookinfoサンプルがデプロイされていることを前提としています。まだデプロイしていない場合は、アプリケーションのサービスを開始し、イングレスのIPとポートを決定してから続行してください。

ポッドがメッシュ内にあることを確認する

istioctl describe コマンドは、Envoy プロキシがPodに存在しない場合、またはプロキシが起動していない場合に警告を返します。さらに、このコマンドは、Podに対するIstioの要件の一部が満たされていない場合にも警告します。

たとえば、次のコマンドは、kube-dns Podにサイドカーがないため、サービスメッシュの一部ではないことを示す警告を生成します。

$ export KUBE_POD=$(kubectl -n kube-system get pod -l k8s-app=kube-dns -o jsonpath='{.items[0].metadata.name}')
$ istioctl x describe pod -n kube-system $KUBE_POD
Pod: coredns-f9fd979d6-2zsxk
   Pod Ports: 53/UDP (coredns), 53 (coredns), 9153 (coredns)
WARNING: coredns-f9fd979d6-2zsxk is not part of mesh; no Istio sidecar
--------------------
2021-01-22T16:10:14.080091Z     error   klog    an error occurred forwarding 42785 -> 15000: error forwarding port 15000 to pod 692362a4fe313005439a873a1019a62f52ecd02c3de9a0957cd0af8f947866e5, uid : failed to execute portforward in network namespace "/var/run/netns/cni-3c000d0a-fb1c-d9df-8af8-1403e6803c22": failed to dial 15000: dial tcp4 127.0.0.1:15000: connect: connection refused[]
Error: failed to execute command on sidecar: failure running port forward process: Get "https://#:42785/config_dump": EOF

このコマンドは、メッシュの一部であるPod、たとえばBookinfoの ratings サービスなどに対してそのような警告を生成しません。代わりに、Podに適用されるIstioの設定を出力します。

$ export RATINGS_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')
$ istioctl experimental describe pod $RATINGS_POD
Pod: ratings-v1-7dc98c7588-8jsbw
   Pod Ports: 9080 (ratings), 15090 (istio-proxy)
--------------------
Service: ratings
   Port: http 9080/HTTP targets pod port 9080

出力には次の情報が表示されます。

  • Pod内のサービスコンテナのポート(この例では、ratingsコンテナの場合は9080)。
  • Pod内の istio-proxy コンテナのポート(この例では15090)。
  • Pod内のサービスが使用するプロトコル(この例ではポート9080経由のHTTP)。

宛先ルールの構成を確認する

istioctl describe を使用して、Podへのリクエストに適用されるデスティネーションルールを確認できます。たとえば、Bookinfoの相互TLSデスティネーションルールを適用します。

Zip
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

次に、ratings Podを再度記述します。

$ istioctl x describe pod $RATINGS_POD
Pod: ratings-v1-f745cf57b-qrxl2
   Pod Ports: 9080 (ratings), 15090 (istio-proxy)
--------------------
Service: ratings
   Port: http 9080/HTTP
DestinationRule: ratings for "ratings"
   Matching subsets: v1
      (Non-matching subsets v2,v2-mysql,v2-mysql-vm)
   Traffic Policy TLS Mode: ISTIO_MUTUAL

コマンドは追加の出力を表示するようになりました。

  • ratings デスティネーションルールは、ratings サービスへのリクエストに適用されます。
  • Podに一致する ratings デスティネーションルールのサブセット(この例ではv1)。
  • デスティネーションルールによって定義された他のサブセット。
  • PodはHTTPまたは相互TLSリクエストを受け入れますが、クライアントは相互TLSを使用します。

仮想サービスの構成を確認する

仮想サービスがPodへのルートを設定すると、istioctl describe はその出力にルートも含めます。たとえば、すべてのリクエストをv1 PodにルーティングするBookinfo仮想サービスを適用します。

Zip
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

次に、reviewsサービスの v1 を実装するPodを記述します。

$ export REVIEWS_V1_POD=$(kubectl get pod -l app=reviews,version=v1 -o jsonpath='{.items[0].metadata.name}')
$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
   1 HTTP route(s)

出力には、以前にratings Podに対して表示されたものと同様の情報が含まれていますが、Podへの仮想サービスのルートも含まれています。

istioctl describe コマンドは、Podに影響を与える仮想サービスを表示するだけではありません。仮想サービスがPodのサービスホストを設定しているにもかかわらず、トラフィックがPodに到達しない場合、コマンドの出力には警告が含まれます。このケースは、仮想サービスが実際にPodのサブセットにトラフィックをルーティングしないことでトラフィックをブロックした場合に発生する可能性があります。たとえば

$ export REVIEWS_V2_POD=$(kubectl get pod -l app=reviews,version=v2 -o jsonpath='{.items[0].metadata.name}')
$ istioctl x describe pod $REVIEWS_V2_POD
...
VirtualService: reviews
   WARNING: No destinations match pod subsets (checked 1 HTTP routes)
      Route to non-matching subset v1 for (everything)

警告には、問題の原因、チェックされたルートの数、および配置されている他のルートに関する情報も含まれています。この例では、仮想サービス内のルートがすべてのトラフィックをv1サブセットに転送するため、v2 Podにトラフィックが到達しません。

ここでBookinfoのデスティネーションルールを削除すると

Zip
$ kubectl delete -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

istioctl describe のもう1つの便利な機能を確認できます。

$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
   WARNING: No destinations match pod subsets (checked 1 HTTP routes)
      Warning: Route to subset v1 but NO DESTINATION RULE defining subsets!

出力には、デスティネーションルールは削除したが、それに依存する仮想サービスは削除していないことが示されています。仮想サービスはトラフィックをv1サブセットにルーティングしますが、v1サブセットを定義するデスティネーションルールはありません。したがって、バージョンv1宛てのトラフィックはPodにフローできません。

ここでブラウザを更新してBookinfoに新しいリクエストを送信すると、次のメッセージが表示されます:「製品レビューの取得エラー」。問題を解決するには、デスティネーションルールを再適用します。

Zip
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

ブラウザをリロードすると、アプリが再び動作し、istioctl experimental describe pod $REVIEWS_V1_POD を実行しても警告は生成されなくなります。

トラフィックルートの検証

istioctl describe コマンドは、トラフィックの分割ウェイトも表示します。たとえば、次のコマンドを実行して、トラフィックの90%をreviewsサービスのv1サブセットに、10%をv2サブセットにルーティングします。

Zip
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-90-10.yaml@

次に、reviews v1 Podを記述します。

$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
   Weight 90%

出力には、reviews 仮想サービスに v1 サブセットの 90% のウェイトがあることが示されています。

この機能は、他のタイプのルーティングにも役立ちます。たとえば、ヘッダー固有のルーティングをデプロイできます。

Zip
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml@

次に、Podを再度記述します。

$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
   WARNING: No destinations match pod subsets (checked 2 HTTP routes)
      Route to non-matching subset v2 for (when headers are end-user=jason)
      Route to non-matching subset v3 for (everything)

v1 サブセットのPodを記述しているため、出力には警告が表示されます。ただし、適用した仮想サービス設定は、ヘッダーに end-user=jason が含まれている場合はトラフィックを v2 サブセットにルーティングし、それ以外の場合はすべてのトラフィックを v3 サブセットにルーティングします。

厳密な相互 TLS の検証

相互TLS移行の指示に従って、ratingsサービスに対して厳密な相互TLSを有効にすることができます。

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: ratings-strict
spec:
  selector:
    matchLabels:
      app: ratings
  mtls:
    mode: STRICT
EOF

次のコマンドを実行して、ratings Podを記述します。

$ istioctl x describe pod $RATINGS_POD
Pilot reports that pod enforces mTLS and clients speak mTLS

出力は、ratings Podへのリクエストがロックダウンされ、安全になったことを報告します。

ただし、相互TLSを STRICT に切り替えると、デプロイが壊れることがあります。考えられる原因は、デスティネーションルールが新しい構成と一致しなかったことです。たとえば、プレーンHTTPデスティネーションルールを使用して、相互TLSを使用しないようにBookinfoクライアントを設定した場合。

Zip
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all.yaml@

ブラウザでBookinfoを開くと、「Ratings service is currently unavailable」と表示されます。理由を調べるには、次のコマンドを実行します。

$ istioctl x describe pod $RATINGS_POD
...
WARNING Pilot predicts TLS Conflict on ratings-v1-f745cf57b-qrxl2 port 9080 (pod enforces mTLS, clients speak HTTP)
  Check DestinationRule ratings/default and AuthenticationPolicy ratings-strict/default

出力には、デスティネーションルールと認証ポリシーの間の競合を説明する警告が含まれています。

相互TLSを使用するデスティネーションルールを適用することで、正しい動作を復元できます。

Zip
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

結論とクリーンアップ

istioctl x describe コマンドの目標は、Istioメッシュのトラフィックとセキュリティ構成を理解するのに役立つことです。

改善のためのアイデアをお待ちしています!https://discuss.istio.ioでご参加ください。

このガイドで使用したBookinfoのPodと構成を削除するには、次のコマンドを実行します。

ZipZipZipZip
$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo.yaml@
$ kubectl delete -f @samples/bookinfo/networking/bookinfo-gateway.yaml@
$ kubectl delete -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
この情報は役に立ちましたか?
改善のための提案はありますか?

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