sigs.k8s.io/gateway-api@v1.0.0/site-src/guides/migrating-from-ingress.md (about)

     1  # Migrating from Ingress
     2  
     3  The Gateway API project is the successor to the [Ingress API][ing]. However, it
     4  does not include the Ingress resource (the closest parallel is the HTTPRoute).
     5  As a result, a one-time conversion from your existing Ingress resources to the
     6  relevant Gateway API resources is necessary.
     7  
     8  [ing]:https://kubernetes.io/docs/concepts/services-networking/ingress/
     9  
    10  This guide will help you with the conversion. It will:
    11  
    12  * Explain why you may want to switch to the Gateway API.
    13  * Describe the key differences between the Ingress API and the Gateway API.
    14  * Map Ingress features to Gateway API features.
    15  * Show an example of an Ingress resource converted to Gateway API resources.
    16  * Mention [ingress2gateway](https://github.com/kubernetes-sigs/ingress2gateway)
    17    for automatic conversion.
    18  
    19  At the same time, it will not prepare you for a live migration or explain how to
    20  convert some implementation-specific features of your Ingress controller.
    21  Additionally, since the Ingress API only covers HTTP/HTTPS traffic, this guide
    22  does not cover the Gateway API support for other protocols.
    23  
    24  ## Reasons to Switch to Gateway API
    25  
    26  The [Ingress API](https://kubernetes.io/docs/concepts/services-networking/ingress/)
    27  is the standard Kubernetes way to configure external HTTP/HTTPS load balancing
    28  for Services. It is widely adopted by Kubernetes users and well-supported by
    29  vendors with many implementations ([Ingress controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/))
    30  available. Additionally, several cloud-native projects integrate with the
    31  Ingress API, such as [cert-manager](https://cert-manager.io/)
    32  and [ExternalDNS](https://github.com/kubernetes-sigs/external-dns).
    33  
    34  However, the Ingress API has several limitations:
    35  
    36  - *Limited features*. The Ingress API only supports TLS termination and
    37    simple content-based request routing of HTTP traffic.
    38  - *Reliance on annotations for extensibility*. The annotations approach to
    39    extensibility leads to limited portability as every implementation has its own
    40    supported extensions that may not translate to any other implementation.
    41  - *Insufficient permission model*. The Ingress API is not well-suited for
    42    multi-team clusters with shared load-balancing infrastructure.
    43  
    44  The Gateway API addresses those limitations, as the next section will show.
    45  
    46  > Read more about the [design goals](https://gateway-api.sigs.k8s.io/#gateway-api-concepts)
    47  > of the Gateway API.
    48  
    49  ## Key Differences Between Ingress API and Gateway API
    50  
    51  There are three major differences between the Ingress API and the Gateway API:
    52  
    53  * Personas
    54  * Available features
    55  * Approach to extensibility (implementation-specific features)
    56  
    57  ### Personas
    58  
    59  At first, the Ingress API had only a single resource kind Ingress. As a result,
    60  it had only one persona -- the user -- the owner of Ingress resources. The
    61  Ingress features give the user a lot of control over how applications are
    62  exposed to their external clients, including TLS termination configuration and
    63  provisioning of the load balancing infrastructure (supported by some Ingress
    64  controllers). Such a level of control is called the self-service model.
    65  
    66  At the same time, the Ingress API also included two implicit personas to
    67  describe somebody responsible for provisioning and managing an Ingress
    68  controller: the infrastructure provider for provider-managed Ingress controllers
    69  and the cluster operator (or admin) for self-hosted Ingress controllers. With
    70  the late addition of
    71  the [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)
    72  resource, the infrastructure provider and cluster operator became the owners of
    73  that resource, and thus, explicit personas of the Ingress API.
    74  
    75  The Gateway API
    76  includes [four explicit personas](/concepts/security-model/#roles-and-personas):
    77  the application developer, the application admin, the cluster operator, and the
    78  infrastructure providers. This allows you to break away from the self-service
    79  model by splitting the responsibilities of the user persona across those
    80  personas (all except the infrastructure provider):
    81  
    82  * The cluster operator/application admin defines entry points for the external
    83    client traffic including TLS termination configuration.
    84  * The application developer defines routing rules for their applications that
    85    attach to those entry points.
    86  
    87  Such a split adheres to a common organizational structure where multiple teams
    88  share the same load-balancing infrastructure. At the same time, it is not
    89  mandatory to give up the self-service model -- it is still possible to configure
    90  a single RBAC Role that will fulfill the application developer, application
    91  admin, and cluster operator responsibilities.
    92  
    93  The table below summarizes the mapping between the Ingress API and the Gateway
    94  API personas:
    95  
    96  | Ingress API Persona | Gateway API Persona |
    97  |-|-|
    98  | User | Application developer, Application admin, Cluster operator |
    99  | Cluster operator | Cluster operator |
   100  | Infrastructure provider | Infrastructure provider |
   101  
   102  ### Available Features
   103  
   104  The Ingress API comes with basic features only: TLS termination and
   105  content-based routing of HTTP traffic based on the host header and the URI of a
   106  request. To offer more features, Ingress controllers support them through
   107  [annotations][anns] on the Ingress resource which are implementation-specific
   108  extensions to the Ingress API.
   109  
   110  [anns]:https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
   111  The annotations approach to extensibility has two negative consequences for
   112  users of the Ingress API:
   113  
   114  * *Limited portability*. Because so many features are available through
   115    annotations, switching between Ingress controllers becomes difficult or even
   116    impossible, as it is necessary to convert the annotations of one
   117    implementation to another (the other implementation might not even support
   118    some features of the first one). This limits the portability of the Ingress
   119    API.
   120  * *Awkwardness of the API*. Because annotations are key-value strings (as
   121    opposed to a structured scheme like the spec of the Ingress resource) and
   122    applied at the top of a resource (rather than in the relevant parts of the
   123    spec), the Ingress API can become awkward to use, especially when a large
   124    number of annotations are added to an Ingress resource.
   125  
   126  The Gateway API supports all the features of the Ingress resources and many
   127  features that are only available through annotations. As a result, the Gateway
   128  API is more portable than the Ingress API. Additionally, as the next section
   129  will show, you will not need to use any annotations at all, which addresses the
   130  awkwardness problem.
   131  
   132  ### Approach to Extensibility
   133  
   134  The Ingress API has two extensions points:
   135  
   136  * Annotations on the Ingress resource (described in the previous section)
   137  * [Resource backends](https://kubernetes.io/docs/concepts/services-networking/ingress/#resource-backend),
   138     which is the ability to specify a backend other than a Service
   139  
   140  The Gateway API is feature-rich compared with the Ingress API. However, to
   141  configure some advanced features like authentication or common but non-portable
   142  across data planes features like connection timeouts and health checks, you will
   143  need to rely on the extensions of the Gateway API.
   144  
   145  The Gateway API has the following primary extension points:
   146  
   147  * *External references.* A feature (field) of a Gateway API resource can
   148    reference a custom resource specific to the Gateway implementation that
   149    configures that feature. For example:
   150      * [HTTPRouteFilter](/reference/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteFilter)
   151        can reference an external resource via the `extensionRef` field, thus
   152        configuring an implementation-specific filter.
   153      * [BackendObjectReference](/reference/spec/#gateway.networking.k8s.io/v1beta1.BackendObjectReference)
   154        supports resources other than Services.
   155      * [SecretObjectReference](/reference/spec/#gateway.networking.k8s.io/v1beta1.SecretObjectReference)
   156        supports resources other than Secrets.
   157  * *Custom implementations*. For some features, it is left up to an
   158    implementation to define how to support them. Those features correspond to the
   159    implementation-specific
   160    (custom)  [conformance level](/concepts/conformance/#2-support-levels). For
   161    example:
   162      * The `RegularExpression` type of
   163        the [HTTPPathMatch](/reference/spec/#gateway.networking.k8s.io/v1beta1.HTTPPathMatch).
   164  * *Policies.* A Gateway implementation can define custom resources called
   165    Policies for exposing data plane features like authentication. The Gateway API
   166    does not prescribe the details of those resources. However, it prescribes a
   167    standard UX. See the [Policy attachment guide](/reference/policy-attachment/)
   168    for more details. In contrast with the *external references* above, a Gateway
   169    API resource does not reference a Policy. Instead, a Policy must reference a
   170    Gateway API resource.
   171  
   172  The extension points do not include annotations on the Gateway API resources.
   173  This approach is strongly discouraged for implementations of the API.
   174  
   175  ## Mapping Ingress API features to Gateway API Features
   176  
   177  This section will map the Ingress API features to the corresponding Gateway API
   178  features, covering three major areas:
   179  
   180  * Entry points
   181  * TLS termination
   182  * Routing rules
   183  
   184  ### Entry Points
   185  
   186  Roughly speaking, an entry point is a combination of an IP address and port
   187  through which the data plane is accessible to external clients.
   188  
   189  Every Ingress resource has two implicit entry points -- one for HTTP and the
   190  other for HTTPS traffic. An Ingress controller provides those entry points.
   191  Typically, they will either be shared by all Ingress resources, or every Ingress
   192  resource will get dedicated entry points.
   193  
   194  In the Gateway API, entry points must be explicitly defined in
   195  a [Gateway](/api-types/gateway/) resource. For example, if you want the data
   196  plane to handle HTTP traffic on port 80, you need to define
   197  a [listener](/reference/spec/#gateway.networking.k8s.io/v1beta1.Listener) for
   198  that traffic. Typically, a Gateway implementation provides a dedicated data
   199  plane for each Gateway resource.
   200  
   201  Gateway resources are owned by the cluster operator and the application admin.
   202  
   203  ### TLS Termination
   204  
   205  The Ingress resource supports TLS termination via
   206  the [TLS section](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls),
   207  where the TLS certificate and key are stored in a Secret.
   208  
   209  In the Gateway API, TLS termination is a property of
   210  the [Gateway listener](/reference/spec/#gateway.networking.k8s.io/v1beta1.Listener),
   211  and similarly to the Ingress, a TLS certificate and key are also stored in a
   212  Secret.
   213  
   214  Because the listener is part of the Gateway resource, the cluster operator and
   215  application admin own TLS termination.
   216  
   217  ### Routing Rules
   218  
   219  The [path-based routing rules](https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types)
   220  of the Ingress resource map directly to
   221  the [routing rules](/reference/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteRule)
   222  of the [HTTPRoute](/api-types/httproute/).
   223  
   224  The [host-header-based routing rules](https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting)
   225  map to
   226  the [hostnames](/reference/spec/#gateway.networking.k8s.io/v1beta1.Hostname) of
   227  the HTTPRoute. However, note that in the Ingress, each hostname has separate
   228  routing rules, while in the HTTPRoute the routing rules apply to all hostnames.
   229  
   230  > The Ingress API uses the term host while the Gateway API uses the hostname.
   231  > This guide will use the Gateway API term to refer to the Ingress host.
   232  
   233  > The `hostnames` of an HTTPRoute must match the `hostname` of the [Gateway listener](/reference/spec/#gateway.networking.k8s.io/v1beta1.Listener).
   234  > Otherwise, the listener will ignore the routing rules for the unmatched
   235  > hostnames. See the [HTTPRoute documentation](/reference/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec).
   236  
   237  HTTPRoutes are owned by the application developer.
   238  
   239  The next three sections map additional features of the Ingress routing rules.
   240  
   241  #### Rules Merging and Conflict Resolution
   242  
   243  Typically, Ingress controllers merge routing rules from all Ingress resources
   244  (unless they provision a data plane per each Ingress resource) and resolve
   245  potential conflicts among the rules. However, both merging and conflict
   246  resolution are not prescribed by the Ingress API, so Ingress controllers might
   247  implement them differently.
   248  
   249  In contrast, the Gateway API specifies how to merge rules and resolve conflicts:
   250  
   251  * A Gateway implementation must merge the routing rules from all HTTPRoutes
   252    attached to a listener.
   253  * Conflicts must be handled as
   254    prescribed [here](/concepts/guidelines/#conflicts). For example, more specific
   255    matches in a routing rule win over the less specific ones.
   256  
   257  #### Default Backend
   258  
   259  The
   260  Ingress [default backend](https://kubernetes.io/docs/concepts/services-networking/ingress/#default-backend)
   261  configures a backend that will respond to all unmatched HTTP requests related to
   262  that Ingress resource. The Gateway API does not have a direct equivalent: it is
   263  necessary to define such a routing rule explicitly. For example, define a rule
   264  to route requests with the path prefix `/` to a Service that corresponds to the
   265  default backend.
   266  
   267  #### Selecting Data Plane to Attach to
   268  
   269  An Ingress resource must specify
   270  a [class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)
   271  to select which Ingress controller to use. An HTTPRoute must specify which
   272  Gateway (or Gateways) to attach to via
   273  a [parentRef](/reference/spec/#gateway.networking.k8s.io/v1beta1.ParentRef).
   274  
   275  ### Implementation-Specific Ingress Features (Annotations)
   276  
   277  Ingress annotations configure implementation-specific features. Thus, converting
   278  them to the Gateway API depends both on the Ingress controller and Gateway
   279  implementations.
   280  
   281  Luckily, some of the features supported through annotations are now part of the
   282  Gateway API (HTTPRoute), primarily:
   283  
   284  * Request redirects (including a TLS redirect)
   285  * Request/response manipulation
   286  * Traffic splitting
   287  * Header, query param, or method-based routing
   288  
   289  However, the remaining features remain largely implementation-specific. To
   290  convert them, consult the Gateway implementation documentation to see
   291  which [extension point](#approach-to-extensibility) to use.
   292  
   293  ## Example
   294  
   295  This section shows an example of how to convert an Ingress resource to Gateway
   296  API resources.
   297  
   298  ### Assumptions
   299  
   300  The example includes the following assumptions:
   301  
   302  * All resources belong to the same namespace.
   303  * The Ingress controller:
   304      * Has the corresponding IngressClass resource  `prod` in the cluster.
   305      * Supports the TLS redirect feature via
   306        the `example-ingress-controller.example.org/tls-redirect` annotation.
   307  * The Gateway implementation has the corresponding GatewayClass resource `prod`
   308    in the cluster.
   309  
   310  Additionally, the content of the referenced Secret and Services as well as
   311  IngressClass and GatewayClass are omitted for brevity.
   312  
   313  ### Ingress Resource
   314  
   315  The Ingress below defines the following configuration:
   316  
   317  * Configure a TLS redirect for any HTTP request for  `foo.example.com`
   318    and `bar.example.com` hostnames using
   319    the  `example-ingress-controller.example.org/tls-redirect` annotation.
   320  * Terminate TLS for the `foo.example.com` and `bar.example.com` hostnames using
   321    the TLS certificate and key from the Secret `example-com`.
   322  * Route HTTPS requests for the `foo.example.com` hostname with the URI
   323    prefix `/orders` to the `foo-orders-app` Service.
   324  * Route HTTPS requests for the  `foo.example.com` hostname with any other prefix
   325    to the `foo-app` Service.
   326  * Route HTTPS requests for the `bar.example.com` hostname with any URI to
   327    the `bar-app` Service.
   328  
   329  ```yaml
   330  apiVersion: networking.k8s.io/v1
   331  kind: Ingress
   332  metadata:
   333    name: example-ingress
   334    annotations:
   335      some-ingress-controller.example.org/tls-redirect: "True"
   336  spec:
   337    ingressClassName: prod
   338    tls:
   339    - hosts:
   340      - foo.example.com
   341      - bar.example.com
   342      secretName: example-com
   343    rules:
   344    - host: foo.example.com
   345      http:
   346        paths:
   347        - path: /
   348          pathType: Prefix
   349          backend:
   350            service:
   351              name: foo-app
   352              port:
   353                number: 80
   354        - path: /orders
   355          pathType: Prefix
   356          backend:
   357            service:
   358              name: foo-orders-app
   359              port:
   360                number: 80
   361    - host: bar.example.com
   362      http:
   363        paths:
   364        - path: /
   365          pathType: Prefix
   366          backend:
   367            service:
   368              name: bar-app
   369              port:
   370                number: 80
   371  ```
   372  
   373  The next three sections convert that Ingress into Gateway API resources.
   374  
   375  ### Conversion Step 1 - Define Gateway
   376  
   377  The following Gateway resource:
   378  
   379  * Belongs to our GatewayClass `prod`.
   380  * Provisions load balancing infrastructure (this depends on the Gateway
   381    implementation).
   382  * Configures HTTP and HTTPS listeners (entry points), which the Ingress resource
   383    included implicitly:
   384      * The HTTP listener `http` on port `80`
   385      * The HTTPS listener `https` on port `443` with TLS termination with the
   386        cert and key stored in the `example-com` Secret, which is the same Secret
   387        used in the Ingress
   388  
   389  Also, note that both listeners allow all HTTPRoutes from the same namespace
   390  (which is the default setting) and restrict HTTPRoute hostnames to
   391  the `example.com` subdomain (allow hostnames like `foo.example.com` but
   392  not `foo.kubernetes.io`).
   393  
   394  ```yaml
   395  {% include 'standard/simple-http-https/gateway.yaml' %}
   396  ```
   397  
   398  ### Conversion Step 2 - Define HTTPRoutes
   399  
   400  The Ingress is split into two HTTPRoutes -- one for `foo.example.com` and one
   401  for `bar.example.com` hostnames.
   402  
   403  ```yaml
   404  {% include 'standard/simple-http-https/foo-route.yaml' %}
   405  ```
   406  
   407  ```yaml
   408  {% include 'standard/simple-http-https/bar-route.yaml' %}
   409  ```
   410  
   411  Both HTTPRoutes:
   412  
   413  * Attach to the `https` listener of the Gateway resource from Step 1.
   414  * Define the same routing rules as in the Ingress rules for the corresponding
   415    hostname.
   416  
   417  ### Step 3 - Configure TLS Redirect
   418  
   419  The following HTTPRoute configures a TLS redirect, which the Ingress resource
   420  configured via an annotation. The HTTPRoute below:
   421  
   422  * Attaches to the `http` listener of our Gateway.
   423  * Issues a TLS redirect for any HTTP request for the `foo.example.com`
   424    or `bar.example.com` hostnames.
   425  
   426  ```yaml
   427  {% include 'standard/simple-http-https/tls-redirect-route.yaml' %}
   428  ```
   429  
   430  ## Automatic Conversion of Ingresses
   431  
   432  The [Ingress to Gateway](https://github.com/kubernetes-sigs/ingress2gateway)
   433  project helps translate Ingress resources to Gateway API resources, specifically
   434  HTTPRoutes. The conversion results should always be tested and verified.