7 min read

Thanks for all Kubernetes Ingress API, Long life to Gateway API

Ingress API has been frozen. Yes, you heard well, our lovely Ingress API was officially frozen by Kubernetes itself during October 2023.
Thanks for all Kubernetes Ingress API, Long life to Gateway API

Primer

Ingress API is frozen.
Yes, you heard well, our lovely Ingress API was officially frozen by Kubernetes itself during October 2023.

To be honest, I suppose that this is the very first step before the full deprecation, which will not take place shortly.

So let's say the "last" goodbye to Ingress API 🥹 while saying a huge welcome to Gateway API.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

Thanks for all..

via GIPHY

You probably be in the above situation but DON'T PANIC, let's see in this article:

  • what our lovely Ingress API left to us
  • how we survived
  • what introduces the new GatewayAPI

Brief history of Ingress API

  • 🗓️ 2015 – Kubernetes introduces Ingress api
  • 🟢 2020 – Ingress api become stable

The aim was to build an API object able to manage external access to the services in a cluster, typically using HTTP protocol.

Main characteristics were:

  1. layer7 standard (even if we saw a lot of layer 3/4 implementations but the main aim was layer7)
  2. Portability

Well, the second aim (portability) was not a quite successful story and we all know what I mean (let's dive on it next).

How ingress works

Easy, define your Ingress yaml as below, apply on Kubernetes and.....

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: tls-example-ingress
spec:
 tls:
 - hosts:
     - https-example.foo.com
   secretName: testsecret-tls
 rules:
 - host: https-example.foo.com
   http:
     paths:
     - path: /
       pathType: Prefix
       backend:
         service:
           name: service1
           port:
             number: 80

Against all odds... nothing will happen!

How ingress (really) works

As said below, the main aim of Ingress API was to manage the HTTP traffic coming from the outside world, this traffic is called also as north/south traffic.

The missing component was of course the ingress controller concept.

Ingress controller was exactly the "guy" who make it happen.
Regardless of the provider implementations (ex. Ngnix, Traefik..), the Ingress controller was basically a pod with two aims:

  • actively watch for Ingress API inside the Kubernetes cluster and add/edit routing rules inside itself
  • route traffic coming from the outside to the correct backend service based on previous configurations

Of course, this new way enabled the decoupling of routing configuration (through Ingress API) from the proxy engine (Ingress controller).

What's wrong with Ingress API?

Well, basically nothing.

It solved for many years (and it’s still doing now) a specific basic problem.

So what it is missing?
Let's see mainly 3 bullets points:

  • No advanced usage
    Unfortunately, no advanced routing is available out-of-the-box.
    I can mention for example:
    • path rewriting
    • weighted routing
    • header manipulation

I have to add also to the list above that Ingress API resource and backend service must reside inside the same namespace.

  • Truly portability
    We all know how it ended...

Ingresses started taking the form of a supermarket tax receipt for the infinite list of annotations... 🤯🤯🤯🤯🤯🤯
And what about the redundancy of configurations (ex. tls)?

  • Finally, IMO the most important, not role oriented
    Ingress
    was not designed to scale in complex Kubernetes ecosystems with multiple environments/projects and consequently deal with multiple roles and responsibilities.

    This was mainly caused by the single file configuration where all stuff reside (ex. routing rules, hostnames, tls..)

    In complex organization, we know, tls configurations are usually managed by a role similar of a cluster operator or infrastructure engineer. On the other hand, routing rules are totally delegated to developers who know their applications.

Big picture

Let's put on the table another concept that was born in parallel, which is service mesh.
We could say that one of the most pioneer of service mesh is Istio.

A service mesh is a dedicated infrastructure layer that you can add to your applications.
It allows you to transparently add capabilities like observability, traffic management, and security, without adding them to your own code. 
Ref. https://istio.io/latest/about/service-mesh/

While Ingress took the responsibility of external traffic management (also called north/south traffic), Service mesh covered the internal communication between our pods (aka east/west traffic).

Istio was not limited to service mesh concept, it included also all the stuff that was missing in Ingress API adding the concept of Gateway, VirtualService and so on..

Welcome Gateway API

After the above primer, which was absolutely worth for our old friend Ingress API, let's say welcome to the missing network API standard in Kubernetes!

via GIPHY

ID card

Who is that? Gateway API is an open source project managed by the SIG-NETWORK community

Who compose SIG-NETWORK? “Network Special Interest Group” officially recognized by Kubernetes as a contributor to Kubernetes itself.More info → https://github.com/kubernetes/community/blob/master/sig-network/README.md

Stability (v1.0.0) 31 October 2023 → Gateway API v1.0 GA Release

Documentation https://gateway-api.sigs.k8s.io

Intro

Let me be honest, Gateway API was totally inspired by Istio.

They basically imported an abstraction of Istio as Kubernetes API.
This will enable more portability and less provider lock-in.

If you're familiar with the older Ingress API, you can think of the Gateway API as analogous to a more-expressive next-generation version of that API.

I leave here also an interesting Spotify episode in which Rob Scott (software engineer at Google and a lead on the SIG Network Gateway API project), in Jul 2022, talked about how Gateway API born and how Gateway API was growing.

--> https://open.spotify.com/episode/6oh4yqPaNv8huSpulwH38Z

From users side, GatewayAPI magically transformed the Ingress API resource to some more distinct and fragmented API resources, like

Gateway API (reasons of existing)

The reason of GatewayAPI existence is totally concentrated in the above figure.

Main features are

  • Role-oriented - Gateway is composed of API resources which model organizational roles that use and configure Kubernetes service networking.
  • Portable - This isn't an improvement but rather something that should stay the same. Just as Ingress is a universal specification with numerous implementations, Gateway API is designed to be a portable specification supported by many implementations.
  • Expressive - Gateway API resources support core functionality for things like header-based matching, traffic weighting, and other capabilities that were only possible in Ingress through custom annotations.
  • Extensible - Gateway API allows for custom resources to be linked at various layers of the API. This makes granular customization possible at the appropriate places within the API structure.

The name unfortunately could carry a misperception of what it really is because of course Gateway API is not an API Gateway.

Same words, different order but totally different meanings.

  • API Gateway is a general concept that describes anything that exposes capabilities of a backend service. A lot of solution in the markets (ex. AWS Api Gateway)
  • Gateway API is an interface, or set of resources, that model service networking in Kubernetes

A lot of API gateways are already implementing Gateway API standards, we can mention someone which is already in GA status:

  • GKE
  • Kong
  • Wso2
  • Nginx Gateway Fabric
  • EKS

Other (like Azure Application Gateway for containers) are in preview.
You can find the full list of implementations here.

Some analogies with Ingress API

Let's see for example how a typical Ingress definition will become using Gateway API instead.

First of all, the one yaml file of Ingress API will be split in 2/3 different definitions).

