Migrating from Ingress

Gateway API project is the successor to the Ingress API. However, it does not include the Ingress resource (the closest parallel is the HTTPRoute). As a result, a one-time conversion from your existing Ingress resources to the relevant Gateway API resources is necessary.

This guide will help you with the conversion. It will:

  • Explain why you may want to switch to Gateway API.
  • Describe the key differences between the Ingress API and Gateway API.
  • Map Ingress features to Gateway API features.
  • Show an example of an Ingress resource converted to Gateway API resources.
  • Mention ingress2gateway for automatic conversion.

At the same time, it will not prepare you for a live migration or explain how to convert some implementation-specific features of your Ingress controller. Additionally, since the Ingress API only covers HTTP/HTTPS traffic, this guide does not cover Gateway API support for other protocols.

Reasons to Switch to Gateway API

The Ingress API is the standard Kubernetes way to configure external HTTP/HTTPS load balancing for Services. It is widely adopted by Kubernetes users and well-supported by vendors with many implementations (Ingress controllers) available. Additionally, several cloud-native projects integrate with the Ingress API, such as cert-manager and ExternalDNS.

However, the Ingress API has several limitations:

  • Limited features. The Ingress API only supports TLS termination and simple content-based request routing of HTTP traffic.
  • Reliance on annotations for extensibility. The annotations approach to extensibility leads to limited portability as every implementation has its own supported extensions that may not translate to any other implementation.
  • Insufficient permission model. The Ingress API is not well-suited for multi-team clusters with shared load-balancing infrastructure.

Gateway API addresses those limitations, as the next section will show.

Read more about the design goals of Gateway API.

Key Differences Between Ingress API and Gateway API

There are three major differences between the Ingress API and Gateway API:

  • Personas
  • Available features
  • Approach to extensibility (implementation-specific features)

Personas

At first, the Ingress API had only a single resource kind Ingress. As a result, it had only one persona — the user — the owner of Ingress resources. The Ingress features give the user a lot of control over how applications are exposed to their external clients, including TLS termination configuration and provisioning of the load balancing infrastructure (supported by some Ingress controllers). Such a level of control is called the self-service model.

At the same time, the Ingress API also included two implicit personas to describe somebody responsible for provisioning and managing an Ingress controller: the infrastructure provider for provider-managed Ingress controllers and the cluster operator (or admin) for self-hosted Ingress controllers. With the late addition of the IngressClass resource, the infrastructure provider and cluster operator became the owners of that resource, and thus, explicit personas of the Ingress API.

Gateway API includes four explicit personas: the application developer, the application admin, the cluster operator, and the infrastructure providers. This allows you to break away from the self-service model by splitting the responsibilities of the user persona across those personas (all except the infrastructure provider):

  • The cluster operator/application admin defines entry points for the external client traffic including TLS termination configuration.
  • The application developer defines routing rules for their applications that attach to those entry points.

Such a split adheres to a common organizational structure where multiple teams share the same load-balancing infrastructure. At the same time, it is not mandatory to give up the self-service model — it is still possible to configure a single RBAC Role that will fulfill the application developer, application admin, and cluster operator responsibilities.

The table below summarizes the mapping between the Ingress API and the Gateway API personas:

Ingress API PersonaGateway API Persona
UserApplication developer, Application admin, Cluster operator
Cluster operatorCluster operator
Infrastructure providerInfrastructure provider

Available Features

The Ingress API comes with basic features only: TLS termination and content-based routing of HTTP traffic based on the host header and the URI of a request. To offer more features, Ingress controllers support them through annotations on the Ingress resource which are implementation-specific extensions to the Ingress API.

The annotations approach to extensibility has two negative consequences for users of the Ingress API:

  • Limited portability. Because so many features are available through annotations, switching between Ingress controllers becomes difficult or even impossible, as it is necessary to convert the annotations of one implementation to another (the other implementation might not even support some features of the first one). This limits the portability of the Ingress API.
  • Awkwardness of the API. Because annotations are key-value strings (as opposed to a structured scheme like the spec of the Ingress resource) and applied at the top of a resource (rather than in the relevant parts of the spec), the Ingress API can become awkward to use, especially when a large number of annotations are added to an Ingress resource.

Gateway API supports all the features of the Ingress resources and many features that are only available through annotations. As a result, the Gateway API is more portable than the Ingress API. Additionally, as the next section will show, you will not need to use any annotations at all, which addresses the awkwardness problem.

Approach to Extensibility

The Ingress API has two extensions points:

  • Annotations on the Ingress resource (described in the previous section)
  • Resource backends, which is the ability to specify a backend other than a Service

Gateway API is feature-rich compared with the Ingress API. However, to configure some advanced features like authentication or common but non-portable across data planes features like connection timeouts and health checks, you will need to rely on the extensions of Gateway API.

