Egressトラフィック監視

サービスメッシュについて考える1つの方法は、ドメイン制御です。 Istioサイドカーインジェクションが有効になっているKubernetesのNamespaceで、Pod間のすべてのトラフィックを監視し、セキュリティポリシーを適用できます。

しかし、メッシュの外側にあるアップストリームサービスはどうでしょうか。どのサービスが外部APIを呼び出すかを実行時にどうやって決定するのでしょうか?サービスが書き込んでいるデータベースインスタンスをどのようにして知るのでしょうか?または、メッシュ内のサービスが独自の地理的領域内のトラフィックのみを送信していることをどのように確認するのでしょうか?こうしたことは、IstioのEgress監視 が解決します。

Egress出口を意味します。この場合、Egressトラフィックとは、Istioメッシュから出る必要があるリクエストを意味します。 デフォルトですべてのEgressトラフィックをIstioがブロックした時期がありました。サービスがアクセスする必要があるすべての外部ホストをホワイトリストに登録するには、ServiceEntryを手動で作成する必要がありました。ServiceEntryは、Istioのサービスレジストリに外部ホストを追加します。これはIstio 1.3で変更され、REGISTRY_ONLY Egressポリシーがデフォルトで ALLOW_ANY になりました。このため、現在メッシュ内サービスは ServiceEntry を必要とせずに、外部サービスに自由にアクセスできます。

メッシュにどのIstioEgressオプションを選択しても、IstioはすべてのEgressトラフィックを監視できます。また、専用のEgressゲートウェイプロキシを必要とせずに、ワークロードのサイドカープロキシを通してこのEgressトラフィックを監視できます。それがどのように機能するか見てみましょう。

この例では、ユーザーがレシピを共有できるWebサイトを構築しました。コストを最適化するために、ウェブフロントエンドはサーバーレス機能としてKubernetesの外で実行されます。ユーザーがレシピを追加すると、フロントエンドはKubernetesクラスター内のIDジェネレーターサービス(idgen)を呼び出して、そのレシピのIDを作成します。idgen はデフォルトのIstio IngressGatewayを介して公開され、httpbin と呼ばれる外部APIからランダムなIDを取得します。

オプション1 - Passthrough

まず、Egressのデフォルト ALLOW_ANY オプションを指定したIstioインストールを使用してみましょう。これは、追加の構成なしで、idgenhttpbin への要求が許可されることを意味します。 ALLOW_ANY が有効になっている場合、Istioは、idgen のサイドカープロキシによって適用される PassthroughCluster と呼ばれるEnvoyクラスターを使用して、Egressトラフィックを監視します。

Envoyクラスターは、エンドポイントのバックエンド(または「アップストリーム」)セットであり、外部サービスを表します。 IstioサイドカーEnvoyプロキシは、アプリケーションコンテナーからのインターセプトされたリクエストにフィルターを適用します。これらのフィルターに基づいて、Envoyは特定のルートにトラフィックを送信します。ルートは、トラフィックを送信するクラスターを指定します。

Istio Passthrough クラスターは、バックエンドが元のリクエストの宛先になるように設定されています。したがって、Egressトラフィックで ALLOW_ANY が有効になっている場合、Envoyは単に idgen のリクエストを httpbin に「パススルー」します。

この構成では、IngressGatewayを介してレシピIDリクエストを送信すると、idgenhttpbin を正常に呼び出すことができます。このトラフィックは、Kialiサービスグラフで PassthroughCluster トラフィックとして表示されます。httpbin が独自のサービスレベルのテレメトリを取得するには、ServiceEntry を追加する必要があります。(後ほど行います。)

しかし、Prometheusをドリルダウンして、istio_total_requests メトリクスを見つけると、PassthroughCluster トラフィックが httpbin.org と呼ばれる destinationservice に向かっていることがわかります。

オプション2 - REGISTRY_ONLY、no ServiceEntry

ここで、httpbin の ServiceEntry を追加する前に、すべてのEgressトラフィックをロックしたいとします。これを行うには、送信トラフィックのグローバルインストールオプションREGISTRY_ONLY に更新し、Istioインストールマニフェストを再適用します。

今度は、BlackHoleという新しいクラスターが登場します。ブラックホールクラスターは、IPエンドポイントのないバックエンドです。 BlackHoleCluster にルーティングされたリクエストはEnvoyによってドロップされ、502: Bad Gateway エラーが返されます。実際には、Egressリクエストをドロップするサイドカープロキシのコレクションは、REGISTRY_ONLY ポリシーが適用される方法です。

REGISTRY_ONLY オプションを有効にしてIstioを再インストールし、idgen Podを再デプロイすると、BlackHoleCluster がリクエストをインターセプトしていることがわかります。赤いグラフの端は、HTTPリクエストが完了しないことを意味します-トラフィックは目的の httpbin.org エンドポイントに到達できません。

Prometheusでは、istio_total_requests メトリクスが BlackHoleCluster トラフィックを考慮していることがわかります。実際には、このメトリクスにアラートを設定して、クラスター内のサービスによって試みられたdata exfiltrationを検出できます。このモードでは、Prometheusはブロックされたリクエストの送信元と(試行された)宛先の両方のワークロードを通知できます。

Option 3 - REGISTRY_ONLY with ServiceEntry

ここで、idgen が外部APIを呼び出すための承認を得たとしましょう。 Isioレジストリに httpbin を追加する ServiceEntry の作成を承認しました。:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts:
  - httpbin.org
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL

これで、リクエストがメッシュを正常に脱出し、BlackHoleCluster によってドロップされていないことがわかります。:

また、ServiceEntryを使用すると、Istioは、Kubernetesクラスターの外にあり、制御ドメインの一部ではありませんが、httpbinを別のメッシュサービスとして扱います。これで、httpbin 専用のテレメトリを取得できるようになりました。別の外部サービスを追加すると、サービスグラフに独自の別個のノードとして表示されます。

Egressトラフィック監視について詳しく学ぶ: