# Practical Guide to Kubernetes Gateway API: Setup, Use Cases, and Best Practices

Let’s see today’s agenda first.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727622447779/63fb2375-3d45-4a39-a8b7-bfb3eb93815a.png align="center")

### **Let’s start with a What?**

The Gateway API is a Kubernetes CRD that provides a consistent way to configure and manage API gateways. It defines a set of resources that can be used to create and configure gateways, routes, and listeners.

**It was boring textbook definition** 😛

**<mark>For me : Ingerss + Service mesh = Gateway Api (Sometimes, It is more than it)</mark>**

### Now Let’s see “Why” Part?

1. It is Role based
    
2. It is portable.
    
3. It is Expressive
    
4. It is Extensible
    

You will get to know about above feature further. Before moving further , Let’s see It’s architecture so you get to know it’s first feature(Role based)

![Gateway API Resource Model](https://gateway-api.sigs.k8s.io/images/resource-model.png align="left")

I hope it is clear from above image that How gateway api components will be developed/setuped by different people in team.

### Now Let’s compare it with Ingress and service mesh

While the Gateway API shares similarities with Ingress and Service Mesh in managing API traffic, there are key differences to note:

Ingress: Ingress serves as a Kubernetes resource that exposes services running within a Kubernetes cluster to the external world. It offers load balancing, SSL termination, and authentication capabilities.

Service Mesh: A service mesh is a network of proxies that facilitate API traffic management. It provides features like load balancing, fault tolerance, and observability.

The Gateway API goes beyond Ingress and Service Mesh by providing a comprehensive solution for API traffic management. <mark>It encompasses not only load balancing and SSL termination but also authentication, authorization, and rate limiting.</mark> Moreover, its extensibility allows users to tailor the Gateway API to their specific requirements.

### Let’s move very fast from these boring theories to it’s usecase with examples.

I will be using GKE for all demo, but you will can setup your choice of your gateway api using just few lines of command from documentation.

For GKE, run following command to enable gateway api.

```yaml
 gcloud container clusters update CLUSTER_NAME \
    --location=CLUSTER_LOCATION\
    --gateway-api=standard
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727623566747/31cf5871-1387-40ae-8b65-cadcdc76d4d6.png align="center")

By default , It creates 4 gateway classes.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727623632182/fb2ff20d-337e-4d21-9283-cfa2b36b4493.png align="center")

You can know more about more gateway classes from [here](https://cloud.google.com/kubernetes-engine/docs/how-to/gatewayclass-capabilities).

**First Use case: Multiple applications behind a single Gateway**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727646500247/bd4e077e-ff37-4161-9fff-2a6057aef236.png align="center")

Let’s create our first Gateway.

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: gke-l7-gxlb
  listeners:
  - name: http
    protocol: HTTP
    port: 80
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727646905919/fb762fb3-8672-4ce9-8b9d-5f975be7c86a.png align="center")

It will take time to create load balancer, once it will create it populate in address field of gateway.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727647214765/ddf79182-971c-4387-b86b-77c62080528d.png align="center")

For demo , we will deploy one application with this command.

```yaml
k run app1 --image patelajay745/go-sample-app:v1 

k run app2 --image patelajay745/go-sample-app2:v1

k expose pod app1 --port=8080 --target-port=8080 --name=app1-svc 

k expose pod app2 --port=8081 --target-port=8081 --name=app2-svc
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727697108132/dd020217-906c-45ae-a6f1-61c0e2f86180.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727697159923/8aea215b-8ac8-487f-a0a9-3fe09461b2a9.png align="center")

Now let’s create HttpRoute for both application.

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
spec:
  parentRefs:
  - name: my-gateway
  hostnames:
  - 34.54.169.176
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /app1
    backendRefs:
    - name: app1-svc
      port: 8080
  - matches:
    - path:
        type: PathPrefix
        value: /app2
    backendRefs:
    - name: app2-svc
      port: 8081
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727647765008/3bcd6a0f-d5cc-4e3f-86a1-198edbbb38ce.png align="center")

If you visit your <mark>http:IP-Address/app1</mark> ,

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727697303386/31621ec1-6855-45c9-8d90-7e72dd93a5cd.png align="center")

<mark>http:IP-Address/app2</mark>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727697333735/f9e7dbd4-c5a0-42a6-a7c8-96f920a05c86.png align="center")

Now Let’s see how gateway api can be useful in different deployment strategy

1. ### Canary traffic rollout
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727724919181/b284c7b9-7400-4abe-a1f1-63f6a7eeedd1.png align="center")

For Demo, I have two application.

```yaml
k run app1 --image patelajay745/go-system-stats:v1                                                      ─╯

k run app2 --image patelajay745/go-system-stats:v2

# we will be using same service for this demo
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727725328976/d7ebed94-a1ef-4005-867a-137670ceda9a.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727725403985/44dc37de-b866-4091-8edf-7e07993010e2.png align="center")

HttpRoute File:

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-canary-route
spec:
  parentRefs:
  - name: my-gateway
  hostnames:
  - 34.54.169.176
  rules:
  - backendRefs:
    - name: app1-svc
      port: 8080
  - matches:
    - headers:
      - name: env
        value: test
    backendRefs:
    - name: app2-svc
      port: 8080
```

Now if you check your Load balancer IP: You will see version 1 of your application

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727729455864/f0d77ab2-c230-4a14-9f46-c0e86055ab2b.png align="center")

To check v2 you need to send header “env=test”

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727729551668/60ac29e9-f17c-4461-b06b-7954d356dbce.png align="center")

After testing internally with specific header, It is time to rollout. It's desirable to shift a small percentage of the traffic to the new Service for gradual and more realistic testing.

2. ### Blue-green traffic
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1727730758842/26c94f56-f793-4d51-88a6-ecec94ae677d.png align="center")

Before writing out httpRoute, we need to change out gateway also as we used “gke-l7-gxlb” above which does not support multiple backend for default “/”. For that we need to use “gke-l7-global-external-managed” gateway class.

Gateway file:

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

HttpRoute File:

```yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: app-blue-green-route
spec:
  parentRefs:
  - name: my-second-gateway
  hostnames:
  - 34.54.169.176
  rules:
  - backendRefs:
    - name: app1
      port: 8080
      weight: 90
    - name: app2
      port: 8080
      weight: 10
```

Now if you hit your Ip address then it will 90% redirect traffic to app1(v1) and 10% to app2(v2).

Now it is time to complete rollout and It is simple.

HttpRoute:

```yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: app-blue-green-route
spec:
  parentRefs:
  - name: my-second-gateway
  hostnames:
  - 34.54.169.176
  rules:
  - backendRefs:
    - name: app1
      port: 8080
      weight: 0
    - name: app2
      port: 8080
      weight: 1
```

That was all for rolling strategy in kubernetes.

Wait traffic splitting is just one of the features of gateway api. This is not over. We will see more demos of other features of gateway api.

Stay tuned for second blog of this amazing gateway api. Till then keep reading official document 😛
