Skip to content

NGINX Gateway API

The NGINX Gateway Fabric is an open-source project that provides an implementation of the Gateway API using NGINX as the data plane.

Installation

Run the helm command to install NGINX Gateway.

Run the NGINX Gateway deployment Script /opt/genestack/bin/install-nginx-gateway.sh
#!/bin/bash
# shellcheck disable=SC2124,SC2145,SC2294

GLOBAL_OVERRIDES_DIR="/etc/genestack/helm-configs/global_overrides"
SERVICE_CONFIG_DIR="/etc/genestack/helm-configs/nginx-gateway-fabric"
BASE_OVERRIDES="/opt/genestack/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml"
NGINX_VERSION="1.4.0"
HELM_CMD="helm upgrade --install nginx-gateway-fabric oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
                       --create-namespace \
                       --namespace=nginx-gateway \
                       --post-renderer /etc/genestack/kustomize/kustomize.sh \
                       --post-renderer-args gateway/overlay \
                       --version ${NGINX_VERSION}"

HELM_CMD+=" -f ${BASE_OVERRIDES}"

for dir in "$GLOBAL_OVERRIDES_DIR" "$SERVICE_CONFIG_DIR"; do
    if compgen -G "${dir}/*.yaml" > /dev/null; then
        for yaml_file in "${dir}"/*.yaml; do
            # Avoid re-adding the base override file if present in the service directory
            if [ "${yaml_file}" != "${BASE_OVERRIDES}" ]; then
                HELM_CMD+=" -f ${yaml_file}"
            fi
        done
    fi
done

HELM_CMD+=" $@"

kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v${NGINX_VERSION}" | kubectl apply -f -

kubectl apply -f /opt/genestack/manifests/nginx-gateway/nginx-gateway-namespace.yaml

echo "Executing Helm command:"
echo "${HELM_CMD}"
eval "${HELM_CMD}"

The install script will deploy NGINX Gateway to the nginx-gateway namespace via Helm.

Setup

Run the NGINX Gateway setup Script /opt/genestack/bin/setup-nginx-gateway.sh
#!/bin/bash
# shellcheck disable=SC2045,SC2124,SC2145,SC2164,SC2236,SC2294

if [ -z "${ACME_EMAIL}" ]; then
  read -rp "Enter a valid email address for use with ACME, press enter to skip: " ACME_EMAIL
fi

if [ -z "${GATEWAY_DOMAIN}" ]; then
  echo "The domain name for the gateway is required, if you do not have a domain name press enter to use the default"
  read -rp "Enter the domain name for the gateway [cluster.local]: " GATEWAY_DOMAIN
  export GATEWAY_DOMAIN=${GATEWAY_DOMAIN:-cluster.local}
fi

if [ -z "${GATEWAY_DOMAIN}" ]; then
  echo "Gateway domain is required"
  exit 1
fi

kubectl kustomize /etc/genestack/kustomize/gateway/nginx-gateway-fabric | kubectl apply -f -

echo "Waiting for the gateway to be programmed"
kubectl -n nginx-gateway wait --timeout=5m gateways.gateway.networking.k8s.io flex-gateway --for=condition=Programmed

if [ ! -z "${ACME_EMAIL}" ]; then
  cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ${ACME_EMAIL}
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          gatewayHTTPRoute:
            parentRefs:
            - group: gateway.networking.k8s.io
              kind: Gateway
              name: flex-gateway
              namespace: nginx-gateway
EOF

  kubectl patch --namespace nginx-gateway \
                --type merge \
                --patch-file /etc/genestack/gateway-api/gateway-letsencrypt.yaml \
                gateway flex-gateway

  kubectl rollout restart deployment cert-manager --namespace cert-manager
fi

sudo mkdir -p /etc/genestack/gateway-api/routes
for route in $(ls -1 /opt/genestack/etc/gateway-api/routes); do
    sed "s/your.domain.tld/${GATEWAY_DOMAIN}/g" "/opt/genestack/etc/gateway-api/routes/${route}" > "/tmp/${route}"
    sudo mv -v "/tmp/${route}" "/etc/genestack/gateway-api/routes/${route}"
done

kubectl apply -f /etc/genestack/gateway-api/routes

sudo mkdir -p /etc/genestack/gateway-api/listeners
for listener in $(ls -1 /opt/genestack/etc/gateway-api/listeners); do
    sed "s/your.domain.tld/${GATEWAY_DOMAIN}/g" "/opt/genestack/etc/gateway-api/listeners/${listener}" > "/tmp/${listener}"
    sudo mv -v "/tmp/${listener}" "/etc/genestack/gateway-api/listeners/${listener}"
done

kubectl patch -n nginx-gateway gateway flex-gateway \
              --type='json' \
              --patch="$(jq -s 'flatten | .' /etc/genestack/gateway-api/listeners/*)"

echo "Setup Complete"

The setup script will ask the following questions:

  • Enter a valid email address for use with ACME, press enter to skip"
  • Enter the domain name for the gateway"

These values will be used to generate a certificate for the gateway and set the routes used within the flex-gateway, typically for OpenStack. This script can also be fully automated by providing the required values as arguments.

Run the NGINX Gateway setup Script with arguments

ACME_EMAIL="username@your.domain.tld" GATEWAY_DOMAIN="your.domain.tld" /opt/genestack/bin/setup-nginx-gateway.sh

Validation

At this point, flex-gateway has a listener pointed to the port 80 matching *.your.domain.tld hostname. The HTTPRoute resource configures routes for this gateway. Here, we match all path and simply pass any request from the matching hostname to kube-prometheus-stack-prometheus backend service.

kubectl -n openstack get httproute
kubectl -n nginx-gateway get gateways.gateway.networking.k8s.io flex-gateway