Kubernetes Gateway API

Istioは、独自のトラフィック管理APIに加えて、Kubernetes Gateway APIをサポートしており、将来的にトラフィック管理のデフォルトAPIにすることを目指しています。このドキュメントでは、Istio APIとKubernetes APIの違いについて説明し、Gateway APIを使用してサービスメッシュクラスターの外部にサービスを公開するようにIstioを設定する方法を示す簡単な例を提供します。これらのAPIは、KubernetesのServiceおよびIngress APIを積極的に進化させたものであることに注意してください。

セットアップ

  1. Gateway APIは、ほとんどのKubernetesクラスターにデフォルトではインストールされていません。Gateway API CRDが存在しない場合はインストールしてください。

    $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \ { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0" | kubectl apply -f -; }
  2. minimalプロファイルを使用してIstioをインストールします。

    $ istioctl install --set profile=minimal -y

Istio APIとの違い

Gateway APIは、GatewayやVirtualServiceなどのIstio APIと多くの類似点を共有しています。メインリソースは同じ名前のGatewayであり、リソースは同様の目標を達成します。

新しいGateway APIは、Istioを含むさまざまなKubernetesイングレスの実装から得られた学習を活用して、標準化されたベンダーニュートラルなAPIを構築することを目的としています。これらのAPIは、IstioのGatewayおよびVirtualServiceと同じ目的を果たしますが、いくつかの重要な違いがあります。

  • Istio APIでは、Gatewayデプロイされている既存のゲートウェイDeployment/Serviceを構成します。Gateway APIでは、Gatewayリソースはゲートウェイを構成およびデプロイします。詳細については、デプロイメント方法を参照してください。
  • IstioのVirtualServiceでは、すべてのプロトコルが単一のリソース内で構成されます。Gateway APIでは、各プロトコルタイプに、HTTPRouteTCPRouteなどの独自のリソースがあります。
  • Gateway APIは多くの豊富なルーティング機能を提供しますが、まだIstioの機能セットの100%をカバーしていません。これらのユースケースをカバーするようにAPIを拡張する作業が進行中であり、APIの拡張性を利用して、Istioの機能をより適切に公開します。

ゲートウェイの設定

APIの詳細については、Gateway APIのドキュメントを参照してください。

この例では、簡単なアプリケーションをデプロイし、Gatewayを使用して外部に公開します。

  1. まず、httpbinテストアプリケーションをデプロイします。

    Zip
    $ kubectl apply -f samples/httpbin/httpbin.yaml
  2. 単一の公開ルート(つまり、/get)を含むGateway API構成をデプロイします。

    $ kubectl create namespace istio-ingress $ kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway namespace: istio-ingress spec: gatewayClassName: istio listeners: - name: default hostname: "*.example.com" port: 80 protocol: HTTP allowedRoutes: namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http namespace: default spec: parentRefs: - name: gateway namespace: istio-ingress hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /get backendRefs: - name: httpbin port: 8000 EOF
  3. Ingress Host環境変数を設定します。

    $ kubectl wait -n istio-ingress --for=condition=programmed gateways.gateway.networking.k8s.io gateway $ export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io gateway -n istio-ingress -ojsonpath='{.status.addresses[0].value}')
  4. curlを使用してhttpbinサービスにアクセスします。

    $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
    ... HTTP/1.1 200 OK ... server: istio-envoy ...

    Host HTTPヘッダーを「httpbin.example.com」に設定するために-Hフラグを使用していることに注意してください。これは、HTTPRouteが「httpbin.example.com」を処理するように構成されていますが、テスト環境にはそのホストのDNSバインドがなく、リクエストをイングラスIPに送信しているだけであるためです。

  5. 明示的に公開されていない他のURLにアクセスします。HTTP 404エラーが表示されるはずです。

    $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers"
    HTTP/1.1 404 Not Found ...
  6. /headersも公開するようにルートルールを更新し、リクエストにヘッダーを追加します。

    $ kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http namespace: default spec: parentRefs: - name: gateway namespace: istio-ingress hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /get - path: type: PathPrefix value: /headers filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: my-added-header value: added-value backendRefs: - name: httpbin port: 8000 EOF
  7. 再度/headersにアクセスし、ヘッダーMy-Added-Headerがリクエストに追加されていることに注意してください。

    $ curl -s -HHost:httpbin.example.com "http://$INGRESS_HOST/headers" | jq '.headers["My-Added-Header"][0]'
    ... "added-value" ...

