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.