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デスティネーションルールを適用します。
$ 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仮想サービスを適用します。
$ 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のデスティネーションルールを削除すると
$ 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に新しいリクエストを送信すると、次のメッセージが表示されます:「製品レビューの取得エラー」。問題を解決するには、デスティネーションルールを再適用します。
$ 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
サブセットにルーティングします。
$ 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% のウェイトがあることが示されています。
この機能は、他のタイプのルーティングにも役立ちます。たとえば、ヘッダー固有のルーティングをデプロイできます。
$ 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クライアントを設定した場合。
$ 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を使用するデスティネーションルールを適用することで、正しい動作を復元できます。
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@
結論とクリーンアップ
istioctl x describe
コマンドの目標は、Istioメッシュのトラフィックとセキュリティ構成を理解するのに役立つことです。
改善のためのアイデアをお待ちしています!https://discuss.istio.ioでご参加ください。
このガイドで使用したBookinfoのPodと構成を削除するには、次のコマンドを実行します。
$ 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@