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 parent1 serves traffic for the delegation-parent1.example domain.
  • The parent HTTPRoute resource parent2 serves traffic for the delegation-parent2.example domain.
  • Both parent HTTPRoute resources have routes that delegate traffic as follows:
    • /anything/team1 delegates traffic to the child HTTPRoute resource child-team1 in namespace team1.
    • /anything/team2 delegates traffic to the child HTTPRoute resource child-team2 in namespace team2.

child-team1 HTTPRoute:

  • The child HTTPRoute resource child-team1 matches incoming traffic for the /anything/team1/foo prefix path and routes that traffic to the httpbin app in namespace team1. The resource does not select any parent HTTPRoute resource in the parentRef section. Both parent HTTPRoute resources can therefore delegate traffic to this child HTTPRoute resource.

child-team2 HTTPRoute:

  • The child HTTPRoute resource child-team2 matches incoming traffic for the /anything/team2/bar exact prefix path and routes that traffic to the httpbin app in namespace team2. The resource selects the parent1 HTTPRoute resource in the parentRef section. Because of that, only the parent1 HTTPRoute resource can delegate traffic to this child HTTPRoute resource. The parent2 HTTPRoute resource cannot delegate traffic to this child.

Before you begin

  1. Create the namespaces for team1 and team2.

    kubectl create namespace team1
    kubectl create namespace team2
  2. Deploy the httpbin app into both namespaces.

    kubectl -n team1 apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
    kubectl -n team2 apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
  3. Verify that the httpbin apps are up and running.

    kubectl get pods -n team1
    kubectl get pods -n team2

    Example 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

  1. Create the parent1 HTTPRoute resource that matches incoming traffic on the delegation-parent1.example domain. The HTTPRoute resource specifies two routes:

    • /anything/team1: The routing decision is delegated to a child HTTPRoute resource in the team1 namespace.
    • /anything/team2: The routing decision is delegated to a child HTTPRoute resource in the team2 namespace.
    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: parent1
      namespace: gloo-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
  2. Create the second parent2 HTTPRoute resource that serves traffic for the delegation-parent2.example domain. The HTTPRoute resource specifies two routes:

    • /anything/team1: The routing decision is delegated to a child HTTPRoute resource in the team1 namespace.
    • /anything/team2: The routing decision is delegated to a child HTTPRoute resource in the team2 namespace.
    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: parent2
      namespace: gloo-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
  3. Create the child HTTPRoute resource child-team1 in the team1 namespace that matches traffic on the /anything/team1/foo prefix and routes traffic to the httpbin app in the team1 namespace. 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
  4. Create the child HTTPRoute resource child-team2 in the team2 namespace that matches traffic on the /anything/team1/bar exact prefix and routes traffic to the httpbin app in the team2 namespace. The child HTTPRoute resource specifies the parent1 HTTPRoute resource in the spec.parentRefs section. Because of that, only parent1 can 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: gloo-system
        group: gateway.networking.k8s.io
        kind: HTTPRoute
      rules:
      - matches:
        - path:
            type: Exact
            value: /anything/team2/bar
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
  5. Send a request to the delegation-parent1.example domain along the /anything/team1/foo path. 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:8080"
    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
  6. Send another request to the delegation-parent1.example domain along the /anything/team2/bar path. 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:8080"
    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
  7. Now, send a request to the delegation-parent2.example domain along the /anything/team1/foo path. 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:8080"
    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
  8. Send another request to the delegation-parent2.example domain. This time, you send traffic along the /anything/team2/bar path. Notice that although the parent2 HTTPRoute resource delegates traffic to the child-team2 HTTPRoute resource, the child resource allows traffic from the parent1 HTTPRoute 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:8080"
    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 httproute parent1 -n gloo-system
kubectl delete httproute parent2 -n gloo-system
kubectl delete httproute child-team1 -n team1
kubectl delete httproute child-team2 -n team2
kubectl delete -n team1 -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
kubectl delete -n team2 -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
kubectl delete namespaces team1 team2