This page will explain how to configure and deploy an extension in Spring Cloud Gateway for Kubernetes. If you have doubts about the development process, refer to Extensions Development.

Extensions can be added with two simple steps to any Gateway Instance, including those already running. In short, you just need to create a Kubernetes ConfigMap and enable it in the desired Gateway Instance.

Prerequisites

The requirements for these steps are:

  • SCG for K8s packaged extension (in JAR)
  • Kubernetes cluster

Extension Deployment

For ease of use and flexibility extensions are stored in ConfigMaps. Provided you have the JAR package, simply create a ConfigMap as follows:

  $ kubectl create configmap extension-name --from-file=extension.jar -n gateway_namespace

The config map name will identify the extension later.

You can confirm that the ConfigMap was successfully created with the contents of the jar:

$  kubectl get configmap extension-name -o yaml

You will see something that looks like this:

apiVersion: v1
binaryData:
  mycustomfilter-0.0.1-SNAPSHOT.jar: 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
kind: ConfigMap
metadata:
  creationTimestamp: "2021-07-23T21:02:47Z"
  name: my-custom-header
  namespace: testing
  resourceVersion: "10535421"
  selfLink: /api/v1/namespaces/testing/configmaps/my-custom-header
  uid: 405e72ce-b025-4552-bee3-5d795c9013ce

Note: It's possible to create a config map with multiple jars, for example if you need a third-party library. Ensure that these do not cause classpath conflicts with project template.

Gateway Configuration

With the extension deployed in the cluster, update or create a new Gateway with the extensions option.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  extensions:
    custom:
      - extension-name

Tip: extensions is an array element, allowing to enable multiple extensions at the same time.

This will automatically restart the Gateway with the new extension(s) available.

Once it is running, you can update the extension configmap and automatically restart the gateway with:

$ kubectl create configmap extension-name --from-file=extension.jar -o yaml --dry-run=client | kubectl apply -f -

Now that the extension is available, it can be used in the respective Route Configuration.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: my-gateway-routes
spec:
  routes:
  - uri: https://httpbin.org
    predicates:
      - Path=/add-header/**
    filters:
      - AddMyCustomHeader

If there's no mapping already, add it to complete the configuration.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayMapping
metadata:
  name: test-gateway-mapping
spec:
  gatewayRef:
    name: my-gateway
  routeConfigRef:
    name: my-gateway-routes

Validation and Troubleshooting

With the deployment completed, enable traffic to the gateway kubectl port-forward service/my-gateway 8080:80 and open http://localhost:8080/add-header/get in your web browser.

You will be greeted with a response similar to the one below, for simplicity some data has been removed. There you should see the custom X-My-Header header.

{
  "args": {},
  "headers": {
    "Forwarded": "proto=http;host=\"localhost:8080\";for=\"127.0.0.1:58598\"",
    "Host": "httpbin.org",
    "X-Forwarded-Host": "localhost:8080",
    "X-Forwarded-Prefix": "/add-header",
    "X-My-Header": "my-header-value"
  },
  "url": "https://localhost:8080/get"
}

If you cannot see the extension working:

  • Obtain the output of a gateway instance (kubectl logs statefulset.apps/my-gateway) to validate if your log traces appear.
  • See the Gateway events with kubectl describe scg my-gateway for diagnostics messages. If the extension could not be loaded you will see a message like ConfigMap '{extension_name}' not found. Skipping configuration.
  • Check the ConfigMap is available in the same namespace as the gateway.
  • Ensure the ConfigMap name matches the extension configuration in the Gateway.
check-circle-line exclamation-circle-line close-line
Scroll to top icon