# Migrating from Ingress NGINX to Gateway API in GKE

If you have been working with Kubernetes for a while, there's a good chance you've used **NGINX Ingress** to expose services outside your cluster. For years, it has been the default choice for many teams because it was simple to set up and widely supported.

But Kubernetes networking has been evolving rapidly.

Recently, the Kubernetes community has been shifting focus toward the **Gateway API**, which is designed to be the **next-generation replacement for the traditional Ingress model**. Because of this shift, the community is gradually **deprecating the ingress-nginx controller in favor of more modern networking approaches built around Gateway API**.

For teams running workloads on **Google Kubernetes Engine (GKE)**, this transition becomes even more relevant since GKE provides **native support for Gateway API with managed load balancing**.

If you're currently running applications using **NGINX Ingress**, this guide will help you understand **why the shift is happening and how to transition to Gateway API in GKE**.

By the end of this tutorial, you’ll have a **working Gateway + HTTPRoute setup** that replaces your traditional ingress-based routing.

# Why Move Away from Ingress NGINX?

![](https://cdn.hashnode.com/uploads/covers/66f43cce4175136d80945d5a/1733cdef-4835-4a62-a2c3-6c6014fe7e7e.png align="center")

While **Ingress NGINX** has been a widely used solution for exposing Kubernetes services, the ecosystem is gradually shifting toward the **Gateway API** as the long-term standard for traffic management.

Some of the major limitations of traditional Ingress include:

*   Limited routing capabilities
    
*   Complex annotations
    
*   Lack of role separation between platform teams and app teams
    
*   Poor extensibility
    

Gateway API solves these problems by introducing a **more structured and modular networking model**.

# Understanding Gateway API Architecture

Gateway API introduces several new Kubernetes resources that separate responsibilities clearly.

![](https://cdn.hashnode.com/uploads/covers/66f43cce4175136d80945d5a/577cca5a-3e18-4f3d-9499-d86eb252e77a.png align="center")

| Resource | Responsibility |
| --- | --- |
| GatewayClass | Defines the gateway implementation |
| Gateway | Defines the entry point to the cluster |
| HTTPRoute | Defines routing rules to services |

This model allows **platform teams to manage infrastructure** while **application teams manage routing rules**.

# Prerequisites

Before starting the migration, ensure you have:

*   A **running GKE cluster**
    
*   **kubectl installed**
    
*   **gcloud CLI configured**
    
*   Permissions to manage cluster networking
    

Verify cluster connectivity:

```bash
kubectl get nodes
```

# Enable Gateway API in GKE

Gateway API support must be enabled in your GKE cluster.

You can do this either through the **GKE Console** or **Terraform**, depending on how you manage infrastructure.

## Option 1: Enable via GKE Console

1.  Open **Google Cloud Console**
    
2.  Navigate to **Kubernetes Engine → Clusters**
    
3.  Select your cluster
    
4.  Go to **Details**
    
5.  Enable **Gateway API**
    

![GKE console](https://cdn.hashnode.com/uploads/covers/66f43cce4175136d80945d5a/b4fe955a-4b55-466a-bf2a-c0b19da539cf.png align="center")

## Option 2: Enable Gateway API Using Terraform

If you're managing infrastructure using Terraform, you can enable the Gateway API during cluster creation.

```hcl
resource "google_container_cluster" "gke_cluster" {
  name     = "gateway-demo-cluster"
  location = "us-central1"

  gateway_api_config {
    channel = "CHANNEL_STANDARD"
  }
}
```

Apply the configuration:

```bash
terraform apply
```

# List Available GatewayClasses

Once Gateway API is enabled, GKE automatically installs supported **GatewayClasses**.

List them using:

```bash
kubectl get gatewayclass
```

Example output:

```plaintext
NAME                                       CONTROLLER                            
gke-l7-global-external-managed             networking.gke.io/gateway                   
gke-l7-gxlb                                networking.gke.io/gateway            
gke-l7-regional-external-managed           networking.gke.io/gateway                    
gke-l7-rilb                                networking.gke.io/gateway                                         
```

Each GatewayClass corresponds to a specific load balancing capability.

For most public applications, we will typically use:

```plaintext
gke-l7-global-external-managed
```

# Create the Gateway (Application Gateway)

Now we create the **Gateway resource** that acts as the entry point to your cluster.

Create a file called **gateway.yaml**

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: application-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: All
```

Apply it:

```bash
kubectl apply -f gateway.yaml
```

Verify:

```bash
kubectl get gateway
```

CLI output:

```plaintext
kubectl get gateway
```

# Deploy Application

Let’s deploy a sample **nginx application** to simulate a typical service behind an ingress.

Deployment:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
```

Service:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
```

Apply:

```bash
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
```

# Create an HTTPRoute

Now we connect the **application-gateway** to the backend service using **HTTPRoute**.

Create **httproute.yaml**

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: application-gateway
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80
```

Apply it:

```bash
kubectl apply -f httproute.yaml
```

Verify:

```bash
kubectl get httproute
```

### **Architecture flow:**

**Gateway API architecture in GKE**

![Gateway API architecture in GKE](https://cdn.hashnode.com/uploads/covers/66f43cce4175136d80945d5a/6ec0dbec-4b31-4845-ad43-987322e8cd92.png align="center")

# Access the Application

Retrieve the Gateway external IP:

```bash
kubectl get gateway application-gateway
```

Open the IP in your browser.

You should see:

![](https://cdn.hashnode.com/uploads/covers/66f43cce4175136d80945d5a/050d6989-262b-48a5-b543-5cafba0d7ccb.png align="center")

This confirms your **Gateway API configuration is working successfully**.

# Troubleshooting Tips

If your application isn't accessible, Perform these checks:

To check Gateway status:

```bash
kubectl describe gateway application-gateway
```

To check HTTPRoute status:

```bash
kubectl describe httproute nginx-route
```

To get Pod health:

```bash
kubectl get pods
```

Most issues occur due to **incorrect service references or missing GatewayClass**.

# Key Takeaways

Migrating from **Ingress NGINX to Gateway API** in GKE provides several advantages:

*   Modern Kubernetes networking standard
    
*   More powerful routing capabilities
    
*   Clear separation between infrastructure and application routing
    
*   Native integration with GKE load balancers
    

Gateway API is expected to become the **primary way to manage traffic in Kubernetes clusters going forward**.

> 💡Do not treat migration as a simple YAML conversion ... treat it as a **networking architecture upgrade**.

# Conclusion

Gateway API represents the **next generation of Kubernetes traffic management**. It provides:

*   Clear separation of responsibilities
    
*   Rich routing capabilities
    
*   Extensible policy framework
    
*   Better security model
    

Migrating from **Ingress NGINX** to **Gateway API** requires planning, but by following **progressive migration, policy standardization, and observability best practices**, teams can modernize their Kubernetes networking stack safely.
