Configuring Gateway API resources across namespaces
Unlike Ingress, Gateway API routing resources can use Services in another
namespace if the Service’s namespace permits it. This guide shows how to create
a HTTPRoute
in one namespace that routes to a Service in another, bound to a
Gateway in a third namespace.
Prerequisites: Install Kong Ingress Controller with Gateway API support in your Kubernetes cluster and connect to Kong.
Prerequisites
Install the Gateway APIs
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
-
Create a
Gateway
andGatewayClass
instance to use.echo " --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: kong annotations: konghq.com/gatewayclass-unmanaged: 'true' spec: controllerName: konghq.com/kic-gateway-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: kong spec: gatewayClassName: kong listeners: - name: proxy port: 80 protocol: HTTP allowedRoutes: namespaces: from: All " | kubectl apply -f -
The results should look like this:
gatewayclass.gateway.networking.k8s.io/kong created gateway.gateway.networking.k8s.io/kong created
Install Kong
You can install Kong in your Kubernetes cluster using Helm.
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo update
-
Install Kong Ingress Controller and Kong Gateway with Helm:
helm install kong kong/ingress -n kong --create-namespace
Test connectivity to Kong
Kubernetes exposes the proxy through a Kubernetes service. Run the following commands to store the load balancer IP address in a variable named PROXY_IP
:
-
Populate
$PROXY_IP
for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $PROXY_IP
-
Ensure that you can call the proxy IP:
curl -i $PROXY_IP
The results should look like this:
HTTP/1.1 404 Not Found Content-Type: application/json; charset=utf-8 Connection: keep-alive Content-Length: 48 X-Kong-Response-Latency: 0 Server: kong/3.0.0 {"message":"no Route matched with those values"}
Create namespaces and allow references
-
Create separate namespaces to hold the
HTTPRoute
and target Service:kubectl create namespace test-source kubectl create namespace test-destination
The results should look like this:
namespace/test-source created namespace/test-destination created
-
Create a
ReferenceGrant
resource in the destination namespace:echo 'kind: ReferenceGrant apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: test-grant namespace: test-destination spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: test-source to: - group: "" kind: Service ' | kubectl create -f -
The results should look like this:
referencegrant.gateway.networking.k8s.io/test-grant created
ReferenceGrants allow namespaces to opt in to references from other resources.
They reside in the namespace of the target resource and list resources and
namespaces that can talk to specific resources in the ReferenceGrant’s
namespace. The above example allows HTTPRoutes in the test-source
namespace
to reference Services in the test-destination
namespace.
Using a Gateway resource in a different namespace
Gateway resources may also allow references from resources (HTTPRoute
,
TCPRoute
, etc.) in other namespaces. However, these references do not use
ReferenceGrants, as they are defined per listener in the Gateway resource, not for the entire Gateway.
A listener’s allowedRoutes
field
lets you define which routing resources can bind to that listener.
The default Gateway in this guide only allows routes from its same namespace
(default
). You’ll need to expand its scope to allow routes from the
test-source
namespace:
kubectl patch --type=json gateways.gateway.networking.k8s.io kong -p='[{"op":"replace","path": "/spec/listeners/0/allowedRoutes/namespaces/from","value":"All"}]'
The results should look like this:
gateway.gateway.networking.k8s.io/kong patched
This results in a Gateway
resource with the following configuration:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
Listeners can allow routes in their own namespace (from: Same
), all namespaces (from: All
), or a
labeled set of namespaces (from: Selector
).
Deploy a Service and HTTPRoute
-
Deploy an echo Service to the
test-destination
resource.kubectl apply -f https://docs.konghq.com/assets/kubernetes-ingress-controller/examples/echo-service.yaml -n test-destination
The results should look like this:
service/echo created deployment.apps/echo created
-
Deploy a HTTPRoute that sends traffic to the service.
echo 'apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: echo namespace: test-source annotations: konghq.com/strip-path: "true" spec: parentRefs: - name: kong namespace: default rules: - matches: - path: type: PathPrefix value: /echo backendRefs: - name: echo kind: Service port: 1027 namespace: test-destination ' | kubectl apply -f -
The results should look like this:
httproute.gateway.networking.k8s.io/echo created
Note the
namespace
fields in both the parent and backend references. By default, entries here attempt to use the same namespace as the HTTPRoute if you do not specify a namespace. -
Send requests through the route.
curl -s "$PROXY_IP/echo"
The results should look like this:
Welcome, you are connected to node kind-control-plane. Running on Pod echo-965f7cf84-z9jv2. In namespace test-destination. With IP address 10.244.0.6.