Kubernetes Gateway API

    1. The Gateway APIs do not come installed by default on most Kubernetes clusters. Install the Gateway API CRDs if they are not present:

    2. Install Istio using the profile:

      1. $ istioctl install --set profile=minimal -y

    Differences from Istio APIs

    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:

    • In Istio APIs, a 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 for more information.
    • In the Istio 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.
    • While the Gateway APIs offer a lot of rich routing functionality, it does not yet cover 100% of Istio’s feature set. Work is ongoing to extend the API to cover these use cases, as well as utilizing the APIs extensibility to better expose Istio functionality.

    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.

    1. First, deploy the httpbin test application:

      1. $ kubectl apply -f @samples/httpbin/httpbin.yaml@
    2. Deploy the Gateway API configuration including a single exposed route (i.e., /get):

      1. $ kubectl create namespace istio-ingress
      2. $ kubectl apply -f - <<EOF
      3. apiVersion: gateway.networking.k8s.io/v1alpha2
      4. kind: Gateway
      5. metadata:
      6. name: gateway
      7. namespace: istio-ingress
      8. spec:
      9. gatewayClassName: istio
      10. listeners:
      11. - name: default
      12. hostname: "*.example.com"
      13. port: 80
      14. protocol: HTTP
      15. allowedRoutes:
      16. namespaces:
      17. from: All
      18. ---
      19. apiVersion: gateway.networking.k8s.io/v1alpha2
      20. kind: HTTPRoute
      21. metadata:
      22. name: http
      23. namespace: default
      24. spec:
      25. parentRefs:
      26. - name: gateway
      27. hostnames: ["httpbin.example.com"]
      28. rules:
      29. - matches:
      30. - path:
      31. type: PathPrefix
      32. value: /get
      33. backendRefs:
      34. - name: httpbin
      35. port: 8000
      36. EOF
    3. Access the httpbin service using curl:

      1. $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
      2. server: istio-envoy
      3. ...

      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.

    4. Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error:

      1. $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers"
      2. HTTP/1.1 404 Not Found
      3. ...
    5. Update the route rule to also expose /headers and to add a header to the request:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: gateway.networking.k8s.io/v1alpha2
      3. kind: HTTPRoute
      4. metadata:
      5. name: http
      6. namespace: default
      7. spec:
      8. parentRefs:
      9. - name: gateway
      10. namespace: istio-ingress
      11. hostnames: ["httpbin.example.com"]
      12. rules:
      13. - matches:
      14. - path:
      15. type: PathPrefix
      16. value: /get
      17. - path:
      18. type: PathPrefix
      19. value: /headers
      20. filters:
      21. - type: RequestHeaderModifier
      22. requestHeaderModifier:
      23. - name: my-added-header
      24. value: added-value
      25. backendRefs:
      26. - name: httpbin
      27. port: 8000
      28. EOF
    6. Access /headers again and notice header My-Added-Header has been added to the request:

    Deployment methods

    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 of the same name. These configurations will be updated automatically if the Gateway changes (for example, if a new port is added).

    These resources can be customized in a few ways:

    • Annotations and labels on the Gateway will be copied to the Service and Deployment. This allows configuring things such as Internal load balancers that read from these fields.

    • The Service.spec.loadBalancerIP field can be explicit set by configuring the addresses field:

      1. apiVersion: gateway.networking.k8s.io/v1alpha2
      2. kind: Gateway
      3. metadata:
      4. name: gateway
      5. spec:
      6. addresses:
      7. - value: 192.0.2.0
      8. type: IPAddress
      9. ...

    Note: only one address may be specified.

    • (Advanced) The generated Pod configuration can be configured by .

    Manual Deployment

    If you do not want to have an automated deployment, a Deployment and Service can be .

    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.

    To link a Gateway to a Service, configure the addresses field to point to a single Hostname.

    1. apiVersion: gateway.networking.k8s.io/v1alpha2
    2. kind: Gateway
    3. metadata:
    4. name: gateway
    5. spec:
    6. addresses:
    7. - value: ingress.istio-gateways.svc.cluster.local
    8. type: Hostname
    9. ...

    This feature is under development and pending .

    The Gateway API can also be used to configure mesh traffic. This is done by configuring the parentRef, to point to the istio Mesh. This resource does not actually exist in the cluster and is only used to signal that the Istio mesh should be used.

    For example, to redirect calls to example.com to an in-cluster Service named example:

    1. apiVersion: gateway.networking.k8s.io/v1alpha2
    2. kind: HTTPRoute
    3. metadata:
    4. name: mesh
    5. spec:
    6. parentRefs:
    7. - kind: Mesh
    8. name: istio
    9. hostnames: ["example.com"]
    10. rules:
    11. - backendRefs:
    12. - name: example
    13. port: 80

    Cleanup

    1. Uninstall Istio and the sample: