Basic example

Set up basic route delegation between a parent and two child HTTPRoute resources.

Configuration overview

In this guide you walk through a basic route delegation example that demonstrates route delegation between a parent HTTPRoute resource and two child HTTPRoute resources that forward traffic to an httpbin sample app. The following image illustrates the resulting route delegation hierarchy:

parent HTTPRoute:

  • The parent HTTPRoute resource delegates 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.

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.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. 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
  3. 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_ADDRESS
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

  4. Create the namespaces for team1 and team2.

    kubectl create namespace team1
    kubectl create namespace team2
  5. 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
  6. 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 parent HTTPRoute resource that matches incoming traffic on the delegation.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: parent
      namespace: kgateway-system
    spec:
      hostnames:
      - delegation.example
      parentRefs:
      - name: http
      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 child HTTPRoute resource for 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
  3. Create the child HTTPRoute resource for the team2 namespace that matches traffic on the /anything/team2/bar exact prefix and routes traffic to the httpbin app in the team2 namespace. The child HTTPRoute resource specifies a specific parent HTTPRoute resource by using the spec.parentRefs field.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team2
      namespace: team2
    spec:
      parentRefs:
      - name: parent
        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
  4. Inspect the parent and child HTTPRoute resources.

    kubectl get httproute child-team1 -n team1
    kubectl get httproute child-team2 -n team2
    kubectl get httproute parent -n kgateway-system
  5. Send a request to the delegation.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.example"
    curl -i localhost:8080/anything/team1/foo -H "host: delegation.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.example domain along the /anything/team1/bar path. Verify that you get back a 404 HTTP response code, because this route is not specified in the child HTTPRoute resource child-team1.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/team1/bar -H "host: delegation.example"
    curl -vi localhost:8080/anything/team1/bar -H "host: delegation.example"

    Example output:

    HTTP/1.1 404 Not Found
    date: Mon, 06 May 2024 16:01:48 GMT
    server: envoy
    transfer-encoding: chunked
  7. Send another request to the delegation.example domain. This time, you use the /anything/team2/bar path that is configured on the child-team2 HTTPRoute resource. Verify that you get back a 200 HTTP response code.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation.example"
    curl -i localhost:8080/anything/team2/bar -H "host: delegation.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 along the /anything/team2/bar/test path. Because the child-team2 HTTPRoute resource matches traffic only on the anything/team2/bar exact path, this request fails and a 404 HTTP response code is returned.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar/test -H "host: delegation.example"
    curl -i localhost:8080/anything/team2/bar/test -H "host: delegation.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 parent -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/v2.0.x/assets/docs/examples/httpbin.yaml
kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/v2.0.x/assets/docs/examples/httpbin.yaml
kubectl delete namespaces team1 team2