Spring Cloud application with Zuul Gateway on Bluemix Kubernetes

5 min read

By: Jeffrey Ruffolo

Spring Cloud application with Zuul Gateway on Bluemix Kubernetes

In this post, we’ll create a simple Spring Cloud application that demonstrates the Zuul library. Zuul acts as a gateway to other microservices, and provides routing and filtering functionality, among other things.  We will build on a project from the Spring guides, and deploy it to Bluemix Kubernetes.

Prerequisites

Before you begin, you’ll need to have the following installed and configured on your PATH:

I will also assume that you are logged into the Bluemix CLI and the Bluemix Container Registry CLI.  You should also have a Kubernetes cluster created in Bluemix, and configured with the Kubernetes CLI.

Building the Application

First, you should complete the Routing and Filtering guide from Spring.  This guide gives a great high-level explanation of how to use Zuul for basic routing and creating simple request filters.  They also provide a completed version of the Spring project, if you would like to skip the implementation. For the rest of this post, I will work within the complete directory.

Once you have completed the Spring guide or downloaded the project code, you are ready to continue with me.  Next we will create Docker images for both applications, starting with book.  Create a Dockerfile file with the following contents:

<br>
FROM java:8<br>
COPY /target/book-0.0.1-SNAPSHOT.jar /book-0.0.1-SNAPSHOT.jar<br>
EXPOSE 8090<br>
ENTRYPOINT java -jar /book-0.0.1-SNAPSHOT.jar<br>

Now run the following command from the same directory as the Dockerfile you just created:

<br>
$ docker build . -t registry.ng.bluemix.net/<namespace>/book:latest<br>

Note: Be sure to replace “” with your own private Bluemix namespace.  For help on creating a Bluemix namespace, see the Bluemix instructions.

After it has finished building the Docker image, push it to your Bluemix registry with the following command:

<br>
$ docker push registry.ng.bluemix.net/<namespace>/book:latest<br>

Next we’ll do the same for the gateway application. But before building the Docker image, we need to make one small change. Add the following line to the application.properties file:

<br>
zuul.routes.kubebooks.url=http://book-service:8090<br>

This addition will add a Zuul route pointing to the other application, through a Kubernetes service that we will create later. With that small change, we are ready to build the Docker image. Create a Dockerfile file with the following contents:

<br>
FROM java:8<br>
COPY /target/gateway-0.0.1-SNAPSHOT.jar /gateway-0.0.1-SNAPSHOT.jar<br>
EXPOSE 8080<br>
ENTRYPOINT java -jar /gateway-0.0.1-SNAPSHOT.jar<br>

Then run the following command (from the gateway directory) to build the Docker image:

<br>
$ docker build . -t registry.ng.bluemix.net/<namespace>/gateway:latest<br>

After the image has built, push it to your Bluemix registry:

<br>
docker push registry.ng.bluemix.net/<namespace>/gateway:latest<br>

Deploying to Kubernetes

Now we’ll deploy both of our application to Kubernetes and create services to make them accessible.  Let’s start with the applications, which I’ll deploy as pods.  Create a pod.yaml file with the following contents:

<br>
apiVersion: v1<br>
kind: Pod<br>
metadata:<br>
  name: spring-gateway<br>
  labels:<br>
    name: spring-gateway<br>
spec:<br>
  containers:<br>
    - name: spring-gateway<br>
      image: registry.ng.bluemix.net/<namespace>/gateway:latest<br>
      ports:<br>
        - containerPort: 8080<p></p>
<p>---</p>
<p>apiVersion: v1<br>
kind: Pod<br>
metadata:<br>
  name: spring-book<br>
  labels:<br>
    name: spring-book<br>
spec:<br>
  containers:<br>
    - name: spring-book<br>
      image: registry.ng.bluemix.net/<namespace>/book:latest<br>
      ports:<br>
        - containerPort: 8090<br>
</p>

In this file, each of the images we created previously is deployed to a pod. Next, create a service.yaml file with the following contents:

<br>
apiVersion: v1<br>
kind: Service<br>
metadata:<br>
  name: book-service<br>
  namespace: default<br>
spec:<br>
  ports:<br>
    - port: 8090<br>
  selector:<br>
    name: spring-book<p></p>
<p>---</p>
<p>apiVersion: v1<br>
kind: Service<br>
metadata:<br>
  name: gateway-service<br>
  namespace: default<br>
spec:<br>
  type: NodePort<br>
  ports:<br>
    - port: 8080<br>
  selector:<br>
    name: spring-gateway<br>
</p>

The first service described in this file is for the book application. It will expose this application inside the Kubernetes cluster, so that it can be routed to from the gateway application. As you may have notice, the name of this service is the same as the URL we provided to the gateway application properties.  This is a feature of standard Kubernetes service discovery.

The other service will expose our gateway application publicly through a NodePort. This will allow us to access and test our Zuul route and filter.

Now we are ready to run our Spring applications on our Bluemix Kubernetes cluster!  Create a proxy connection to your cluster with the following command:

<br>
$ kubectl proxy<br>

Then navigate to the Kubernetes dashboard at: 127.0.0.1:8001/ui.

From the dashboard, click CREATE in the top-right corner, then select the Upload a YAML or JSON file option, and choose your pod.yaml file.  Upload this file with the UPLOAD button.  Then follow the same procedure with your service.yaml file.

Testing the Gateway

After your pods have finished starting up, monitor the log for you gateway pod with the following command:

<br>
$ kubectl logs -f spring-gateway<br>

Here we will see the output from the SimpleFilter, which will be a printout of the requests that are routed.

Next we will need to find where the gateway-service is being exposed to make requests it. To find the public node IP, click Nodes on the left sidebar and use the name of the node that your pod is running on (there should only be one node if you are using a Lite cluster plan). To find the service NodePort, click Services on the left sidebar and find the port number (in the range 30000-32767) associated with the “gateway-service” service.

In a new command window, use the following command to send a request through to the book application through the Zuul route (using your own node’s IP and port):

<br>
$ curl http://168.1.140.71:31069/kubebooks/available<br>
Spring in Action<br>

You should get a response of: “Spring in Action.” If you check the gateway pod logs, you should see the request logged there.

Conclusion

If you followed with me, you have now deployed an application to Kubernetes that uses Zuul to route requests to other services and has a simple filter to log those requests.

Be the first to hear about news, product updates, and innovation from IBM Cloud