ワイルドカードホストを使用したエグレス

外部サービスへのアクセス タスクと イグレスゲートウェイの設定 の例では、edition.cnn.com のような特定のホスト名に対するイグレストラフィックの設定方法について説明しています。この例では、各ホストを個別に設定する代わりに、共通ドメイン内のホストのセット(例:*.wikipedia.org)に対するイグレストラフィックを有効にする方法を示します。

背景

Istioで、すべての言語のwikipedia.orgサイトに対するイグレストラフィックを有効にしたいとします。特定の言語のwikipedia.orgの各バージョンには、それぞれ独自のホスト名があります(例:英語ではen.wikipedia.org、ドイツ語ではde.wikipedia.org)。各言語のサイトを個別に指定することなく、すべてのWikipediaサイトに対して共通の設定項目でイグレストラフィックを有効にしたいと考えています。

始める前に

  • アクセスログが有効になっており、デフォルトでブロックするアウトバウンドトラフィックポリシーが適用されている状態でIstioをインストールします。
$ istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • リクエストを送信するためのテストソースとして使用する、curlサンプルアプリをデプロイします。自動サイドカーインジェクションを有効にしている場合は、次のコマンドを実行してサンプルアプリをデプロイします。

    Zip
    $ kubectl apply -f samples/curl/curl.yaml

    それ以外の場合は、次のコマンドを使用してサイドカーを手動でインジェクトしてから、curlアプリケーションをデプロイします。

    Zip
    $ kubectl apply -f <(istioctl kube-inject -f samples/curl/curl.yaml)
  • ソースポッドの名前をSOURCE_POD環境変数に設定します。

    $ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})

ワイルドカードホストへのダイレクトトラフィックの設定

共通ドメイン内のホストのセットにアクセスする最初の、そして最も簡単な方法は、ワイルドカードホストを持つ単純なServiceEntryを設定し、サイドカーから直接サービスを呼び出すことです。サービスを直接呼び出す場合(つまり、イグレスゲートウェイを介さない場合)、ワイルドカードホストの設定は他の(例:完全修飾)ホストの設定と変わりません。共通ドメイン内に多くのホストがある場合にのみ、はるかに便利です。

  1. *.wikipedia.orgに対するServiceEntryを定義します。

    $ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: wikipedia spec: hosts: - "*.wikipedia.org" ports: - number: 443 name: https protocol: HTTPS EOF
  2. https://en.wikipedia.orghttps://de.wikipedia.orgにHTTPSリクエストを送信します。

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    <title>Wikipedia, the free encyclopedia</title> <title>Wikipedia – Die freie Enzyklopädie</title>

ワイルドカードホストへのダイレクトトラフィックのクリーンアップ

$ kubectl delete serviceentry wikipedia

ワイルドカードホストへのイグレスゲートウェイトラフィックの設定

すべてのワイルドカードホストが単一のサーバーによって提供される場合、ワイルドカードホストへのイグレスゲートウェイベースのアクセスの設定は、ほとんどのホストの設定と非常に似ています。ただし、1つの例外があります。構成されたルートの宛先は、構成されたホスト(つまり、ワイルドカード)と同じではありません。代わりに、ドメインのセットの単一サーバーのホストを使用して構成されます。

  1. *.wikipedia.orgに対するイグレスGatewayと、トラフィックをイグレスゲートウェイ経由で、そしてイグレスゲートウェイから外部サービスに転送するルートルールを作成します。
$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - "*.wikipedia.org" tls: mode: PASSTHROUGH --- apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: egressgateway-for-wikipedia spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: wikipedia --- apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: direct-wikipedia-through-egress-gateway spec: hosts: - "*.wikipedia.org" gateways: - mesh - istio-egressgateway tls: - match: - gateways: - mesh port: 443 sniHosts: - "*.wikipedia.org" route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: wikipedia port: number: 443 weight: 100 - match: - gateways: - istio-egressgateway port: 443 sniHosts: - "*.wikipedia.org" route: - destination: host: www.wikipedia.org port: number: 443 weight: 100 EOF
  1. 宛先サーバーwww.wikipedia.orgに対するServiceEntryを作成します。

    $ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: www-wikipedia spec: hosts: - www.wikipedia.org ports: - number: 443 name: https protocol: HTTPS resolution: DNS EOF
  2. https://en.wikipedia.orghttps://de.wikipedia.orgにHTTPSリクエストを送信します。

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    <title>Wikipedia, the free encyclopedia</title> <title>Wikipedia – Die freie Enzyklopädie</title>
  3. *.wikipedia.orgへのリクエストに対応するカウンターについて、イグレスゲートウェイのプロキシの統計を確認します。

$ kubectl exec "$(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -n istio-system -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2

ワイルドカードホストへのイグレスゲートウェイトラフィックのクリーンアップ

$ kubectl delete serviceentry www-wikipedia $ kubectl delete gateway istio-egressgateway $ kubectl delete virtualservice direct-wikipedia-through-egress-gateway $ kubectl delete destinationrule egressgateway-for-wikipedia

任意のドメインに対するワイルドカード設定

前のセクションの設定は、すべての*.wikipedia.orgサイトがwikipedia.orgサーバーのいずれかによって提供されるため機能しました。しかし、これは常に当てはまるわけではありません。たとえば、*.com*.orgのようなより一般的なワイルドカードドメインへのアクセスに対してイグレス制御を設定したい場合があります。任意のワイルドカードドメインへのトラフィックの設定は、Istioゲートウェイにとって課題となります。Istioゲートウェイは、事前に定義されたホスト、事前に定義されたIPアドレス、またはリクエストの元の宛先IPアドレスへのトラフィックのルーティングのみを構成できます。

前のセクションでは、仮想サービスを構成してトラフィックを事前に定義されたホストwww.wikipedia.orgに転送するように設定しました。しかし、一般的なケースでは、リクエストで受信した任意のホストを提供できるホストまたはIPアドレスがわからないため、リクエストをルーティングするための値としてリクエストの元の宛先アドレスだけが残ります。残念ながら、イグレスゲートウェイを使用する場合、元の要求がゲートウェイにリダイレクトされるため、リクエストの元の宛先アドレスは失われ、宛先IPアドレスはゲートウェイのIPアドレスになります。

Istioの実装の詳細に依存するため、簡単ではなく、やや脆弱ではありますが、Envoyフィルターを使用して、HTTPSまたはTLSリクエストのSNI値を使用して、リクエストをルーティングする元の宛先を識別することで、ゲートウェイが任意のドメインをサポートするように構成できます。この構成アプローチの例は、ワイルドカード宛先へのイグレストラフィックのルーティングにあります。

クリーンアップ

  • curlサービスをシャットダウンします。

    Zip
    $ kubectl delete -f samples/curl/curl.yaml
  • クラスタからIstioをアンインストールします。

    $ istioctl uninstall --purge -y
この情報は役に立ちましたか?
改善のための提案はありますか?

ご意見ありがとうございます!