content/en/docs/tasks/traffic-management/ingress/gateway-api/index.md
In addition to its own traffic management API, {{< boilerplate gateway-api-future >}} This document describes the differences between the Istio and Kubernetes APIs and provides a simple example that shows you how to configure Istio to expose a service outside the service mesh cluster using the Gateway API. Note that these APIs are an actively developed evolution of the Kubernetes Service and Ingress APIs.
{{< tip >}} Many of the Istio traffic management documents include instructions for using either the Istio or Kubernetes API (see the control ingress traffic task, for example). You can use the Gateway API, right from the start, by following the getting started instructions. {{< /tip >}}
The Gateway APIs do not come installed by default on most Kubernetes clusters. Install the Gateway API CRDs if they are not present:
{{< text bash >}}
$ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null ||
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref={{< k8s_gateway_api_version >}}" | kubectl apply -f -; }
{{< /text >}}
Install Istio using the minimal profile:
{{< text bash >}} $ istioctl install --set profile=minimal -y {{< /text >}}
The Gateway APIs share a lot of similarities to the Istio APIs such as Gateway and VirtualService.
The main resource shares the same name, Gateway, and the resources serve similar goals.
The new Gateway APIs aim to take the learnings from various Kubernetes ingress implementations, including Istio, to build a standardized vendor neutral API. These APIs generally serve the same purposes as Istio Gateway and VirtualService, with a few key differences:
Gateway configures an existing gateway Deployment/Service that has been deployed.
In the Gateway APIs, the Gateway resource both configures and deploys a gateway.
See Deployment Methods for more information.VirtualService, all protocols are configured within a single resource.
In the Gateway APIs, each protocol type has its own resource, such as HTTPRoute and TCPRoute.See the Gateway API documentation for information about the APIs.
In this example, we will deploy a simple application and expose it externally using a Gateway.
First, deploy the httpbin test application:
{{< text bash >}} $ kubectl apply -f @samples/httpbin/httpbin.yaml@ {{< /text >}}
Deploy the Gateway API configuration including a single exposed route (i.e., /get):
{{< text bash >}} $ 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:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http namespace: default spec: parentRefs:
Set the Ingress Host environment variable:
{{< text bash >}} $ 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}') {{< /text >}}
Access the httpbin service using curl:
{{< text bash >}} $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get" ... HTTP/1.1 200 OK ... server: istio-envoy ... {{< /text >}}
Note the use of the -H flag to set the Host HTTP header to
"httpbin.example.com". This is needed because the HTTPRoute is configured to handle "httpbin.example.com",
but in your test environment you have no DNS binding for that host and are simply sending your request to the ingress IP.
Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error:
{{< text bash >}} $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers" HTTP/1.1 404 Not Found ... {{< /text >}}
Update the route rule to also expose /headers and to add a header to the request:
{{< text bash >}} $ kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http namespace: default spec: parentRefs:
Access /headers again and notice header My-Added-Header has been added to the request:
{{< text bash >}} $ curl -s -HHost:httpbin.example.com "http://$INGRESS_HOST/headers" | jq '.headers["My-Added-Header"][0]' ... "added-value" ... {{< /text >}}
In the example above, you did not need to install an ingress gateway Deployment prior to configuring a Gateway.
In the default configuration, a gateway Deployment and Service is automatically provisioned based on the Gateway configuration.
For advanced use cases, manual deployment is still allowed.
By default, each Gateway will automatically provision a Service and Deployment.
These will be named <Gateway name>-<GatewayClass name> (with the exception of the istio-waypoint GatewayClass, which does not append a suffix).
These configurations will be updated automatically if the Gateway changes (for example, if a new port is added).
These resources can be customized by using the infrastructure field:
{{< text yaml >}} apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway spec: infrastructure: annotations: some-key: some-value labels: key: value parametersRef: group: "" kind: ConfigMap name: gw-options gatewayClassName: istio {{< /text >}}
Key-value pairs under labels and annotations will be copied onto the generated resources.
The parametersRef can be used to fully customize the generated resources.
This must reference a ConfigMap in the same namespace as the Gateway.
An example configuration:
{{< text yaml >}} apiVersion: v1 kind: ConfigMap metadata: name: gw-options data: horizontalPodAutoscaler: | spec: minReplicas: 2 maxReplicas: 2
deployment: | metadata: annotations: additional-annotation: some-value spec: replicas: 4 template: spec: containers: - name: istio-proxy resources: requests: cpu: 1234m
service: | spec: ports: - "$patch": delete port: 15021 {{< /text >}}
These configurations will be overlaid on top of the generated resources using a Strategic Merge Patch strategy. The following keys are valid:
servicedeploymentserviceAccounthorizontalPodAutoscalerpodDisruptionBudget{{< tip >}}
A HorizontalPodAutoscaler and PodDisruptionBudget are not created by default.
However, if the corresponding field is present in the customization, they will be created.
{{< /tip >}}
Defaults for all Gateways can be configured for each GatewayClass.
This is done by a ConfigMap with the label gateway.istio.io/defaults-for-class: <gateway class name>.
This ConfigMap must be in the root namespace (typically, istio-system).
Only one ConfigMap per GatewayClass is allowed.
This ConfigMap takes the same format as the ConfigMap for a Gateway.
Customization may be present on both a GatewayClass and a Gateway.
If both are present, the Gateway customization applies after the GatewayClass customization.
This ConfigMap can also be created at installation time. For example:
{{< text yaml >}} kind: IstioOperator spec: values: gatewayClasses: istio: deployment: spec: replicas: 2 {{< /text >}}
Resources can be attached to a Gateway to customize it.
However, most Kubernetes resources do not currently support attaching directly to a Gateway, but they can be attached to the corresponding generated Deployment and Service instead.
This is easily done because the resources are generated with well-known labels (gateway.networking.k8s.io/gateway-name: <gateway name>) and names:
<gateway name>-<gateway class name><gateway name>For example, to deploy a Gateway with a HorizontalPodAutoscaler and PodDisruptionBudget:
{{< text yaml >}} apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway spec: gatewayClassName: istio listeners:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: gateway spec:
kind: Gateway.scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: gateway-istio minReplicas: 2 maxReplicas: 5 metrics:
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 {{< /text >}}
If you do not want to have an automated deployment, a Deployment and Service can be configured manually.
When this option is done, you will need to manually link the Gateway to the Service, as well as keep their port configuration in sync.
In order to support Policy Attachment, e.g. when you're using the targetRef field on an AuthorizationPolicy, you will also need to reference the name of your Gateway by adding the following label to your gateway pod: gateway.networking.k8s.io/gateway-name: <gateway name>.
To link a Gateway to a Service, configure the addresses field to point to a single Hostname.
{{< tip >}}
Istio's controller will not configure the Service if it is in a different namespace to the Gateway.
{{< /tip >}}
{{< text yaml >}} apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway spec: addresses:
The Gateway API can also be used to configure mesh traffic.
This is done by configuring the parentRef to point to a service, instead of a gateway.
For example, to add a header on all calls to an in-cluster Service named example:
{{< text yaml >}} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: mesh spec: parentRefs:
More details and examples can be found in other traffic management tasks.
Remove the httpbin sample and gateway:
{{< text bash >}} $ 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 {{< /text >}}
Uninstall Istio:
{{< text bash >}} $ istioctl uninstall -y --purge $ kubectl delete ns istio-system {{< /text >}}
Remove the Gateway API CRDs if they are no longer needed:
{{< text bash >}} $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref={{< k8s_gateway_api_version >}}" | kubectl delete -f - {{< /text >}}