Under the gateway API we will have the following setup. A gateway are shared by multiple httproute that has a different hostname. Each services are deployed to a different namespace (yellow) and if they are in a different namespace, a reference grant needs to be created and place in the different namespace, as indicated by the diagram below:
In this example, we are going to setup a gateway shared by multiple httproute and multiple services that's deployed to different namespace - namely test and default.
Let's setup our istio
istioctl install --set profile=minimal
Label the namespace
Label the namespace with ostio-injection=enabled as shown below:
kubectl label namespace default istio-injection=enabled
Create test namespace.
kubectl label namespace test istio-injection=enabled
Install the CRDs
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -
Deploy the gateway in the default namespace
kubectl apply -f gateway.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: httpbin-gateway
spec:
gatewayClassName: istio
listeners:
- name: http
hostname: "*.example.com"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
Then install httpbin.yaml that looks like this. You can just use the httpbin.yaml from samples/httpbin folder.
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
We will be deploying to 2 different namespace
kubectl apply -f httpbin.yaml -n default
kubectl apply -f httpbin.yaml -n test
Setting up HTTP Route.
We will be setting up 2 httproute the default namespace. The hostname 'httpbin.example.com' that point to default namespace and 'httpbintest.example.com' that points to test namespace.
httpbin.example.com
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
spec:
parentRefs:
- name: httpbin-gateway
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /status
- path:
type: PathPrefix
value: /delay
backendRefs:
- name: httpbin
port: 8000
kind: Service
namespace: default
httpbintest.example.com
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbintest
spec:
parentRefs:
- name: httpbin-gateway
hostnames: ["httpbintest.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /status
- path:
type: PathPrefix
value: /delay
backendRefs:
- name: httpbin
port: 8000
kind: Service
namespace: test
This is what our httproute looks like (both httproute is in the default namespace).
In the example above, I am placing both httproute in the same namespace. If you want to place httproute in a different namespace, please specify gateway namespace when you try to connect - as shown in the example here:-
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbintest
spec:
parentRefs:
- name: httpbin-gateway
namespace: default ### <----- My gateway resides in default namespace
hostnames: ["httpbintest.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /status
- path:
type: PathPrefix
value: /delay
backendRefs:
- name: httpbin
port: 8000
kind: Service
namespace: test
Finally we need reference grant to test namespace. To do that, please use the following yaml:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: httpgrant
namespace: test
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: ""
kind: Service
After your deploy, you can see a referencegrant in test namespace. This is require if you allow httproute to reach a service that resides in another namespace.
To test it out
curl -s -I -HHost:httpbin.example.com "http://localhost:80/status/200" -v
curl -s -I -HHost:httpbintest.example.com "http://localhost:80/status/200" -v
Comments