デプロイメント方法

上記の例では、Gatewayを構成する前に、イングレスゲートウェイのDeploymentをインストールする必要はありませんでした。デフォルト構成では、ゲートウェイのDeploymentServiceGateway構成に基づいて自動的にプロビジョニングされます。高度なユースケースでは、手動デプロイも可能です。

自動デプロイメント

デフォルトでは、各Gatewayは同じ名前のServiceDeploymentを自動的にプロビジョニングします。これらの構成は、Gatewayが変更された場合(たとえば、新しいポートが追加された場合)に自動的に更新されます。

これらのリソースは、いくつかの方法でカスタマイズできます。

  • Gatewayのアノテーションとラベルは、ServiceDeploymentにコピーされます。これにより、これらのフィールドから読み取る内部ロードバランサーなどを構成できます。

  • Istioは、生成されたリソースを構成するための追加のアノテーションを提供します。

    アノテーション目的
    networking.istio.io/service-typeService.spec.typeフィールドを制御します。たとえば、サービスを外部に公開しないようにClusterIPに設定します。デフォルトはLoadBalancerです。
  • Service.spec.loadBalancerIPフィールドは、addressesフィールドを構成することで明示的に設定できます。

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: gateway
    spec:
      addresses:
      - value: 192.0.2.0
        type: IPAddress
    ...
    

注:指定できるアドレスは1つのみです。

リソースのアタッチとスケーリング

リソースは、Gatewayアタッチしてカスタマイズできます。ただし、ほとんどのKubernetesリソースは現在、Gatewayに直接アタッチすることをサポートしていませんが、代わりに、対応する生成されたDeploymentおよびServiceにアタッチできます。これらのリソースは両方とも名前<ゲートウェイ名>-<ゲートウェイクラス名>とラベルgateway.networking.k8s.io/gateway-name: <ゲートウェイ名>で生成されるため、これは簡単に行えます。

たとえば、HorizontalPodAutoscalerPodDisruptionBudgetを使用してGatewayをデプロイするには

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
spec:
  gatewayClassName: istio
  listeners:
  - name: default
    hostname: "*.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: gateway
spec:
  # Match the generated Deployment by reference
  # Note: Do not use `kind: Gateway`.
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: gateway-istio
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: gateway
spec:
  minAvailable: 1
  selector:
    # Match the generated Deployment by label
    matchLabels:
      gateway.networking.k8s.io/gateway-name: gateway

手動デプロイメント

自動デプロイメントを行わない場合は、DeploymentService手動で構成できます。

このオプションが完了したら、GatewayServiceに手動でリンクし、ポート構成を同期させる必要があります。

ポリシーアタッチメントをサポートするために、たとえば、AuthorizationPolicyでtargetRefフィールドを使用している場合、ゲートウェイポッドに次のラベルを追加して、Gatewayの名前も参照する必要があります。gateway.networking.k8s.io/gateway-name: <ゲートウェイ名>

GatewayServiceにリンクするには、単一Hostnameを指すようにaddressesフィールドを構成します。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
spec:
  addresses:
  - value: ingress.istio-gateways.svc.cluster.local
    type: Hostname
...

メッシュトラフィック

Gateway APIは、メッシュトラフィックを構成するためにも使用できます。これは、ゲートウェイではなく、サービスを指すようにparentRefを構成することで行われます。

たとえば、クラスター内のexampleという名前のServiceへのすべての呼び出しにヘッダーを追加するには

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: mesh
spec:
  parentRefs:
  - group: ""
    kind: Service
    name: example
  rules:
  - filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        add:
        - name: my-added-header
          value: added-value
    backendRefs:
    - name: example
      port: 80

詳細と例は、他のトラフィック管理タスクにあります。

クリーンアップ

  1. httpbinサンプルとゲートウェイを削除します。

    Zip
    $ kubectl delete -f samples/httpbin/httpbin.yaml $ kubectl delete httproute http $ kubectl delete gateways.gateway.networking.k8s.io gateway -n istio-ingress $ kubectl delete ns istio-ingress
  2. Istioをアンインストールします。

    $ istioctl uninstall -y --purge $ kubectl delete ns istio-system
  3. Gateway API CRDが不要になった場合は削除します。

    $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0" | kubectl delete -f -
この情報は役に立ちましたか?
改善のための提案はありますか?

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