How to Install Gateway API in Kubernetes


In this guide, we will learn how to install Gateway API in Kubernetes with Istio as controller.

Traditional Kubernetes Ingress has limitations: it is vendor-specific, lacks standardization, and offers limited routing capabilities. Gateway API is a next-generation Kubernetes networking API designed to manage external traffic into a cluster. It is intended to replace and improve the traditional Kubernetes Ingress resource. It is role-based, extensible, and portable across any Kubernetes cluster.

Why to use Gateway API?

  • Clear separation between infra and app teams
  • Removes the dependency on vendor-specific annotations
  • Advanced traffic splitting
  • mTLS support
  • Header-based routing
  • Canary deployments
  • Traffic redirection and URL rewriting
  • Future-ready Kubernetes networking

Prerequisites

  • Kubernetes v1.26+ (we are using k3s for simplicity)
  • Basic kubectl knowledge
  • Linux with sudo access

Quick k3s Setup

Installing k3s is simple. Just run this one-liner command on your Linux server or test environment:

curl -sfL https://get.k3s.io | sh -

k3s comes default with kubectl pre-packaged. All you have to do is set a bash shell alias for easier access to all kubectl commands.

alias kubectl="sudo k3s kubectl"

Now that everything is ready, let’s begin installing the Gateway API in Kubernetes. Please follow the steps below sequentially.

1) Install Gateway API CRDs

Custom Resource Definitions extend Kubernetes with new resource types like Gateway and HTTPRoute.

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml

Verify installation:

kubectl get crds | grep gateway

Install Gateway API in Kubernetes

Expected output:

  • gatewayclasses.gateway.networking.k8s.io
  • gateways.gateway.networking.k8s.io
  • httproutes.gateway.networking.k8s.io

2) Install Istio

istioctl is the official tool for Istio installation and management. Download this tool using following curl command,

curl -L https://istio.io/downloadIstio | sh -

Install Istio for Kuberenetes

Adjust the PATH variable as shown in the screenshot for istioctl. Copy the export command and run it.

Generate Istio Manifest

Instead of direct installation (which can have permission issues with k3s), we generate the manifest using following command

istioctl manifest generate --set profile=minimal > istio-minimal.yaml

We can either go with istio minimal or the default profile. Deploy Istio, run

kubectl create ns istio-system 
kubectl apply -f istio-minimal.yaml

You might get an error when trying to apply istio-minimal.yaml. In order to resolve the error, you first need to create istio-system namespace.

Error showing istio-system namespace not found during Istio installation

Verify Istio is running:

kubectl get pods -n istio-system

All pods should show Running status.

Cloud providers give you LoadBalancers automatically. For bare metal/k3s, MetalLB provides external IPs. Run beneath kubectl command

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

Once metallb pods are in running status, configure IP pool.

kubectl get all -n metallb-system

MetalLB controller and speaker pods status in metallb-system namespace

Configure IP Pool

Replace 192.168.1.240-192.168.1.250 with IPs from your local network:

kubectl apply -f - <<EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.240-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default-l2
  namespace: metallb-system
spec: {}
EOF

4) Create GatewayClass

GatewayClass tells Kubernetes which controller manages the Gateway. Think of it like a “driver” for traffic.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
EOF

Verify:

kubectl get gatewayclass

Gateway Class Status in Kuberntes

5) Create Gateway (Traffic Entry Point)

Gateway is your cluster’s front door that defines what traffic enters and on which ports. Create the gateway with the name “ecommerce-gateway” using following command.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ecommerce-gateway
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    protocol: HTTP
    port: 80
EOF

Check Gateway status:

kubectl get gateway ecommerce-gateway
kubectl describe gateway ecommerce-gateway

Look for Programmed: True in the status. This confirms Istio is managing it.

Gateway Status in Kubernetes

192.168.1.240 is an EXTERNAL-IP provided by MetalLB.

6) Deploy Backend Application

Let’s deploy one sample backend application, we use use a simple HTTP echo server to test routing. Execute the following command.

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: hashicorp/http-echo
        args:
          - "-text=Hello from Backend API"
          - "-listen=:80"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
EOF

7) Create HTTPRoute (Traffic Rules)

HTTPRoute connects your Gateway to backend services with routing rules (path-based, header-based, etc.).

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
spec:
  parentRefs:
  - name: ecommerce-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: backend-service
      port: 80
EOF

It routes all traffic http://<gateway-ip>/api/* to our backend service.

Verify:

kubectl get httproute api-route
kubectl describe httproute api-route

Look for Accepted: True in parent refs.

HTTPRoute in Gateway API Kubernetes

8) Test End-to-End

Now, we can test the route with a simple curl request.

External IP Associated with Gateway

curl http://<GATEWAY-IP>/api
# This should return "Hello from Backend API"

Common Issues & Fixes

Issue Cause Solution
Gateway stuck in Pending MetalLB not configured Check IP pool range matches your network
404 on /api HTTPRoute not attached Run kubectl describe httproute and check parent refs
Connection refused Backend pod not running Check kubectl get pods and logs
No EXTERNAL-IP MetalLB not running Verify kubectl get pods -n metallb-system

Quick Command Reference

# View all Gateway API resources
kubectl get gateway,httproute,gatewayclass

# Check Istio health
kubectl get pods -n istio-system

# Test routing
curl http:

# Debug HTTPRoute
kubectl describe httproute api-route

# View Istio routing config
istioctl proxy-config routes deploy/ecommerce-gateway-istio

That concludes this guide. I hope you found it helpful and informative. If you have any questions or queries, please share them in the comments section below.



Source link

Leave a Comment