Skip to main content
logoTetrate Enterprise Gateway for Envoy (TEG)Version: v0.1.0

Expose Your Application on a Shared Gateway

In this guide, we'll expose an app using a shared gateway. This means that all apps and teams will share one physical set of Envoy gateways (probably deployed by the platform team), rather than each having their own which they manage themselves.

To use this article, first

For the purposes of this article it's assumed that your cluster follows the standard multi-tenancy pattern: each team of people has their own namespace(s). At first glance, a shared gateway should be no different to dedicated gateways -- each team deploys an HTTPRoute for their app(s) and attaches them to the single, shared Gateway resource. Indeed to a first approximation this is true, but the Gateway API (the spec that defines types like Gateway and HTTPRoute) was designed with multi-tenancy security in mind, and enforces a permissions system. This article will use the following representative cluster layout:

  • namespace ingress: contains the single, shared Gateway resource, which results in a single, shared Deployment of Envoys. In a production cluster this would be managed by the platform team, but in this guide we'll deploy everything ourselves.
  • namespace team1: the namespace for engineering team 1, who wish to offer a service. In a production cluster this is likely all the people on team 1 will have k8s RBAC permissions to, but again in this guide we will omnipotently deploy everything.
  • namespace team2: engineering team 2 are also deploying some apps.

Let's get set up by making those namespaces for this how-to:

kubectl create namespace ingress
kubectl create namespace team1
kubectl label namespace team1 purpose=workloads
kubectl create namespace team2
kubectl label namespace team2 purpose=workloads

Since everything will be in different namespaces, we will have to add fields and resources to our normal objects, in order to explicitly allow such cross-namespace configuration, as you'll see in this guide.

  1. Deploy Shared Gateway Instance

    First, we deploy a Gateway resource, which will result in a set of running Envoy proxies to handle incoming requests.

    kind: Gateway
    name: shared-gateway
    namespace: ingress
    gatewayClassName: teg
    - name: http
    protocol: HTTP
    port: 80
    from: Selector
    purpose: workloads

    Notice this is the same as the Gateway from the previous article, but with the addition of the allowedRoutes section. This allows HTTPRoutes in different namespaces, specifically any with the label purpose=workloads to attach themselves to this Gateway; without this they would be denied.

  2. Route Traffic to Team 2

    By way of a slightly contrived example, imagine that team 1 wants to offer a service, but that by luck they don't need to write any code, because team 2 has already deployed some Pods doing exactly what they want. So, we deploy the HTTPRoute below. This lives in team 1's namespace (as it's them offering the service at this location), but attaches to the previously-deployed Gateway ingress in a different namespace: ingress. Any traffic matched by this route gets sent out-of-namespace, to Service httpbin in namespace team2.

    kind: HTTPRoute
    namespace: team1
    name: httpbin
    - group:
    kind: Gateway
    namespace: ingress
    name: ingress
    - matches:
    - path:
    type: PathPrefix
    value: /httpbin
    - type: URLRewrite
    type: ReplacePrefixMatch
    replacePrefixMatch: /
    - group: ""
    kind: Service
    namespace: team2
    name: httpbin
    port: 8000
  3. Accept Traffic from Team 1

    To complete our test setup, let's quickly deploy a copy of httpbin to team 2's namespace.

    kubectl apply -n team2 -f

    This includes a Service also called httpbin, and we already have the HTTPRoute pointing at it. So the only thing that remains is to give that HTTPRoute permission to send traffic over here. This is done with a ReferenceGrant resource, which lives in the target namespace, with the Service which is allowing access to itself. The ReferenceGrant below allows access to any Service in its namespace, from any HTTPRoute in team 1's namespace.

    kind: ReferenceGrant
    namespace: team2
    name: httpbin-route-service
    - group:
    kind: HTTPRoute
    namespace: team1
    - group: ""
    kind: Service
  4. Test Connectivity

    See the instructions in the dedicated gateway article for how to call httpbin.


    In this case, the shared gateway's Service has the following labels: kubectl get service -n envoy-gateway-system -l,