By default, each Spring Cloud Gateway instance has an associated ClusterIP service to access it within the Kubernetes cluster. To activate access from outside the cluster, you can expose this service using common Kubernetes approaches such as ingress routing or port forwarding. Consult your cloud provider's documentation for ingress options available to you.

Using an ingress resource

Before adding an Ingress, ensure that you have an ingress controller running in your Kubernetes cluster according to your cloud provider documentation.

To use an Ingress resource for exposing a Gateway instance:

  1. Create a Gateway, RouteConfig, and RouteConfigMapping. In this example, we deploy to the my-namespace namespace:

    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGateway
    metadata:
      name: my-gateway
      namespace: my-namespace
    spec:
    ---
    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGatewayRouteConfig
    metadata:
      name: my-gateway-routes
      namespace: my-namespace
    spec:
      routes:
        - uri: https://github.com
          predicates:
            - Path=/github/**
          filters:
            - StripPrefix=1
    ---
    apiVersion: "tanzu.vmware.com/v1"
    kind: SpringCloudGatewayMapping
    metadata:
      name: test-gateway-mapping
      namespace: my-namespace
    spec:
      gatewayRef:
        name: my-gateway
      routeConfigRef:
        name: my-gateway-routes
    
  2. Locate the ClusterIP service associated with the Gateway instance. You can either use this service as an Ingress backend or change it to a different Service type.

  3. Create a file called ingress-config.yaml, with the following YAML definition:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-gateway-ingress
      namespace: my-namespace
      annotations:
        kubernetes.io/ingress.class: contour
    spec:
      rules:
        - host: my-gateway.my-example-domain.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: my-gateway
                    port:
                      number: 80
    

    For the host and serviceName values, substitute your desired hostname and service name.

    This example Ingress resource configuration uses the Project Contour Ingress Controller. You can adapt the example configuration if you wish to use another Ingress implementation.

  4. Apply the Ingress definition file. The Ingress resource must be created in the same namespace as the Gateway instance.

  5. Examine the newly created Ingress resource:

    $ kubectl -n my-namespace get ingress my-gateway-ingress
    
    NAME                  CLASS    HOSTS                                     ADDRESS       PORTS   AGE
    my-gateway-ingress    <none>   my-gateway.my-example-domain.com          34.69.53.79    80     2m51s
    
    $ kubectl -n my-namespace describe ingress my-gateway-ingress
    
    Name:             my-gateway-ingress
    Namespace:        my-namespace
    Address:          34.69.53.79
    Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
    Rules:
      Host                                     Path  Backends
      ----                                     ----  --------
      my-gateway.my-example-domain.com
                                               /   my-gateway:80 ()
    

    As the example output shows, the my-gateway.my-example-domain.com virtual host in the Ingress definition is mapped to the my-gateway service on the backend.

  6. Ensure that you can resolve the Ingress definition hostname (in this example, my-gateway.my-example-domain.com) to the IP address of the Ingress resource.

    The IP address is shown in the Address field of the output from the kubectl describe command.

    For local testing, use the command below to open your /etc/hosts file.

    sudo vim /etc/hosts
    

    Resolve the hostname by adding a line to the hosts file.

    34.69.53.79     my-gateway.my-example-domain.com
    

    For extended evaluation, you might create a wildcard DNS A record that maps any virtual host on the domain name (for example, *.my-example-domain.com) to the Ingress resource.

  7. You should now be able to connect to your Gateway instance via the Ingress resource, using a web browser or an HTTP client such as HTTPie or cURL.

    $ http my-gateway.my-example-domain.com/github
    $ http my-gateway.my-example-domain.com/github/<YOUR_GITHUB_USERNAME>
    

    These requests should receive responses from the GitHub homepage (https://github.com) or from the requested path on the GitHub website.

  8. Test the SSO configuration, for example using an HTTP client such as HTTPie:

    $ http my-gateway.my-example-domain.com/github
    

    This request should result in a 302 HTTP status code response, redirecting to the SSO login page. If you use a web browser to access the route my-gateway.my-example-domain.com/github, you will be redirected to the SSO login page. After authenticating, you will be redirected to the GitHub home page.

TLS passthrough

If you would like to activate TLS termination on your Gateway instance, you will need to route requests to port 443, rather than port 80, of the gateway service.

You will also need to configure your Ingress to allow TLS passthrough - this configuration is Ingress implementation dependent.

As an example, to do this using Contour, instead of using the Ingress API you will need to create an HTTPProxy instance, using the TLS passthrough option:

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: my-gateway-httpproxy
spec:
  virtualhost:
    fqdn: my-gateway.my-example-domain.com
    tls:
      passthrough: true
  tcpproxy:
    services:
      - name: my-gateway
        port: 443

Securing an Ingress with a TLS cert from cert-manager

Using cert-manager, which is installed on TAP clusters, you can configure TLS for your Ingress by simply adding an annotation with your ClusterIssuer:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: tap-ingress-selfsigned
  name: my-ingress
spec:
  rules:
  - host: my-gateway.my-example-domain.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: my-gateway
            port:
              number: 80
  tls:
  - hosts:
    - my-gateway.my-example-domain.com
    secretName: ingress-tls-cert

Here cert-manager uses the ClusterIssuer tap-ingress-selfsigned to create both a Certificate and TLS secret named my-gateway-tls-cert for the domain my-gateway.my-example-domain.com for the gateway my-gateway.

Using a LoadBalancer

When defining a gateway, you can expose the gateway's Kubernetes service as a LoadBalancer to have your cloud provider automatically create a corresponding Layer 4 (L4) network load balancer and assign an IP address to it. To do this, specify the service.type as LoadBalancer in your SpringCloudGateway spec:

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

You can find the IP under the EXTERNAL-IP column of the created service. Note: it might take a few moments for your cloud provider to assign the external IP address:

$ kubectl get service/my-gateway

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
my-gateway   LoadBalancer   10.64.12.176   34.29.205.74   80:31428/TCP   9m24s

See your cloud provider's documentation for specifics on the network load balancer being created and how it can be customized with annotations.

Note that an external load balancer typically incurs a cost from your cloud provider.

TLS considerations

If you want to use the L4 network load balancer to expose the Gateway over TLS, activate TLS termination on your Gateway instance.

check-circle-line exclamation-circle-line close-line
Scroll to top icon