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

外部サービスへのアクセス タスクと イグレスゲートウェイの設定 の例では、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
    
この情報は役に立ちましたか?
改善のための提案はありますか?

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