gateway-api-integrator

Gateway API Integrator

Channel Revision Published Runs on
latest/stable 14 01 Jul 2024
Ubuntu 24.04 Ubuntu 22.04
latest/edge 96 23 Sep 2025
Ubuntu 24.04 Ubuntu 22.04
latest/edge 14 27 Jun 2024
Ubuntu 24.04 Ubuntu 22.04
juju deploy gateway-api-integrator
Show information

Platform:

Ubuntu
24.04 22.04

Charm architecture

The gateway-api-integrator charm is very similar to the nginx-ingress-integrator charm in that it provides Kubernetes ingress to charms that require it. However, instead of interacting with the Kubernetes cluster using the Ingress API, it uses the newer Gateway API , which offers a more portable, expressive, and extensible integration with all types of Kubernetes clusters.

The Gateway API integrator receives ingress requests using the ingress relation.
It relies on the tls-certificates relation to gather TLS certificates for the gateway’s TLS configuration. Information about the backend application is collected from the ingress relation and combined with the TLS certificates from the tls-certificates relation. As a result, Kubernetes Service resources, Gateway resources, HTTPRoute resources, and Secret resources will be created to facilitate ingress as expected by the ingress requirer.

In designing this charm, we’ve leveraged the sidecar pattern for Kubernetes charms, but somewhat unusually we’re not actually deploying a workload container alongside our charm code. Instead, the charm code talks directly to the Kubernetes API to provision the appropriate Gateway API resource to enable traffic to reach the service in question.

As a result, if you run kubectl get pods on a namespace named for the Juju model you’ve deployed the gateway-api-integrator charm into, you’ll see something like the following:

NAME                             READY   STATUS    RESTARTS   AGE
gateway-api-integrator-0       1/1     Running   0          3h47m

This shows there is only one container for the charm code.

OCI images

Gateway Ingress Integrator charm doesn’t use any OCI image resources.

Juju events

For this charm, the following Juju events are observed:

  1. config-changed
  2. start
  3. data-provided from ingress charm library
  4. data-removed from ingress charm library
  5. certificate-available from tls_certificates charm library
  6. certificate-expiring from tls_certificates charm library
  7. certificate-invalidated from tls_certificates charm library
  8. all-certificates-invalidated from tls_certificates charm library
  9. get-certificate-action
  10. certificates-relation-created
  11. certificates-relation-joined
  12. certificates-relation-broken

Charm code overview

The src/charm.py is the default entry point for a charm and has the GatewayAPICharm Python class which inherits from CharmBase. CharmBase is the base class from which all Charms are formed, defined by Ops (Python framework for developing charms).

See more in the Juju docs: Charm

Take, for example, when a configuration is changed by using the CLI.

  1. User runs the configuration command:
juju config gateway-api-integrator external-hostname=example.com
  1. A config-changed event is emitted.
  2. In the __init__ method is defined how to handle this event like this:
self.framework.observe(self.on.config_changed, self._on_config_changed)
  1. The method _on_config_changed, for its turn, will take the necessary actions such as waiting for all the relations to be ready and then configuring the containers.

Charm architecture diagram

The Gateway API Integrator charm uses the ingress and tls_certificates charm libraries to handle charm relations. It also uses the lightkube Python Kubernetes client, which is wrapped in custom modules to reconcile the Kubernetes resources necessary for ingress.

C4Context
    System_Boundary(gateway-api-integrator, "Gateway API Integrator") {
        Container_Boundary(charm-lib, "Charm Libraries") {
            Component(tls-certificates-lib, "tls_certificates_interface.v3.tls_certificates")
            Component(ingress-lib, "traefik_k8s.v2.ingress")
        }
        
        Container_Boundary(charm, "Charm Logic") {
            Component(gateway-api-integrator-charm, "Gateway API Integrator Charm")
        }
        
        Container_Boundary(kubernetes-lib, "Kubernetes Libraries") {
            Component(gateway, "Gateway")
            Component(http-route, "HTTPRoute")
            Component(secret, "Secret")
            Component(service, "Service")
        }
        
        Rel(tls-certificates-lib, gateway-api-integrator-charm, "Server Cert")
        Rel(ingress-lib, gateway-api-integrator-charm, "Ingress Spec")
        Rel(gateway-api-integrator-charm, gateway, "Reconciliation")
        Rel(gateway-api-integrator-charm, http-route, "Reconciliation")
        Rel(gateway-api-integrator-charm, secret, "Reconciliation")
        Rel(gateway-api-integrator-charm, service, "Reconciliation")

        UpdateLayoutConfig($c4ShapeInRow="1", $c4BoundaryInRow="4")
        
        UpdateRelStyle(tls-certificates-lib, gateway-api-integrator-charm, $offsetY="10", $offsetX="-40")
        UpdateRelStyle(ingress-lib, gateway-api-integrator-charm, $offsetY="20", $offsetX="-80")
        UpdateRelStyle(gateway-api-integrator-charm, gateway, $offsetY="10", $offsetX="-10")
        UpdateRelStyle(gateway-api-integrator-charm, http-route, $offsetY="20", $offsetX="-10")
        UpdateRelStyle(gateway-api-integrator-charm, secret, $offsetY="30", $offsetX="-10")
        UpdateRelStyle(gateway-api-integrator-charm, service, $offsetY="40", $offsetX="-10")
    }

Help improve this document in the forum (guidelines). Last updated 4 months ago.