Multiple parents
Set up route delegation for a child HTTPRoute resource that can receive traffic from one or more parent HTTPRoute resources.
Configuration overview
In this guide you walk through a route delegation example that demonstrates route delegation between two parent HTTPRoute and two child HTTPRoute resources that forward traffic to an httpbin sample app. The following image illustrates the route delegation hierarchy:
parent1 and parent2 HTTPRoutes:
- The parent HTTPRoute resource
parent1serves traffic for thedelegation-parent1.exampledomain. - The parent HTTPRoute resource
parent2serves traffic for thedelegation-parent2.exampledomain. - Both parent HTTPRoute resources have routes that delegate traffic as follows:
/anything/team1delegates traffic to the child HTTPRoute resourcechild-team1in namespaceteam1./anything/team2delegates traffic to the child HTTPRoute resourcechild-team2in namespaceteam2.
child-team1 HTTPRoute:
- The child HTTPRoute resource
child-team1matches incoming traffic for the/anything/team1/fooprefix path and routes that traffic to the httpbin app in namespaceteam1. The resource does not select any parent HTTPRoute resource in theparentRefsection. Both parent HTTPRoute resources can therefore delegate traffic to this child HTTPRoute resource.
child-team2 HTTPRoute:
- The child HTTPRoute resource
child-team2matches incoming traffic for the/anything/team2/barexact prefix path and routes that traffic to the httpbin app in namespaceteam2. The resource selects theparent1HTTPRoute resource in theparentRefsection. Because of that, only theparent1HTTPRoute resource can delegate traffic to this child HTTPRoute resource. Theparent2HTTPRoute resource cannot delegate traffic to this child.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Create a Gateway resource and configure an HTTP listener. The following Gateway can serve HTTPRoute resources from all namespaces.
kubectl apply -f- <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: http namespace: kgateway-system spec: gatewayClassName: kgateway listeners: - protocol: HTTP port: 8080 name: http allowedRoutes: namespaces: from: All EOF -
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESSkubectl port-forward deployment/http -n kgateway-system 8080:8080 -
Create the namespaces for
team1andteam2.kubectl create namespace team1 kubectl create namespace team2 -
Deploy the httpbin app into both namespaces.
kubectl -n team1 apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/docs/examples/httpbin.yaml kubectl -n team2 apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/docs/examples/httpbin.yaml -
Verify that the httpbin apps are up and running.
kubectl get pods -n team1 kubectl get pods -n team2Example output:
NAME READY STATUS RESTARTS AGE httpbin-f46cc8b9b-bzl9z 3/3 Running 0 7s NAME READY STATUS RESTARTS AGE httpbin-f46cc8b9b-nhtmg 3/3 Running 0 6s
Setup
-
Create the
parent1HTTPRoute resource that matches incoming traffic on thedelegation-parent1.exampledomain. The HTTPRoute resource specifies two routes:/anything/team1: The routing decision is delegated to a child HTTPRoute resource in theteam1namespace./anything/team2: The routing decision is delegated to a child HTTPRoute resource in theteam2namespace.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: parent1 namespace: kgateway-system spec: parentRefs: - name: http hostnames: - "delegation-parent1.example" rules: - matches: - path: type: PathPrefix value: /anything/team1 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team1 - matches: - path: type: PathPrefix value: /anything/team2 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team2 EOF -
Create the second
parent2HTTPRoute resource that serves traffic for thedelegation-parent2.exampledomain. The HTTPRoute resource specifies two routes:/anything/team1: The routing decision is delegated to a child HTTPRoute resource in theteam1namespace./anything/team2: The routing decision is delegated to a child HTTPRoute resource in theteam2namespace.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: parent2 namespace: kgateway-system spec: parentRefs: - name: http hostnames: - "delegation-parent2.example" rules: - matches: - path: type: PathPrefix value: /anything/team1 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team1 - matches: - path: type: PathPrefix value: /anything/team2 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team2 EOF -
Create the child HTTPRoute resource
child-team1in theteam1namespace that matches traffic on the/anything/team1/fooprefix and routes traffic to the httpbin app in theteam1namespace. The child HTTPRoute resource does not select a specific parent HTTPRoute resource. Because of that, the child HTTPRoute resource is automatically selected by all parent HTTPRoute resources that delegate traffic to this child.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: child-team1 namespace: team1 spec: rules: - matches: - path: type: PathPrefix value: /anything/team1/foo backendRefs: - name: httpbin port: 8000 EOF -
Create the child HTTPRoute resource
child-team2in theteam2namespace that matches traffic on the/anything/team1/barexact prefix and routes traffic to the httpbin app in theteam2namespace. The child HTTPRoute resource specifies theparent1HTTPRoute resource in thespec.parentRefssection. Because of that, onlyparent1can delegate traffic to this child.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: child-team2 namespace: team2 spec: parentRefs: - name: parent1 namespace: kgateway-system group: gateway.networking.k8s.io kind: HTTPRoute rules: - matches: - path: type: Exact value: /anything/team2/bar backendRefs: - name: httpbin port: 8000 EOF -
Send a request to the
delegation-parent1.exampledomain along the/anything/team1/foopath. Verify that you get back a 200 HTTP response code.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation-parent1.example"curl -i localhost:8080/anything/team1/foo -H "host: delegation-parent1.example"Example output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * content-type: application/json; encoding=utf-8 date: Mon, 06 May 2024 15:59:32 GMT x-envoy-upstream-service-time: 0 server: envoy transfer-encoding: chunked -
Send another request to the
delegation-parent1.exampledomain along the/anything/team2/barpath. Verify that you get back a 200 HTTP response code.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation-parent1.example"curl -i localhost:8080/anything/team2/bar -H "host: delegation-parent1.example"Example output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * content-type: application/json; encoding=utf-8 date: Mon, 06 May 2024 15:59:32 GMT x-envoy-upstream-service-time: 0 server: envoy transfer-encoding: chunked -
Now, send a request to the
delegation-parent2.exampledomain along the/anything/team1/foopath. Verify that you get back a 200 HTTP response code.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation-parent2.example"curl -i localhost:8080/anything/team1/foo -H "host: delegation-parent2.example"Example output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * content-type: application/json; encoding=utf-8 date: Mon, 06 May 2024 15:59:32 GMT x-envoy-upstream-service-time: 0 server: envoy transfer-encoding: chunked -
Send another request to the
delegation-parent2.exampledomain. This time, you send traffic along the/anything/team2/barpath. Notice that although theparent2HTTPRoute resource delegates traffic to thechild-team2HTTPRoute resource, the child resource allows traffic from theparent1HTTPRoute resource only. Because of that, the request fails and you get back a 404 HTTP response code.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation-parent2.example"curl -i localhost:8080/anything/team2/bar -H "host: delegation-parent2.example"Example output:
HTTP/1.1 404 Not Found date: Mon, 06 May 2024 16:01:48 GMT server: envoy transfer-encoding: chunked
Cleanup
You can remove the resources that you created in this guide.kubectl delete gateway http -n kgateway-system
kubectl delete httproute parent1 -n kgateway-system
kubectl delete httproute parent2 -n kgateway-system
kubectl delete httproute child-team1 -n team1
kubectl delete httproute child-team2 -n team2
kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/docs/examples/httpbin.yaml
kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/docs/examples/httpbin.yaml
kubectl delete namespaces team1 team2