Introducing support for the Kubernetes Gateway API in the ngrok Kubernetes Operator

01-21-2025: We updated this blog post with new information about using the Kubernetes Operator with our Traffic Policy engine.

We are excited to announce support for the Kubernetes Gateway API, now available in developer preview.

To use the Gateway API, cluster operators will set up a Gateway on their cluster with one or more listeners. These listeners will be linked to endpoints at ngrok. Application developers will then be able to create routes that modify traffic and direct it to backends like Kubernetes Services. 

Regardless of whether you use the existing Kubernetes ingress controller or this new Gateway API implementation, you’ll still get all the benefits of ngrok:

  • Effortless configuration: Set the authentication keys to your ngrok account and you're done. Operators do not need to configure networking details like ELBs, IPs, network interfaces or VPC routing.
  • Environment independence: Runs identically in EKS, GKE, k3s on your laptop, OpenShift in your own datacenter or Minikube on your Raspberry Pi.
  • Security and resiliency: Because the Operator pushes authentication and policy to ngrok's global network, attacks and other unwanted traffic never reach your origin network.
  • Acceleration: ngrok’s GSLB boosts application performance by routing end-user traffic to the closest point of presence, minimizing latency. 
Routing traffic with Kubernetes Gateway API

Let's get started!

Want to jump into the references? Find them here:

Otherwise, let’s take a test ride on the ngrok Gateway API. We’ll create a gateway for the echo service container mendhak/http-https-echo which echos back http requests. In the examples below, we use <HOSTNAME> placeholder to represent an ngrok hostname like yourName.ngrok.app Go to the dashboard to reserve a domain. First let’s create our Gateway and GatewayClass objects

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: simple-gatewayclass
  namespace: ngrok-ingress-controller
spec:
  controllerName: ngrok.com/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: simple-gateway
  namespace: ngrok-ingress-controller
spec:
  gatewayClassName: simple-gatewayclass
  listeners:
    - protocol: HTTPS
      hostname: 
      port: 443
      tls: 
        mode: Terminate
        certificateRefs:
        - name: ngrokcert # ngrok generats a cert for you, so this field is just a placeholder to satisfy the gateway crd
      name: simple-listener


The above code tells the operator that the Gateway uses ngrok’s infrastructure, and then provisions a domain. Next let’s deploy that echo service, so the HTTPRoute can direct traffic to this service.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo-deploy
  namespace: ngrok-ingress-controller
spec:
  selector:
    matchLabels:
      app: http-echo-app
  replicas: 2
  template:
    metadata:
      labels:
        app: http-echo-app
    spec:
      containers:
      - name: http-echo-path2
        image: mendhak/http-https-echo:31
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo-svc
  namespace: ngrok-ingress-controller
  labels:
    app: http-echo-app
spec:
  ports:
  - name: http-echo-app
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: http-echo-app


Now, make your HTTPRoute.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: simple-route
spec:
  parentRefs:
  - name: simple-gateway
  hostnames: [<HOSTNAME>]
  rules:
  - backendRefs:
    - name: http-echo-svc
      port: 80
      kind: Service


And just like that, your service is now available to the entire world. Add some gas to it by using Filters, and adding more hosts. Add the following listeners to your Gateway:

   - protocol: HTTPS
      hostname: <HOSTNAME_2>
      port: 443
      tls: 
        mode: Terminate
        certificateRefs:
        - name: ngrokcert
      name: domain-two
    - protocol: HTTPS
      hostname: <HOSTNAME_3>
      port: 443
      tls: 
        mode: Terminate
        certificateRefs:
        - name: ngrokcert
      name: domain-three


Replace the Route’s Hostnames with the following:

hostnames:
  - <HOSTNAME_1>
  - <HOSTNAME_2>
  - <HOSTNAME_3>


Next, add some functionality to the HTTPRoute. The most composable way to do this is with ngrok's Traffic Policy engine, which has full support in the Kubernetes Operator via a NgrokTrafficPolicy CRD and the extensionRef filter in the Gateway API.

For example, if you want to add a certain request header whenever someone hits your service from a certain path, you can use the add headers action.

---
kind: NgrokTrafficPolicy
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
metadata:
  name: paprika-header
