The GatewayAPI resource is an alternative and replacement to Ingress resource. The Gateway resource provides functionality not available in the Ingress resource and offers the opportunity to simplify Kubernetes application access. The GatewayAPI provides a number of key benefits over the legacy Ingress/LoadBalancer model.
This use-case does not cover the infrastructure design differences between an Ingress infrastructure and a Gateway infrastructure. It assumes that an existing, operational Ingress infrastructure is present and illustrates how to migration the Ingress resource to a Gateway Resource.
The following Ingress resources is a simple fanout example taken directly from the Kubernetes documentation. It includes a host rule creating an initial filter based upon the URL and two prefix based paths backed by two different services.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: simple-fanout-example spec: rules: - host: foo.bar.com http: paths: - path: /foo pathType: Prefix backend: service: name: service1 port: number: 4200 - path: /bar pathType: Prefix backend: service: name: service2 port: number: 8080
The Gateway resources are similar but has some important differences.
An Ingress is a predefined shared resource. How the resource is created depends of the environment and the specific Ingress implementation selected. A Gateway resource is defined differently. Gateways are created on demand, the reference used to create a gateway is defined using a gatewayClass. There can be many gatewayClasses all specifying different gateway configurations. How gateway infrastructure configuration are defined is implementation specific. In the EPIC implementation, a gatewayClass references a gatewayClassConfig which includes information used to create a Gateway in EPIC, and the gateway template, a the infrastructure blueprint for the Gateway that will be created.
Unlike an Ingress, a Gateway does not exist until its created with a gateway resources that references the gatewayclass. In the case of EPIC and other external gateway implementations, gateways are created on demand, and its possible to create as many gateways as required by applications in the cluster. By default gateways are not shared among namespaces.
In our example we assume that that their is a gatewayClass called example-gateway-class. The following creates a gateway resource. Note that the listeners are created on demand, this is different to the Ingress where the IP addresses and listeners are predefined during Ingress installation.
apiVersion: gateway.networking.k8s.io/v1alpha2 kind: Gateway metadata: name: example-gateway spec: gatewayClassName: example-gateway-class listeners: - name: http protocol: HTTP port: 80
$ kubectl get gtw NAME CLASS ADDRESS READY AGE example-gateway example-gateway-class 184.108.40.206 True 47d
Creating the gateway object instantiates the gateway, configuring the downstream listener, allocating IP addresses and optionally DNS names. The Gateway is now ready and routes can be added. The Gateway object is seperate from the Route object because the persistency of gateways and routes are probably different. A Gateway would be created so an application can be accessed, the structure of the application is defined in routes, these will probably change over time as new versions are tested and deployed.
The following example creates is the httpRoute object that provides the same functionality as the ingress object above.
apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: simple-fanout-example spec: parentRefs: - name: example-gateway hostnames: - "foo.bar.com" rules: - matches: - path: type: PathPrefix value: /foo backendRefs: - name: service1 port: 4200 - matches: - path: type: Prefix value: /bar backendRefs: - name: service2 port: 8080
The httpRoute resource is very similar to the ingress resource in this example, however the value of the httpRoute resource is the ability to add additional functionality. Extending the example above to add a test version of service2 at the same url route accessed via a custom header “test-match: dev1” match would result in the following configuration
apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: simple-fanout-example spec: parentRefs: - name: example-gateway hostnames: - "foo.bar.com" rules: - matches: - path: type: PathPrefix value: /foo backendRefs: - name: service1 port: 4200 - matches: - path: type: Prefix value: /bar backendRefs: - name: service2 port: 8080 - matches: - path: type: Prefix value: /bar - name: test-match type: Exact value: dev1 backendRefs: - name: service2-test port: 8080