Skip to main content

Deploy a Gateway API controller

The Gateway API is the next-generation Kubernetes API for managing service networking. A Gateway API controller processes traffic from outside a cluster to internal services according to rules defined in resources such as Gateway and HTTPRoute. For more information, see the official Kubernetes Gateway API documentation. This guide explains how to configure and deploy a Gateway API controller in a cluster.

Note

This guide uses NGINX Gateway Fabric, validated with version 2.3.0, as an example implementation of a Gateway API controller.

Kubernetes Engine does not provide or manage a Gateway API controller. You are responsible for selecting, deploying, and operating the controller. Deployment manifests and Helm chart options may differ in other versions, so also refer to the official documentation for the version you use.

Compare Ingress and Gateway API

Ingress uses a single resource model that defines the host, path, TLS, and backend in one resource. Gateway API separates these responsibilities into three layers—GatewayClass → Gateway → HTTPRoute—so infrastructure administrators and application developers can independently manage their respective concerns.

CategoryIngressGateway API
Routing definitionOne Ingress resourceSeparate Gateway and HTTPRoute resources
TLS configurationspec.tlsGateway listeners[].tls
Path matchingspec.rules[].http.pathsHTTPRoute spec.rules[].matches
Host matchingspec.rules[].hostHTTPRoute spec.hostnames
Backendbackend.service.name / portbackendRefs[].name / port
Controller selectioningressClassNamegatewayClassName
Cross-namespace routingNot supportedSupported with ReferenceGrant
Header-based routingAnnotations (non-standard)matches[].headers (standard)
Traffic splittingNot supportedbackendRefs[].weight

For instructions on migrating an existing Ingress to Gateway API, see Migrate from Ingress to Gateway API.

Step 1. Prerequisites

Complete the following prerequisites before configuring and deploying a Gateway API controller.

  1. Create a cluster where you will deploy the Gateway API controller.

  2. Configure kubectl control so that you can send deployment commands to the cluster.

  3. Install the Gateway API CRDs (Custom Resource Definitions) in the cluster.

    Install Gateway API CRDs
    kubectl --kubeconfig=$KUBE_CONFIG kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.3.0" | kubectl --kubeconfig=$KUBE_CONFIG apply -f -
    Verify the installation
    kubectl --kubeconfig=$KUBE_CONFIG get crd | grep gateway
    Output
    backendtlspolicies.gateway.networking.k8s.io     2026-03-19T02:59:09Z
    gatewayclasses.gateway.networking.k8s.io 2026-03-19T02:59:09Z
    gateways.gateway.networking.k8s.io 2026-03-19T02:59:10Z
    grpcroutes.gateway.networking.k8s.io 2026-03-19T02:59:10Z
    httproutes.gateway.networking.k8s.io 2026-03-19T02:59:10Z
    referencegrants.gateway.networking.k8s.io 2026-03-19T02:59:10Z

Step 2. Deploy the Gateway API controller

Deploy a Gateway API controller based on the open-source NGINX Gateway Fabric.

Note

Kubernetes Engine currently does not support Admission Webhooks. To deploy a service configured with an Admission Webhook, set hostNetwork: true.

Deploy using YAML files

The deployment can fail if the target namespace does not exist. Create the namespace first.

Create a namespace
kubectl --kubeconfig=$KUBE_CONFIG create namespace nginx-gateway

Run the following commands to deploy the NGINX Gateway Fabric CRDs and controller in the cluster. The required services, GatewayClass, and other resources are deployed together.

Deploy NGINX Gateway Fabric CRDs
kubectl --kubeconfig=$KUBE_CONFIG apply --server-side -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.3.0/deploy/crds.yaml
Deploy the NGINX Gateway Fabric controller
kubectl --kubeconfig=$KUBE_CONFIG apply -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.3.0/deploy/default/deploy.yaml

Deploy using Helm

Deploy the Gateway API controller using Helm, the Kubernetes package manager.

  1. Install the Helm client before installing the Gateway API controller. For operating-system-specific instructions, see Installing Helm.

  2. Run the following command to deploy NGINX Gateway Fabric in the cluster. NGINX Gateway Fabric provides its Helm chart through an OCI registry, so you do not need to run helm repo add.

    Deploy NGINX Gateway Fabric
    helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
    --version 2.3.0 \
    --namespace nginx-gateway --create-namespace
    Output
    Pulled: ghcr.io/nginx/charts/nginx-gateway-fabric:2.3.0
    Digest: sha256:96910ca9172f8e29c7fbfff9915403eff899653c8d2c9b2703f6e2976744591f
    NAME: ngf
    LAST DEPLOYED: Thu Mar 19 13:17:49 2026
    NAMESPACE: nginx-gateway
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None

    If NGINX Gateway Fabric is already deployed with Helm, upgrade the existing release.

    Upgrade an existing NGINX Gateway Fabric release
    helm upgrade ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
    --version 2.3.0 \
    --namespace nginx-gateway