spec:
  policy:
    on_http_request:
      - name: "Add header to /paprika path"
        expressions:
          - "req.url.path.startsWith('/paprika')"
        actions:
          - type: add-headers
            config:
              headers:
                paprika-header: spicy-value


Then modify your existing HTTPRoute to add an ExtensionRef filter that references your new CRD.

  - backendRefs:
    - name: http-echo-svc
      port: 80
    matches:
    - path:
        type: PathPrefix
        value: /paprika
    filters:
    - type: ExtensionRef
      extensionRef:
        group: ngrok.k8s.ngrok.com
        kind: NgrokTrafficPolicy
        name: paprika-header


With the on_http_response phase of ngrok's Traffic Policy engine, you could also add a response variable.

---
kind: NgrokTrafficPolicy
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
metadata:
  name: paprika-header
spec:
  policy:
    on_http_response:
      - name: "Add header on response"
        actions:
          - type: add-headers
            config:
              headers:
                my-response-header-name: my-header-value


You can follow a similar pattern for redirecting from one path to another using the redirect action.

---
kind: NgrokTrafficPolicy
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
metadata:
  name: pumpkin-paprika
spec:
  policy:
    on_http_request:
      - name: "Redirect from /pumpkin to /paprika"
        actions:
          - type: redirect
            config:
              from: /pumpkin
              to: /paprika

The Kubernetes Gateway API

Kubernetes Gateway API caters to the needs of modern organization roles that use and configure networking into Kubernetes. Built with a role-oriented architecture, it balances distributed flexibility with centralized governance and control by. It allows shared network infrastructure (hardware load balancers, cloud networking, cluster-hosted proxies etc) to be used by many different and non-coordinating teams, all bound by the policies and constraints set by cluster operators, responsible for managing Kubernetes clusters.

This eliminates friction in application and API delivery by providing the flexibility needed by the users of the infrastructure (application developer) while also maintaining control by the owners of the infrastructure (Infrastructure provider and cluster operator). It also enhances security by ensuring granular control over who can manage networking resources.

Gateway API is also expressive - it natively supports enhanced routing for multiple types of routes (L4 and L7), header-based matching, traffic weighting, and other capabilities that equip developers to direct and shape traffic easily. This enhanced support for routing gives developers the flexibility to configure path routing that maps requests to Kubernetes services. 

Motivation: Addressing ingress limitations

The Kubernetes Gateway API is being developed to address the limitations of the existing Ingress API. Ingress API doesn’t offer enough features out of the box requiring infrastructure operations teams to fill the remaining 70-80% of the interface with annotations to cover what cluster operators and application developers require. This forces users to maintain bespoke configurations for each infrastructure provider they use. Moreover, it also lacks functionality for allocating portions of the cluster to different teams or applications, leading to either the cumbersome setup of multiple controller instances or forcing cluster providers to limit app developers' control over their deployment strategies. 

The Gateway API addresses these challenges, enabling a more flexible and secure environment for managing networking into Kubernetes. It overcomes the issue of limited functionality through routes, which establish a set of rules that contain Matches and Filters to support any desired matching logic or transformation needed by app developers.

This means users don’t need to maintain bespoke configurations for each environment and eliminates friction when migrating from one platform to another as the Gateway API abstracts connectivity by providing a common interface into Kubernetes. Furthermore, the Gateway API’s role-based framework allows individual app developers to integrate with the same gateway independently, without impacting each other’s services. 

What’s next?

The ngrok Kubernetes Operator currently supports the creation of Gateways, HTTPRoutes, and the core filters on those routes. We've also added support for the Traffic Policy engine, which lets you compose API gateway functionality into how your K8s-based APIs and apps respond adding complexity to your clusters.

We're also working to support Gateway API v1.2, released in October 2024, which includes timeouts, propagation of labels/annotations, and other protocols.

Get started with the ngrok Operator today

If you don’t have an account, you can sign up today to get started with ngrok.

Reach us on Twitter, the ngrok community on Slack, or contact us at support@ngrok.com and share your feedback on this developer preview of the Gateway API.

Share this post
Product updates
Kubernetes Gateway API
Kubernetes Operator
Kubernetes
Production