A gateway controller is software that manages the infrastructure associated with routing traffic across contexts using the Gateway API, analogous to the earlier ingress controller concept. Gateway controllers often, but not always, run in the cluster where they're managing infrastructure.

Gateway controller configure external API Gateway based on GatewayClass used.

Most of the time, running Kubernetes in a cloud managed way (ex. Azure/AWS), GatewayClass is defined and maintained by the cloud provider itself.
Providers usually create one GatewayClass per API Gateway topology (ex. internet or private implementation).

Gateway instead defines some high level routing information (like matched hostnames, tls configurations) and which routes could be attached to it.

Routes are instead the protocol-specific definition of how traffic has to be routed to backend services with some awesome features like header manipulation, traffic splitting, path rewriting and so on.

Examples

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: shared-gateway
  namespace: infra-ns
spec:
  gatewayClassName: shared-gateway-class
  listeners:
  - name: https
    hostname: "foo.example.com"
    protocol: HTTPS
    port: 443
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            shared-gateway-access: "true"
    tls:
      certificateRefs:
      - name: foo-example-com

Example of a Gateway definition which uses "shared-gateway-class", define tls configuration and allow to accept routes only from namespaces with "shared-gateway-access" label.

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
 name: http-filter-rewrite
spec:
 hostnames:
   - foo.example.com
 rules:
   - filters:
       - type: URLRewrite
         urlRewrite:
           hostname: elsewhere.example.com
           path:
             type: ReplacePrefixMatch
             replacePrefixMatch: /fennel
     backendRefs:
       - name: example-svc
         weight: 1
         port: 80

An example of a HTTPRouter which rewrite both the hostname and the path just before the traffic goes to the backend service "example-svc"

This is instead an easy example of traffic splitting based on a percentage weight (all defined inside the same HTTTRoute).

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
 name: simple-split
spec:
 rules:
 - backendRefs:
   - name: foo-v1
     port: 8080
     weight: 90
   - name: foo-v2
     port: 8080
     weight: 10

It is also possible to reference from a HTTPRoute a service which is living in another namespace, see below figure (ReferenceGrant resource involved to make it happen).

Summary

Even if IngressAPI is officially frozen, from the public FAQ we can read

Q: Will Gateway API replace the Ingress API?
A: No. The Ingress API is GA since Kubernetes 1.19. There are no plans to deprecate this API and we expect most Ingress controllers to support it indefinitely.

So for now we have to not worry about it, but nobody know...

Tweets by YBacciarini