istio using kubernetes gateway api (httproute/gateway) to host multiple hosts applications

 In this example, we are going to setup istio to use kubernetes gateway api to host multiple hosts. In this setup, we have a single localhost and we can support servera.example.com and serverb.example.com and many more. First we have to get istio installed and install the kubernetes gateway api CRD. 

Setup istio

istioctl install -f samples/bookinfo/demo-profile-no-gateways.yaml -y

install kubernetes gateway api crds

kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.3.0" | kubectl apply -f -


Let's deploy our application A and application B.

Application A uses port 8080 and uses httpbin as the app image.

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  labels:
    tenant: tenant-a
---
apiVersion: v1
kind: Service
metadata:
  name: servera-service
  namespace: tenant-a
spec:
  selector:
    app: servera
  ports:
  - port: 8080
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: servera
  namespace: tenant-a
spec:
  replicas: 1
  selector:
    matchLabels:
      app: servera
  template:
    metadata:
      labels:
        app: servera
    spec:
      containers:
      - image: docker.io/mccutchen/go-httpbin:v2.15.0
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 8080

Deploy application B that uses a different app and port 5000.

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-b
  labels:
    tenant: tenant-b
---
apiVersion: v1
kind: Service
metadata:
  name: serverb-service
  namespace: tenant-b
spec:
  selector:
    app: serverb
  ports:
  - port: 5000
    targetPort: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serverb
  namespace: tenant-b
spec:
  replicas: 1
  selector:
    matchLabels:
      app: serverb
  template:
    metadata:
      labels:
        app: serverb
    spec:
      containers:
      - image: docker.io/istio/examples-helloworld-v1:1.0
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 5000


It is important that we have "gatewayClassName" as istio.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-gateway
  namespace: default
spec:
  gatewayClassName: istio # <-- important when you're using istio
  listeners:
  - name: servera
    hostname: servera.example.com
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All  # allow routes from all namespaces (multi-tenant)
  - name: serverb
    hostname: serverb.example.com
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All

Next we will define our httproute A

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: servera-route
  namespace: tenant-a
spec:
  parentRefs:
  - name: shared-gateway
    namespace: default
  hostnames:
  - servera.example.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: servera-service
      port: 8080
      namespace: tenant-a

Then httproute B


apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: serverb-route
  namespace: tenant-b
spec:
  parentRefs:
  - name: shared-gateway
    namespace: default
  hostnames:
  - serverb.example.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: serverb-service
      port: 5000
      namespace: tenant-b

Let's validate our gateway to ensure there's no error. You should see 2 that there's 2 HttpRoute listeners and no problem. 


To test this out we can use the following curl command:- 

# Test Tenant A (serverA.example.com)
curl -H "Host: servera.example.com" http://localhost/

# Test Tenant B (serverB.example.com)
curl -H "Host: serverb.example.com" http://localhost/hello -v


Sample output from application A 


Sample output from application B





Comments

Popular posts from this blog

gemini cli getting file not defined error

NodeJS: Error: spawn EINVAL in window for node version 20.20 and 18.20

vllm : Failed to infer device type