The Getting started guide describes the creation of an initial Spring Cloud Gateway instance to get you up and running with routes and route mappings quickly. In this guide you will learn about more features that are available on each Spring Cloud Gateway instance. Configuration for these features is picked up from your SpringCloudGateway resource definitions by the Spring Cloud Gateway for Kubernetes Operator, and applied to the respective gateway pods that underpin each gateway instance.

Configuring environment variables

You can define a map of environment variables to pass to the gateway using the spec.env property. As with any Spring application, this provides a flexible means to override configuration that is not explicitly exposed in the SpringCloudGateway resource definition. The following example uses environment variables to configure the timeout for connections from the gateway to downstream services, and the Spring Framework web package logging level.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: gateway-demo
spec:
  ...
  env:
    - name: spring.cloud.gateway.httpclient.connect-timeout
      value: "90s"
    - name: logging.level.org.springframework.web
      value: debug

Deactivating the SecureHeaders global filter

Spring Cloud Gateway for Kubernetes activates a custom SecureHeaders filter globally, by default. This filter adds the following security best-practice headers to responses:

Activated Secure Header Default Value
Cache-Control no-cache, no-store, max-age=0, must-revalidate
Pragma no-cache
Expires 0
X-Content-Type-Options nosniff
Strict-Transport-Security max-age=631138519
X-Frame-Options DENY
X-XSS-Protection 1; mode=block

If you do not want these headers to be added to responses, use the following:

  • To deactivate this global filter behavior, set the spring.cloud.gateway.secure-headers.disabled environment variable to true:

    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGateway
    metadata:
      name: my-gateway
    spec:
      env:
        - name: spring.cloud.gateway.secure-headers.disabled
          value: "true"
    
  • To deactivate a specific header for a specific route, you can apply the RemoveResponseHeader filter to the route. For example, to remove the X-Frame-Options header, you define:

    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGatewayRouteConfig
    metadata:
      name: my-gateway-routes
    spec:
      routes:
        - uri: https://httpbingo.org
          predicates:
            - Path=/remove-x-frame-options/**
          filters:
            - RemoveResponseHeader=X-Frame-Options
    
  • To deactivate a specific header globally for all routes, you can pass the header name in the spring.cloud.gateway.secure-headers.disabled environment variable, as described in the SecureHeaders filter documentation:

    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGateway
    metadata:
      name: my-gateway
    spec:
      env:
        - name: spring.cloud.gateway.filter.secure-headers.disable
          value: "x-frame-options"
    

Configuring Java environment options

To allow for Gateway instance Java VM tuning, JVM options (JAVA_OPTS) can be specified in the SpringCloudGateway resource:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  java-opts: -XX:+PrintFlagsFinal -Xmx512m

The Spring Cloud Gateway for Kubernetes Operator applies these options to the underlying gateway instance pods and restart them.

Configuring session expiration

If you want to discard inactive sessions after a certain time (10 minutes, for example), add the inactive-session-expiration-in-minutes configuration:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  sso:
    secret: my-sso-credentials
    inactive-session-expiration-in-minutes: 10

This does not modify any authorization server token expiration ("time to live") configuration. It affects only the session information managed inside the gateway.

Configuring hardware resources

Similarly to other Kubernetes resource types, you can override the required memory and CPU for a Gateway under spec.resources:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  resources:
    requests:
      memory: "512Mi"
      cpu: "1"
    limits:
      memory: "1Gi"
      cpu: "2"

By default each instance is initialized with the values shown in the following table:

Resource Requested Limit
Memory 1Gi 1Gi
CPU 0.5 (no limit)

Note that requesting values lower than the suggested values might cause issues and is not recommended.

Configuring probes

Similarly to other Kubernetes resources, you can optionally configure the livenessProbe, readinessProbe and startupProbe for a Gateway to suit your requirements.

By default each instance is initialized with the following configuration:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  podOverrides:
    containers:
      - name: gateway
        livenessProbe:
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 3
          timeoutSeconds: 1
          successThreshold: 1
          httpGet:
            port: 8090
            path: actuator/health/liveness
            scheme: HTTP
        readinessProbe:
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 3
          timeoutSeconds: 1
          successThreshold: 1
          httpGet:
            port: 8090
            path: actuator/health/readiness
            scheme: HTTP
        startupProbe:
          initialDelaySeconds: 10
          failureThreshold: 30
          periodSeconds: 3
          timeoutSeconds: 1
          successThreshold: 1

Applying custom labels to the Gateway pods

Custom labels can be added to the Gateway configuration. These labels are propagated to the pods created by the Operator.

For example:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: test-gateway-tracing
  labels:
    test-label: test
spec:
  count: 2

Then the pods can be listed by specifying the label:

kubectl get pods --selector=test-label=test

Customizing the service type

By default, the gateway is exposed with a ClusterIP service. You can change the type of this service to a NodePort or a LoadBalancer by specifying spec.service.type. You can also configure the exposed port by specifying spec.service.nodePort. If not specified, the port will be assigned automatically.

For example:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
spec:
  service:
    type: NodePort
    nodePort: 32222

Note that for local development, your cluster needs to be configured to expose your chosen nodePort before you can send traffic to the nodes from the host.

Configuring path predicates to match on more specific paths first

In the case where a request matches the predicates of multiple routes, Spring Cloud Gateway for Kubernetes selects the first matching route it encounters in its internal ordered list.

There are two ways to control the path matching:

  • You can use the route type's order field to prioritize specific routes, however it still might be difficult to coordinate the correct order, especially if different teams manage the routes.

  • Alternatively, Spring Cloud Gateway for Kubernetes provides an environment variable to control the ordering of routes by path length:

    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGateway
    metadata:
      name: my-gateway
    spec:
      env:
        - name: spring.cloud.gateway.k8s.route.order
          value: pathlength
    

    By setting this flag on the gateway, it will order the routes by the more specific path. For example, Path=/org/users/** is prioritized over Path=/org/**.

Note the following behavior:

  • With the pathlength flag set, if multiple paths are provided in Path predicates, then the routes are ordered by the first path in their Path predicate. For example, if you have route A with Path=/org/**,/abc/123/** and route B with Path=/org/users/**,/abc/**, then internally, route B would be ordered before route A, because the first path in route B's Path predicate (/org/users/**) is more specific than that of route A (/org/**). Therefore a request to /abc/123, would match with route B.
  • A route's explicit order value, if provided, takes precedence over path specificity ordering. A route with a lower order value (lower values have higher precedence) and less specific path will match before a route with a higher order value and more specific path.
check-circle-line exclamation-circle-line close-line
Scroll to top icon