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.
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:
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
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.
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.
Apply the Ingress definition file. The Ingress resource must be created in the same namespace as the Gateway instance.
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.
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.
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.
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.
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
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
.
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.
If you want to use the L4 network load balancer to expose the Gateway over TLS, activate TLS termination on your Gateway instance.