Step 3. Verify the controller deployment

  1. Run the following command and observe the Pod status to verify that the Gateway API controller was deployed successfully. Confirm that the nginx-gateway Pod is running.

    • When the nginx-gateway Pod reaches the Running state, press Ctrl+C to stop watching.

      Verify that the Pod is running
      kubectl --kubeconfig=$KUBE_CONFIG get pods -n nginx-gateway --watch
      Output
      NAME                                 READY   STATUS      RESTARTS   AGE
      nginx-gateway-cd9c6c4f5-jhbbx 1/1 Running 0 41s
      nginx-gateway-cert-generator-rgp26 0/1 Completed 0 41s
  2. Verify that the GatewayClass resource was created successfully.

    Verify GatewayClass
    kubectl --kubeconfig=$KUBE_CONFIG get gatewayclass
    Output
    NAME    CONTROLLER                                  ACCEPTED   AGE
    nginx gateway.nginx.org/nginx-gateway-controller True 60s

Step 4. Create a Gateway resource

After deploying the Gateway API controller, create a Gateway resource to configure listeners. Creating the Gateway resource also provisions a load balancer.

  1. Create a Gateway resource using the following YAML file.

    gateway.yaml
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
    name: nginx-gateway
    namespace: nginx-gateway
    spec:
    gatewayClassName: nginx
    listeners:
    - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
    namespaces:
    from: All
    - name: https
    port: 443
    protocol: HTTPS
    tls:
    mode: Terminate
    certificateRefs:
    - name: nginx-tls-secret
    allowedRoutes:
    namespaces:
    from: All
    Create the Gateway resource
    kubectl --kubeconfig=$KUBE_CONFIG apply -f gateway.yaml
  2. Verify that the Gateway resource was created successfully.

    Verify the Gateway resource
    kubectl --kubeconfig=$KUBE_CONFIG get gateway -n nginx-gateway
    Output
    NAME            CLASS   ADDRESS                                                                 PROGRAMMED   AGE
    nginx-gateway nginx k8s-nginxga-nginxga-xxxxxxxxxx-xxxxxx.ke.kr-central-2.kakaocloud.com True 3m47s
  3. Check the Gateway ADDRESS in the output. ADDRESS is the load balancer domain and becomes the endpoint for services exposed through HTTPRoute.

Step 5. Route traffic using HTTPRoute

Use an HTTPRoute resource to route incoming Gateway traffic to backend services.

Note

The following example assumes that the demo-app-v1 and demo-app-v2 Services are already deployed in the demo-apps namespace. If your Service names or ports differ, update backendRefs for your environment.

  1. Create an HTTPRoute resource using the following YAML file.

    httproute.yaml
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
    name: demo-route
    namespace: demo-apps
    spec:
    parentRefs:
    - name: nginx-gateway
    namespace: nginx-gateway
    rules:
    - matches:
    - path:
    type: PathPrefix
    value: /v1
    backendRefs:
    - name: demo-app-v1
    port: 80
    - matches:
    - path:
    type: PathPrefix
    value: /v2
    backendRefs:
    - name: demo-app-v2
    port: 80
    Create the HTTPRoute resource
    kubectl --kubeconfig=$KUBE_CONFIG apply -f httproute.yaml
  2. Verify that the HTTPRoute resource was created successfully.

    Verify the HTTPRoute resource
    kubectl --kubeconfig=$KUBE_CONFIG get httproute -n demo-apps
    Output
    NAME         HOSTNAMES   AGE
    demo-route 7s

Configure a public IP for the Gateway load balancer

  • If the load balancer created by the Gateway needs external connectivity, you can configure whether it uses a public IP.

    • Run the following command to find the Service of type LoadBalancer created by the Gateway deployment.
    Find the Service of type LoadBalancer
    kubectl --kubeconfig=$KUBE_CONFIG get svc -n nginx-gateway
  • Set the service.beta.kubernetes.io/openstack-internal-load-balancer value under metadata.annotations on the Service of type LoadBalancer.

    • Set it to true to create a load balancer with a private IP. This is the default.
    • Set it to false to create a load balancer with a public IP.
Caution
  • Depending on the value of service.beta.kubernetes.io/openstack-internal-load-balancer, a new public IP is created and associated with the load balancer, or the existing public IP is disassociated. If a public IP was used when the value was false, changing the value to true only disassociates that public IP. The disassociated public IP remains billable until it is deleted.
  • To delete a public IP used by a Kubernetes Engine load balancer, go to KakaoCloud console > VPC > Public IP. For details, see Create and manage public IP.