Kubernetes Gateway API Integration Beta

The NetBird Kubernetes operator supports the Gateway API as an alternative to annotation-based service exposure. Using standard Gateway API resources, you can:

  • Expose services publicly via reverse proxy using HTTPRoute resources with the public gateway class
  • Expose services privately to your NetBird network using TCPRoute resources with the private gateway class

The operator watches for these Gateway API resources and automatically creates the corresponding Networks and Resources in your NetBird account.

Prerequisites

Before you begin, ensure you have the following:

  • Helm version 3+ (recommended)
  • kubectl version v1.11.3+
  • Access to a Kubernetes v1.11.3+ cluster
  • Cert Manager (recommended) — for secure communication between the k8s API and the operator
  • A NetBird API token — you can create a PAT by following the steps here

Installation

Step 1: Add the Helm repository

helm repo add netbirdio https://netbirdio.github.io/helms

Step 2: Install Cert Manager

This is recommended for the k8s API to communicate securely with the NetBird operator.

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.0/cert-manager.yaml

Step 3: Install the Gateway API CRDs

The operator requires the experimental Gateway API CRDs to be installed in your cluster.

kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.0/experimental-install.yaml

Step 4: Create the NetBird API secret

Create a namespace for the operator and store your API token as a Kubernetes secret.

kubectl create namespace netbird
kubectl -n netbird create secret generic netbird-mgmt-api-key --from-literal=NB_API_KEY=$(cat ~/nb-pat.secret)

Step 5: Install the operator

helm upgrade --install kubernetes-operator netbirdio/kubernetes-operator \
  --namespace netbird \
  --create-namespace \
  --version 0.3.0-rc.2 \
  -f - <<EOF

gatewayAPI:
  enabled: true

webhook:
  enableCertManager: false

netbirdAPI:
  keyFromSecret:
    name: "netbird-mgmt-api-key"
    key: "NB_API_KEY"

EOF

Step 6: Verify the installation

kubectl -n netbird get pods
# Expected: netbird-operator-kubernetes-operator-xxxxx  1/1  Running

Configure Routing Peers and Gateways

Once the operator is running, deploy the routing peers and gateway resources. The operator supports two gateway classes:

  • netbird-public — exposes services through a reverse proxy, making them accessible via a public hostname using HTTPRoute resources
  • netbird-private — exposes services as private network resources, accessible only to peers within your NetBird network using TCPRoute resources
cat <<EOF | kubectl apply -f -

apiVersion: netbird.io/v1
kind: NBRoutingPeer
metadata:
  name: netbird
  namespace: netbird
spec: {}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: private
  namespace: netbird
spec:
  gatewayClassName: netbird-private
  listeners:
  - protocol: gateway.netbird.io/NBRoutingPeer
    name: netbird
    port: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public
  namespace: netbird
spec:
  gatewayClassName: netbird-public
  listeners:
  - protocol: gateway.netbird.io/NBRoutingPeer
    name: netbird
    port: 1

EOF

Expose Services via Reverse Proxy (Public Gateway)

Use HTTPRoute resources with the public gateway to expose Kubernetes services through a reverse proxy. You can optionally add the hostnames field to make the service accessible via a specific domain.

The following example deploys a demo application and creates an HTTPRoute with a custom hostname pointing to the public gateway:

export DEPLOYMENT_NAME=demo-nb-k8s; export DEPLOYMENT_IMAGE=ghcr.io/netbirdio/kubernetes-demo; cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: $DEPLOYMENT_NAME
  namespace: default
  labels:
    app: $DEPLOYMENT_NAME
spec:
  hostnames:
    # Optional: omit this field if you don't want to expose this through the reverse proxy
    - demo-nb-k8s.eu1.netbird.services
  parentRefs:
  - name: public
    namespace: netbird
  rules:
  - backendRefs:
    - name: $DEPLOYMENT_NAME
      port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: $DEPLOYMENT_NAME
  namespace: default
  labels:
    app: $DEPLOYMENT_NAME
spec:
  replicas: 1
  selector:
    matchLabels:
      app: $DEPLOYMENT_NAME
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: $DEPLOYMENT_NAME
    spec:
      containers:
      - image: $DEPLOYMENT_IMAGE
        imagePullPolicy: Always
        name: demo

---
apiVersion: v1
kind: Service
metadata:
  name: $DEPLOYMENT_NAME
  namespace: default
  labels:
    app: $DEPLOYMENT_NAME
spec:
  type: ClusterIP
  selector:
    app: $DEPLOYMENT_NAME
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
EOF

Expose Private Resources (Private Gateway)

Use TCPRoute resources with the private gateway to expose services as private network resources, accessible only to peers within your NetBird network.

The following example exposes the Kubernetes API server to your NetBird peers:

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: kubernetes
  namespace: default
spec:
  parentRefs:
  - name: private
    namespace: netbird
  rules:
  - backendRefs:
    - name: kubernetes
      port: 443
EOF

Work in progress features

We know the operator is not yet feature complete, but we thought you would like to hear that we're working on:

  • ACL policy attachment
  • Reverse Proxy authentication configuration
  • Multi-cluster support
  • Kubernetes API RBAC support

Get started