Configuration overview

In this example, you learn how to use labels to delegate traffic. The parent HTTPRoute defines the labels that must be present on the child HTTPRoute to allow traffic to be forwarded.

You typically configure the parent to find an HTTPRoute with a specific label in a specific namespace. However, you can also use a wildcard for the namespace when you have multiple HTTPRoutes in different namespaces that can all receive delegated traffic. This configuration can significantly simplify your route delegation setup as it allows you to quickly add new child HTTPRoutes to the delegation chain without changing the parent HTTPRoute configuration.

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
      

HTTPRoutes in specific namespaces

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

    • Route 1 matches traffic on the path prefix /anything/team1 and delegates traffic to the HTTPRoute with the delegation.gateway.solo.io/label: team1 label.
    • Route 2 matches traffic on the path prefix /anything/team2 and delegates traffic to the HTTPRoute with the delegation.gateway.solo.io/label: team2 label.
      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
     name: parent
     namespace: gloo-system
    spec:
     parentRefs:
     - name: http
     hostnames:
     - delegation.example
     rules:
     - matches:
       - path: 
           type: PathPrefix
           value: /anything/team1
       backendRefs:
       # Delegate to routes with the label delegation.gateway.solo.io/label:foobar
       # in the foo namespace
       - group: delegation.gateway.solo.io
         kind: label 
         name: team1
         namespace: team1
     - matches:
       - path: 
           type: PathPrefix
           value: /anything/team2
       backendRefs:
       # Delegate to routes with the label delegation.gateway.solo.io/label:foobar
       # in the foo namespace
       - group: delegation.gateway.solo.io
         kind: label 
         name: team2
         namespace: team2
    EOF
      
  2. Create the child-team1 HTTPRoute resource in the team1 namespace that matches traffic on the /anything/team1/foo path prefix. To delegate traffic to this HTTPRoute, you must label the route with the delegation.gateway.solo.io/label: team1 label that you defined on the parent HTTPRoute.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team1
      namespace: team1
      labels: 
        delegation.gateway.solo.io/label: team1
    spec:
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team1/foo
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
      
  3. Create the child-team2 HTTPRoute resource in the team2 namespace that matches traffic on the /anything/team2/bar exact prefix. To delegate traffic to this HTTPRoute, you must label the route with the delegation.gateway.solo.io/label: team2 label that you defined on the parent HTTPRoute.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team2
      namespace: team2
      labels: 
        delegation.gateway.solo.io/label: team2
    spec:
      rules:
      - matches:
        - path:
            type: Exact
            value: /anything/team2/bar
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
      
  4. Send a request to the delegation.example domain along the /anything/team1/foo path. Verify that you get back a 200 HTTP response code.

    Example output:

      HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: application/json; encoding=utf-8
    content-length: 509
    x-envoy-upstream-service-time: 0
    server: envoy
    
    {
      "args": {},
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "delegation.example:8080"
        ],
        "User-Agent": [
          "curl/8.7.1"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
         "65927858-2c6b-42ae-9278-8ff9d8bba3f8"
        ]
      },
      "origin": "10.0.64.27:49526",
      "url": "http://delegation.example:8080/anything/team1/foo",
      "data": "",
      "files": null,
      "form": null,
      "json": null
    }
      
  5. Send a request to the delegation.example domain along the /anything/team2/bar path. Verify that you also get back a 200 HTTP response code.

    Example output:

      HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: application/json; encoding=utf-8
    content-length: 509
    x-envoy-upstream-service-time: 1
    server: envoy
    
    {
      "args": {},
      "headers": {
        "Accept": [
         "*/*"
        ],
        "Host": [
          "delegation.example:8080"
        ],
        "User-Agent": [
          "curl/8.7.1"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
          "d645dc37-5326-4b69-8c2c-4060e12ca4ff"
        ]
      },
      "origin": "10.0.64.27:53026",
      "url": "http://delegation.example:8080/anything/team2/bar",
      "data": "",
      "files": null,
      "form": null,
      "json": null
    }
      

Use wildcard namespaces

Instead of routing to an HTTPRoute with a specific label in a specific namespace, you can use a wildcard for the namespace. This configuration can streamline your route delegation setup as it allows you to easily add new child HTTPRoutes to the delegation chain.

  1. Update the parent HTTPRoute to delegate traffic to all child HTTPRoutes with the wildcard label.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
     name: parent
     namespace: gloo-system
    spec:
     parentRefs:
     - name: http
     hostnames:
     - delegation.example
     rules:
     - matches:
       - path:
           type: PathPrefix
           value: /
       backendRefs:
       - group: delegation.gateway.solo.io
         kind: label
         name: wildcard
         namespace: all
    EOF
      
  2. Update the child-team1 HTTPRoute to add the delegation.gateway.solo.io/label: wildcard label so that the parent HTTPRoute can delegate traffic to this route.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team1
      namespace: team1
      labels: 
        delegation.gateway.solo.io/label: wildcard
    spec:
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team1/foo
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
      
  3. Update the child-team2 HTTPRoute to also add the delegation.gateway.solo.io/label: wildcard label.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team2
      namespace: team2
      labels: 
        delegation.gateway.solo.io/label: wildcard
    spec:
      rules:
      - matches:
        - path:
            type: Exact
            value: /anything/team2/bar
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
      
  4. Send a request to the delegation.example domain along the /anything/team1/foo path. Verify that you get back a 200 HTTP response code.

    Example output:

      HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: application/json; encoding=utf-8
    content-length: 509
    x-envoy-upstream-service-time: 0
    server: envoy
    
    {
      "args": {},
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "delegation.example:8080"
        ],
        "User-Agent": [
          "curl/8.7.1"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
         "65927858-2c6b-42ae-9278-8ff9d8bba3f8"
        ]
      },
      "origin": "10.0.64.27:49526",
      "url": "http://delegation.example:8080/anything/team1/foo",
      "data": "",
      "files": null,
      "form": null,
      "json": null
    }
      
  5. Send a request to the delegation.example domain along the /anything/team2/bar path. Verify that you also get back a 200 HTTP response code.

    Example output:

      HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: application/json; encoding=utf-8
    content-length: 509
    x-envoy-upstream-service-time: 1
    server: envoy
    
    {
      "args": {},
      "headers": {
        "Accept": [
         "*/*"
        ],
        "Host": [
          "delegation.example:8080"
        ],
        "User-Agent": [
          "curl/8.7.1"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
          "d645dc37-5326-4b69-8c2c-4060e12ca4ff"
        ]
      },
      "origin": "10.0.64.27:53026",
      "url": "http://delegation.example:8080/anything/team2/bar",
      "data": "",
      "files": null,
      "form": null,
      "json": null
    }
      

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl delete httproute parent -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