In this topic, you will learn how to expose Spring Cloud Gateway for Kubernetes outside of your clusters using Contour ingress on the Tanzu Application Platform (commonly known as TAP).
The high-level steps are:
- Install Contour package in your TAP cluster.
- Install Spring Cloud Gateway for Kubernetes, if not already installed.
- Deploy an instance of Spring Cloud Gateway for Kubernetes.
- Setup a Kubernetes Ingress.
- (Optional) For TLS support, automate your certificates using cert-manager.
Installing Contour ingress controller
Contour is a supported Kubernetes ingress controller for Tanzu Application Platform and is available as a package. You can check the version by running:
$ tanzu package available list contour.tanzu.vmware.com -n tap-install
For full details about the installation, see Install Contour in the TAP documentation. The installation requires the pre-installation of cert-manager, which is also available in TAP. See also Install cert-manager.
Installing Spring Cloud Gateway for Kubernetes
You can check if Spring Cloud Gateway package is already installed by running:
$ tanzu package installed list --all-namespaces
If Spring Cloud Gateway is installed, you will see the package spring-cloud-gateway.tanzu.vmware.com
and the installation namespace for spring-cloud-gateway.tanzu.vmware.com
.
NAME PACKAGE-NAME PACKAGE-VERSION STATUS NAMESPACE
accelerator accelerator.apps.tanzu.vmware.com 1.5.1 Reconcile succeeded tap-install
api-auto-registration apis.apps.tanzu.vmware.com 0.3.0 Reconcile succeeded tap-install
api-portal api-portal.tanzu.vmware.com 1.3.0 Reconcile succeeded tap-install
...
spring-cloud-gateway spring-cloud-gateway.tanzu.vmware.com 2.0.0-tap.4 Reconcile succeeded tap-install
...
If it’s not listed, proceed with the installation. Your cluster will already be prepared for the installation of Spring Cloud Gateway for Kubernetes from the Tanzu Application Platform package repository. You can begin Spring Cloud Gateway for Kubernetes installation from the step called checking packages available for installation.
Deploying an instance of Spring Cloud Gateway for Kubernetes
After you have Contour and Spring Cloud Gateway for Kubernetes installed, you deploy a Gateway instance pointing to a valid service or application.
For testing only: Here is an simple configuration to create an instance with a single route configuration pointing to the public service, https://httpbingo.org.
kubectl apply -f - <<EOF
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
routes:
- uri: https://httpbingo.org
predicates:
- Path=/httpbingo/**
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayMapping
metadata:
name: test-gateway-mapping
spec:
gatewayRef:
name: my-gateway
routeConfigRef:
name: my-gateway-routes
---
EOF
You can check the status of the Gateway by running:
$ kubectl get springcloudgateways
After some time, the instance will show READY
as True
.
NAME READY REASON
my-gateway True Updated
Setting up a Kubernetes ingress
Contour already supports standard Kubernetes ingress configurations, and the Spring Cloud Gateway for Kubernetes operator provides a Kubernetes service on port 80. So, the next step is to create an Ingress resource using the Gateway service provided.
kubectl apply -f - <<EOF
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-gateway-ingress
labels:
app: my-gateway-ingress
spec:
defaultBackend:
service:
name: my-gateway
port:
number: 80
---
EOF
To check availability of the services, run:
$ kubectl get services -n {gateway_namespace}
The following service should appear.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-gateway ClusterIP 10.20.12.98 <none> 80/TCP 10m
You can obtain the public IP address by running the following:
$ kubectl get ingress scg-k8s-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
scg-k8s-ingress <none> my-gateway.demo 34.106.39.12 80, 443 3h55m
Now, you can access the service from a web browser using http://{ip_address}/httpbingo/get.
Automating TLS configuration with cert-manager
You can now activate TLS in your Ingress and automate the certificate generation in TAP.
To complete the example:
- Create a cert-manager
Certificate
request to create a certificate using the TAP-provided infrastructure. - Configure the Kubernetes Ingress resource with the generated certificate.
Note that cert-manager is included in the TAP package repository, and is a requirement for Contour, so it should already be available. -
You can validate that it is installed using the same procedure you used to check for Spring Cloud Gateway for Kubernetes.
$ tanzu package installed list --all-namespaces
You will see the package
cert-manager.tanzu.vmware.com
and the installation namespace.NAME PACKAGE-NAME PACKAGE-VERSION STATUS NAMESPACE accelerator accelerator.apps.tanzu.vmware.com 1.5.1 Reconcile succeeded tap-install api-auto-registration apis.apps.tanzu.vmware.com 0.3.0 Reconcile succeeded tap-install api-portal api-portal.tanzu.vmware.com 1.3.0 Reconcile succeeded tap-install ... cert-manager cert-manager.tanzu.vmware.com 2.3.0 Reconcile succeeded tap-install ...
Tanzu Application Platform includes a
ClusterIssuer
resource calledtap-ingress-selfsigned
that can be used for this example. -
Create the following
Certificate
request to obtain a secret calledmy-gateway-ingress-tls-secret
.commonName
anddnsNames
must match the domain name you intend to use in Ingress later.kubectl apply -f - <<EOF --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-gateway-ingress-tls spec: secretName: my-gateway-ingress-tls-secret duration: 2160h renewBefore: 360h subject: organizations: - example commonName: my-gateway.demo isCA: false privateKey: algorithm: RSA encoding: PKCS1 size: 2048 usages: - server auth - client auth dnsNames: - my-gateway.demo issuerRef: name: tap-ingress-selfsigned kind: ClusterIssuer --- EOF
-
Next, create the final Ingress resource using the secret obtained
my-gateway-ingress-tls-secret
.kubectl apply -f - <<EOF --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: scg-k8s-ingress labels: app: scg-k8s-ingress spec: tls: - hosts: - my-gateway.demo secretName: my-gateway-ingress-tls-secret rules: - host: my-gateway.demo http: paths: - path: / pathType: Prefix backend: service: name: my-gateway port: number: 80 --- EOF
-
For the next part to work, you need to invoke the service using the domain name in the certificate. If you don’t have a domain resolution service, you can fake it adding the Ingress public IP to your hosts file.
As seen before, run
kubectl get ingress scg-k8s-ingress
to obtain the IP address. Then, add an entry like the one below in you /etc/hosts configuration file (%SystemRoot%\System32\drivers\etc\hosts in Windows).34.106.39.12 my-gateway.demo
-
Finally, if you call the TLS endpoint by running:
$ curl -vk "https://my-gateway.demo/httpbingo/get"
You can see that the response certificate matches the configuration you provided initially (see subject and issuer).
* Connected to my-gateway.demo (34.106.39.12) port 443 (#0) * ALPN: offers h2 * ALPN: offers http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 * ALPN: server accepted h2 * Server certificate: * subject: O=example; CN=my-gateway.demo * start date: Apr 3 12:53:28 2023 GMT * expire date: Jul 2 12:53:28 2023 GMT * issuer: CN=tap-ingress-selfsigned-root-ca * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. * Using HTTP2, server supports multiplexing ...
Content feedback and comments