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:

  1. Install Contour package in your TAP cluster.
  2. Install Spring Cloud Gateway for Kubernetes, if not already installed.
  3. Deploy an instance of Spring Cloud Gateway for Kubernetes.
  4. Setup a Kubernetes Ingress.
  5. (Optional) For TLS support, automate your certificates using cert-manager.
Block diagram of Spring Cloud Gateway in the context of Contour ingress and TAP packages.

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:///httpbingo/get.

Automating TLS configuration with cert-manager

You can now activate TLS in your Ingress and automate the certificate generation in TAP.

TLS certificate requests are routed from cert-manager in Contour in the TAP Packages.

To complete the example:

  1. Create a cert-manager Certificate request to create a certificate using the TAP-provided infrastructure.

  2. 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.

  3. 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 called tap-ingress-selfsigned that can be used for this example.

  4. Create the following Certificate request to obtain a secret called my-gateway-ingress-tls-secret.

    Important commonName and dnsNames 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
    
  5. 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
    
  6. 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
    
  7. 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
    ...
    
check-circle-line exclamation-circle-line close-line
Scroll to top icon