Gateway API has the following primary extension points:

  • External references. A feature (field) of a Gateway API resource can reference a custom resource specific to the Gateway implementation that configures that feature. For example:
  • Custom implementations. For some features, it is left up to an implementation to define how to support them. Those features correspond to the implementation-specific (custom) conformance level. For example:
  • Policies. A Gateway implementation can define custom resources called Policies for exposing data plane features like authentication. Gateway API does not prescribe the details of those resources. However, it prescribes a standard UX. See the Policy attachment guide for more details. In contrast with the external references above, a Gateway API resource does not reference a Policy. Instead, a Policy must reference a Gateway API resource.

The extension points do not include annotations on Gateway API resources. This approach is strongly discouraged for implementations of the API.

Mapping Ingress API features to Gateway API Features

This section will map the Ingress API features to the corresponding Gateway API features, covering three major areas:

  • Entry points
  • TLS termination
  • Routing rules

Entry Points

Roughly speaking, an entry point is a combination of an IP address and port through which the data plane is accessible to external clients.

Every Ingress resource has two implicit entry points — one for HTTP and the other for HTTPS traffic. An Ingress controller provides those entry points. Typically, they will either be shared by all Ingress resources, or every Ingress resource will get dedicated entry points.

In Gateway API, entry points must be explicitly defined in a Gateway resource. For example, if you want the data plane to handle HTTP traffic on port 80, you need to define a listener for that traffic. Typically, a Gateway implementation provides a dedicated data plane for each Gateway resource.

Gateway resources are owned by the cluster operator and the application admin.

TLS Termination

The Ingress resource supports TLS termination via the TLS section, where the TLS certificate and key are stored in a Secret.

In Gateway API, TLS termination is a property of the Gateway listener, and similarly to the Ingress, a TLS certificate and key are also stored in a Secret.

Because the listener is part of the Gateway resource, the cluster operator and application admin own TLS termination.

Routing Rules

The path-based routing rules of the Ingress resource map directly to the routing rules of the HTTPRoute.

The host-header-based routing rules map to the hostnames of the HTTPRoute. However, note that in the Ingress, each hostname has separate routing rules, while in the HTTPRoute the routing rules apply to all hostnames.

The Ingress API uses the term host while Gateway API uses the hostname. This guide will use Gateway API term to refer to the Ingress host.

The hostnames of an HTTPRoute must match the hostname of the Gateway listener. Otherwise, the listener will ignore the routing rules for the unmatched hostnames. See the HTTPRoute documentation.

HTTPRoutes are owned by the application developer.

The next three sections map additional features of the Ingress routing rules.

Rules Merging and Conflict Resolution

Typically, Ingress controllers merge routing rules from all Ingress resources (unless they provision a data plane per each Ingress resource) and resolve potential conflicts among the rules. However, both merging and conflict resolution are not prescribed by the Ingress API, so Ingress controllers might implement them differently.

In contrast, Gateway API specifies how to merge rules and resolve conflicts:

  • A Gateway implementation must merge the routing rules from all HTTPRoutes attached to a listener.
  • Conflicts must be handled as prescribed here. For example, more specific matches in a routing rule win over the less specific ones.

Default Backend

The Ingress default backend configures a backend that will respond to all unmatched HTTP requests related to that Ingress resource. Gateway API does not have a direct equivalent: it is necessary to define such a routing rule explicitly. For example, define a rule to route requests with the path prefix / to a Service that corresponds to the default backend.

Selecting Data Plane to Attach to

An Ingress resource must specify a class to select which Ingress controller to use. An HTTPRoute must specify which Gateway (or Gateways) to attach to via a parentRef.

Implementation-Specific Ingress Features (Annotations)

Ingress annotations configure implementation-specific features. Thus, converting them to Gateway API depends both on the Ingress controller and Gateway implementations.

Luckily, some of the features supported through annotations are now part of the Gateway API (HTTPRoute), primarily:

  • Request redirects (including a TLS redirect)
  • Request/response manipulation
  • Traffic splitting
  • Header, query param, or method-based routing

However, the remaining features remain largely implementation-specific. To convert them, consult the Gateway implementation documentation to see which extension point to use.

Example

This section shows an example of how to convert an Ingress resource to Gateway API resources.

Assumptions

The example includes the following assumptions:

  • All resources belong to the same namespace.
  • The Ingress controller:
    • Has the corresponding IngressClass resource prod in the cluster.
    • Supports the TLS redirect feature via the example-ingress-controller.example.org/tls-redirect annotation.
  • The Gateway implementation has the corresponding GatewayClass resource prod in the cluster.

Additionally, the content of the referenced Secret and Services as well as IngressClass and GatewayClass are omitted for brevity.

Ingress Resource

