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