Kubernetes Gateway API
Istioは、独自のトラフィック管理APIに加えて、Kubernetes Gateway APIをサポートしており、将来的にトラフィック管理のデフォルトAPIにすることを目指しています。このドキュメントでは、Istio APIとKubernetes APIの違いについて説明し、Gateway APIを使用してサービスメッシュクラスターの外部にサービスを公開するようにIstioを設定する方法を示す簡単な例を提供します。これらのAPIは、KubernetesのServiceおよびIngress APIを積極的に進化させたものであることに注意してください。
セットアップ
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 -; }
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では、各プロトコルタイプに、HTTPRoute
やTCPRoute
などの独自のリソースがあります。 - Gateway APIは多くの豊富なルーティング機能を提供しますが、まだIstioの機能セットの100%をカバーしていません。これらのユースケースをカバーするようにAPIを拡張する作業が進行中であり、APIの拡張性を利用して、Istioの機能をより適切に公開します。
ゲートウェイの設定
APIの詳細については、Gateway APIのドキュメントを参照してください。
この例では、簡単なアプリケーションをデプロイし、Gateway
を使用して外部に公開します。
まず、
httpbin
テストアプリケーションをデプロイします。$ kubectl apply -f @samples/httpbin/httpbin.yaml@
単一の公開ルート(つまり、
/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
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}')
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に送信しているだけであるためです。明示的に公開されていない他のURLにアクセスします。HTTP 404エラーが表示されるはずです。
$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers" HTTP/1.1 404 Not Found ...
/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
再度
/headers
にアクセスし、ヘッダーMy-Added-Header
がリクエストに追加されていることに注意してください。$ curl -s -HHost:httpbin.example.com "http://$INGRESS_HOST/headers" | jq '.headers["My-Added-Header"][0]' ... "added-value" ...
デプロイメント方法
上記の例では、Gatewayを構成する前に、イングレスゲートウェイのDeployment
をインストールする必要はありませんでした。デフォルト構成では、ゲートウェイのDeployment
とService
がGateway
構成に基づいて自動的にプロビジョニングされます。高度なユースケースでは、手動デプロイも可能です。
自動デプロイメント
デフォルトでは、各Gateway
は同じ名前のService
とDeployment
を自動的にプロビジョニングします。これらの構成は、Gateway
が変更された場合(たとえば、新しいポートが追加された場合)に自動的に更新されます。
これらのリソースは、いくつかの方法でカスタマイズできます。
Gateway
のアノテーションとラベルは、Service
とDeployment
にコピーされます。これにより、これらのフィールドから読み取る内部ロードバランサーなどを構成できます。Istioは、生成されたリソースを構成するための追加のアノテーションを提供します。
アノテーション 目的 networking.istio.io/service-type
Service.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つのみです。
- (高度)生成されたPod構成は、カスタムインジェクションテンプレートで構成できます。
リソースのアタッチとスケーリング
リソースは、Gateway
にアタッチしてカスタマイズできます。ただし、ほとんどのKubernetesリソースは現在、Gateway
に直接アタッチすることをサポートしていませんが、代わりに、対応する生成されたDeployment
およびService
にアタッチできます。これらのリソースは両方とも名前<ゲートウェイ名>-<ゲートウェイクラス名>
とラベルgateway.networking.k8s.io/gateway-name: <ゲートウェイ名>
で生成されるため、これは簡単に行えます。
たとえば、HorizontalPodAutoscaler
とPodDisruptionBudget
を使用して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
手動デプロイメント
自動デプロイメントを行わない場合は、Deployment
とService
を手動で構成できます。
このオプションが完了したら、Gateway
をService
に手動でリンクし、ポート構成を同期させる必要があります。
ポリシーアタッチメントをサポートするために、たとえば、AuthorizationPolicyでtargetRef
フィールドを使用している場合、ゲートウェイポッドに次のラベルを追加して、Gateway
の名前も参照する必要があります。gateway.networking.k8s.io/gateway-name: <ゲートウェイ名>
。
Gateway
をService
にリンクするには、単一の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
詳細と例は、他のトラフィック管理タスクにあります。
クリーンアップ
httpbin
サンプルとゲートウェイを削除します。$ 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
Istioをアンインストールします。
$ istioctl uninstall -y --purge $ kubectl delete ns istio-system
Gateway API CRDが不要になった場合は削除します。
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0" | kubectl delete -f -