The Ingress below defines the following configuration:

  • Configure a TLS redirect for any HTTP request for foo.example.com and bar.example.com hostnames using the example-ingress-controller.example.org/tls-redirect annotation.
  • Terminate TLS for the foo.example.com and bar.example.com hostnames using the TLS certificate and key from the Secret example-com.
  • Route HTTPS requests for the foo.example.com hostname with the URI prefix /orders to the foo-orders-app Service.
  • Route HTTPS requests for the foo.example.com hostname with any other prefix to the foo-app Service.
  • Route HTTPS requests for the bar.example.com hostname with any URI to the bar-app Service.
  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. name: example-ingress
  5. annotations:
  6. some-ingress-controller.example.org/tls-redirect: "True"
  7. spec:
  8. ingressClassName: prod
  9. tls:
  10. - hosts:
  11. - foo.example.com
  12. - bar.example.com
  13. secretName: example-com
  14. rules:
  15. - host: foo.example.com
  16. http:
  17. paths:
  18. - path: /
  19. pathType: Prefix
  20. backend:
  21. service:
  22. name: foo-app
  23. port:
  24. number: 80
  25. - path: /orders
  26. pathType: Prefix
  27. backend:
  28. service:
  29. name: foo-orders-app
  30. port:
  31. number: 80
  32. - host: bar.example.com
  33. http:
  34. paths:
  35. - path: /
  36. pathType: Prefix
  37. backend:
  38. service:
  39. name: bar-app
  40. port:
  41. number: 80

The next three sections convert that Ingress into Gateway API resources.

Conversion Step 1 - Define Gateway

The following Gateway resource:

  • Belongs to our GatewayClass prod.
  • Provisions load balancing infrastructure (this depends on the Gateway implementation).
  • Configures HTTP and HTTPS listeners (entry points), which the Ingress resource included implicitly:
    • The HTTP listener http on port 80
    • The HTTPS listener https on port 443 with TLS termination with the cert and key stored in the example-com Secret, which is the same Secret used in the Ingress

Also, note that both listeners allow all HTTPRoutes from the same namespace (which is the default setting) and restrict HTTPRoute hostnames to the example.com subdomain (allow hostnames like foo.example.com but not foo.kubernetes.io).

  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: Gateway
  3. metadata:
  4. name: example-gateway
  5. spec:
  6. gatewayClassName: prod
  7. listeners:
  8. - name: http
  9. port: 80
  10. protocol: HTTP
  11. hostname: "*.example.com"
  12. - name: https
  13. port: 443
  14. protocol: HTTPS
  15. hostname: "*.example.com"
  16. tls:
  17. mode: Terminate
  18. certificateRefs:
  19. - kind: Secret
  20. name: example-com
  21. - name: https-default-tls-mode
  22. port: 8443
  23. protocol: HTTPS
  24. hostname: "*.foo.com"
  25. tls:
  26. certificateRefs:
  27. - kind: Secret
  28. name: foo-com

Conversion Step 2 - Define HTTPRoutes

The Ingress is split into two HTTPRoutes — one for foo.example.com and one for bar.example.com hostnames.

  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: HTTPRoute
  3. metadata:
  4. name: foo
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. sectionName: https
  9. hostnames:
  10. - foo.example.com
  11. rules:
  12. - matches:
  13. - path:
  14. type: PathPrefix
  15. value: /
  16. backendRefs:
  17. - name: foo-app
  18. port: 80
  19. - matches:
  20. - path:
  21. type: PathPrefix
  22. value: /orders
  23. backendRefs:
  24. - name: foo-orders-app
  25. port: 80
  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: HTTPRoute
  3. metadata:
  4. name: bar
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. sectionName: https
  9. hostnames:
  10. - bar.example.com
  11. rules:
  12. - matches:
  13. - path:
  14. type: PathPrefix
  15. value: /
  16. backendRefs:
  17. - name: bar-app
  18. port: 80

Both HTTPRoutes:

  • Attach to the https listener of the Gateway resource from Step 1.
  • Define the same routing rules as in the Ingress rules for the corresponding hostname.

Step 3 - Configure TLS Redirect

The following HTTPRoute configures a TLS redirect, which the Ingress resource configured via an annotation. The HTTPRoute below:

  • Attaches to the http listener of our Gateway.
  • Issues a TLS redirect for any HTTP request for the foo.example.com or bar.example.com hostnames.
  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: HTTPRoute
  3. metadata:
  4. name: tls-redirect
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. sectionName: http
  9. hostnames:
  10. - foo.example.com
  11. - bar.example.com
  12. rules:
  13. - filters:
  14. - type: RequestRedirect
  15. requestRedirect:
  16. scheme: https
  17. port: 443

Automatic Conversion of Ingresses

The Ingress to Gateway project helps translate Ingress resources to Gateway API resources, specifically HTTPRoutes. The conversion results should always be tested and verified.