Router Extensibility Features in Kubernetes

Learn how to deploy a self-hosted router (GraphOS Router or Apollo Router Core) in Kubernetes with extensibility features


note
The Apollo Router Core source code and all its distributions are made available under the Elastic License v2.0 (ELv2) license.

The router supports two extensibility options to customize the router's behavior. The extensibility features are:

This guide shows how to deploy a router with these features in Kubernetes.

Deploy with Rhai scripts

The router supports Rhai scripting to add custom functionality.

Enabling Rhai scripts in your deployed router requires mounting an extra volume for your Rhai scripts and getting your scripts onto the volume. That can be done by following steps in a separate example for creating a custom in-house router chart. The example creates a new (in-house) chart that depends on the released router chart, and the new chart has templates that add the necessary configuration to allow Rhai scripts for a deployed router.

Deploying with a coprocessor

You have two options to consider when deploying a coprocessor.

Consider the following when deciding which option to use:

  • The sidecar container option is the simplest and most common way to deploy a coprocessor. It allows you to run the coprocessor in the same pod as the router, which can simplify networking and configuration.

  • The separate Deployment option allows you to run the coprocessor in a different pod, which can be useful if you want to scale the coprocessor independently of the router.

Deploy as a sidecar container

The router supports external coprocessing to run custom logic on requests throughout the router's request-handling lifecycle.

A deployed coprocessor can have its own application image and container in the router pod.

To configure a coprocessor and its container for your deployed router through a YAML configuration file:

  1. Create a YAML file, coprocessor_values.yaml, to contain additional values that override default values.

  2. Edit coprocessor_values.yaml to configure a coprocessor for the router. For reference, follow the typical and minimal configuration examples, and apply them to router.configuration.coprocessor.

Example of typical configuration for a coprocessor
YAML
router.yaml
1coprocessor:
2  url: http://127.0.0.1:8081 # Required. Replace with the URL of your coprocessor's HTTP endpoint.
3  # The timeout for all coprocessor requests. Defaults to 1 second (1s)
4  # Supported formats: https://docs.rs/humantime/latest/humantime/fn.parse_duration.html
5  timeout: 2s
6  router: # This coprocessor hooks into the `RouterService`
7    request: # By including this key, the `RouterService` sends a coprocessor request whenever it first receives a client request.
8      headers: true # These boolean properties indicate which request data to include in the coprocessor request. All are optional and false by default.
9      body: false
10      context: false
11      sdl: false
12      path: false
13      method: false
14    response: # By including this key, the `RouterService` sends a coprocessor request whenever it's about to send response data to a client (including incremental data via @defer).
15      headers: true
16      body: false
17      context: false
18      sdl: false
19      status_code: false
20  supergraph: # This coprocessor hooks into the `SupergraphService`
21    request: # By including this key, the `SupergraphService` sends a coprocessor request whenever it first receives a client request.
22      headers: true # These boolean properties indicate which request data to include in the coprocessor request. All are optional and false by default.
23      body: false
24      context: false
25      sdl: false
26      method: false
27    response: # By including this key, the `SupergraphService` sends a coprocessor request whenever it's about to send response data to a client (including incremental data via @defer).
28      headers: true
29      body: false
30      context: false
31      sdl: false
32      status_code: false
33  subgraph:
34    all:
35      request: # By including this key, the `SubgraphService` sends a coprocessor request whenever it is about to make a request to a subgraph.
36        headers: true # These boolean properties indicate which request data to include in the coprocessor request. All are optional and false by default.
37        body: false
38        context: false
39        uri: false
40        method: false
41        service_name: false
42        subgraph_request_id: false
43      response: # By including this key, the `SubgraphService` sends a coprocessor request whenever receives a subgraph response.
44        headers: true
45        body: false
46        context: false
47        service_name: false
48        status_code: false
49        subgraph_request_id: false
50  connector: # This coprocessor hooks into connector HTTP requests.
51    all:
52      request: # By including this key, the coprocessor sends a request before each connector HTTP call.
53        headers: true # These boolean properties indicate which request data to include in the coprocessor request. All are optional and false by default.
54        body: false
55        context: false
56        uri: false
57        method: false
58        service_name: false
59      response: # By including this key, the coprocessor sends a request after each connector HTTP call.
60        headers: true
61        body: false
62        context: false
63        service_name: false
64        status_code: false
  1. Edit coprocessor_values.yaml to add a container for the coprocessor.

YAML
coprocessor_values.yaml
1extraContainers:
2  - name: <coprocessor-deployed-name> # name of deployed container
3    image: <coprocessor-app-image> # name of application image
4    ports:
5      - containerPort: <coprocessor-container-port> # must match port of router.configuration.coprocessor.url
6    env: [] # array of environment variables
  1. Deploy the router with the additional YAML configuration file. For example, starting with the helm install command from the basic deployment step, append --values coprocessor_values.yaml:

Bash
1helm install --namespace <router-namespace> --set managedFederation.apiKey="<graph-api-key>" --set managedFederation.graphRef="<graph-ref>"  oci://ghcr.io/apollographql/helm-charts/router --version <router-version> --values router/values.yaml --values coprocessor_values.yaml

Deploying using a separate Deployment

Deploying as a separate Deployment can take shape in two ways:

  • Using an entirely separate Helm chart.

  • Using the router's Helm chart as a dependency and adding a new Deployment template

    • This option is more complex but allows you to customize the router's Helm chart and add your own templates whilst keeping the coporcessor's deployment alongside the router's.

Separate Helm chart

In the case of using a separate Helm chart, a coprocessor chart would be deployed independently of the router. This chart would contain the configuration for the coprocessor's deployment. An example folder structure might look like:

Text
1charts/
2├── coprocessor/
3│   ├── Chart.yaml
4│   ├── values.yaml
5│   ├── templates/
6│   │   ├── deployment.yaml
7│   │   ├── service.yaml
8│   │   └── ...
9│   └── ...
10├── router/
11│   ├── values.yaml
12│   └── ...

The router chart would be the router's Helm chart, which you can deploy as described in the Kubernetes deployment guide.

Using the router's Helm chart as a dependency

In the case of using the router's Helm chart as a dependency, you can create a new template in the templates folder of the router Helm chart. This template would contain the configuration for the coprocessor's deployment.

The Chart.yaml file for the router would include:

YAML
1dependencies:
2  - name: router
3    version: 2.3.0
4    repository: oci://ghcr.io/apollographql/helm-charts

An example folder structure might look like:

Text
1charts/
2├── router/
3│   ├── Chart.yaml
4│   ├── values.yaml
5│   ├── templates/
6│   │   ├── deployment.yaml
7│   │   ├── service.yaml
8│   │   └── ...
9│   └── ...

In the above example, the router chart would be the router's Helm chart, which you can deploy as described in the Kubernetes deployment guide. The templates folder would contain the configuration for the coprocessor's deployment. Within the values.yaml you can then nest the necessary configuration under the router key, such as:

values.yaml
1router:
2  configuration:
3    coprocessor:
4      url: http://<coprocessor-service-name>:<coprocessor-container-port>
Feedback

Edit on GitHub

Ask Community