How-tos

Centralized Configuration for Spring Apps on Bluemix Kubernetes

Share this post:

In this tutorial, we’ll adapt the Centralized Configuration guide from the Spring website to be deployed to Bluemix Kubernetes.  We’ll host our configuration files in a Github repository.  Before getting started, you should follow the guide or download the complete version.

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.

Creating a Config Repository

Your configuration files can be stored in any Git repository you choose.  For simplicity, I will use a public Github repository.  However, in practice you will probably want to use something safer from prying eyes.

Once you have created a repository, we’ll add our first configuration file.  Create an application.properties file with the following contents:

message = Hello world!

Commit this file to your repository.  Next we’re going to connect the configuration server to this repository.

Note: Spring provides support for encrypted configuration files.  There are several additional steps required to set this up, so we won’t cover it here.  If you are interested in encrypting your files, see the Spring Cloud Config docs for guidance.

Adjusting Spring Project for Kubernetes

Before we can deploy our applications to Kubernetes, we need to make a couple adjustments.  If you downloaded the complete version from the Centralized Configuration guide I mentioned above, you’ll want to work with the projects in the complete directory.

First, open the application.properties file from the “configuration-service” project. We’re going to add the URI for our Git repository here.

server.port=8888

spring.cloud.config.server.git.uri=https://github.com/<username>/spring-cloud-config

I mentioned previously that you could use a private Git repository.  If you chose to use a private repository, you’ll need to include a couple more properties:

spring.cloud.config.server.git.username
spring.cloud.config.server.git.password

The username should be an account that can read from the configuration repository. The password can be the account’s password, but you should consider generating a personal API token if you are using Github, or a similar revokable token.

That’s all we need to change to run the Spring Configuration Server on Bluemix Kubernetes! Now let’s create a Docker image with this application. Create a Dockerfile file with the following contents:

FROM java:8
COPY /target/configuration-service-0.0.1-SNAPSHOT.jar /configuration-service-0.0.1-SNAPSHOT.jar
EXPOSE 8888
ENTRYPOINT java -jar /configuration-service-0.0.1-SNAPSHOT.jar

Then run the following commands in the same directory as your Dockerfile:

$ mvn package
...
$ docker build . -t registry.ng.bluemix.net/<namespace>/config-service:latest
...
$ docker push registry.ng.bluemix.net/<namespace>/config-service:latest
...

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

Next we’ll switch over to the “configuration-client” project and make some changes there. Open the bootstrap.properties file and change the config URI:

spring.application.name=a-bootiful-client
# N.B. this is the default:
spring.cloud.config.uri=http://config-service:8888
management.security.enabled=false

Then create another Dockerfile for this application, with the following contents:

FROM java:8
COPY /target/configuration-client-0.0.1-SNAPSHOT.jar /configuration-client-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT java -jar /configuration-client-0.0.1-SNAPSHOT.jar

Then run the following commands in the same directory as your Dockerfile:

$ mvn package
...
$ docker build . -t registry.ng.bluemix.net/<namespace>/config-client:latest
...
$ docker push registry.ng.bluemix.net/<namespace>/config-client:latest
...

That’s it, now we’re ready to deploy to Kubernetes and give the test out the configuration server.

Deploying to Bluemix Kubernetes

We’ll need a few files in order to deploy to Kubernetes.  First create service-pod.yaml and client-pod.yaml files with the following contents:

apiVersion: v1
kind: Pod
metadata:
  name: config-service
  labels:
    name: config-service
spec:
  containers:
    - name: config-service
      image: registry.ng.bluemix.net/<namespace>/config-service:latest
      ports:
        - containerPort: 8888
apiVersion: v1
kind: Pod
metadata:
  name: config-client
  labels:
    name: config-client
spec:
  containers:
    - name: config-client
      image: registry.ng.bluemix.net/<namespace>/config-client:latest
      ports:
        - containerPort: 8080

These are simple pod deployment files, using the images we created earlier. Next create a services.yaml file with the following contents:

apiVersion: v1
kind: Service
metadata:
  name: client-service
  namespace: default
spec:
  type: NodePort
  ports:
    - port: 8080
  selector:
    name: config-client

---

apiVersion: v1
kind: Service
metadata:
  name: config-service
  namespace: default
spec:
  ports:
    - port: 8888
  selector:
    name: config-service

In this file, we define two services. The first will create a NodePort allowing us to access our “configuration-client” REST endpoints. The second is the service where our client will look to find it’s configuration.

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:

$ kubectl proxy

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 services.yaml file.  Upload this file with the UPLOAD button.  Then follow the same procedure with your service-pod.yaml file.

Allow the “configuration-service” application to start before continuing. You can check its progress through the pod logs. After it has started, go ahead and deploy your client-pod.yaml file as well.

Next you will need to find where the service is being exposed. 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 NodePorts, click Services on the left sidebar and find the port number (in the range 30000-32767) associated with the “client-service” service.

In a terminal, use the following command to make a request to the client service. The URL will be formed by the public node IP and “client-service” NodePort.

$ curl http://168.1.140.71:31936/message
Hello world

You should get a response of “Hello world” if everything went as expected. If you received “Hello default” instead, you likely didn’t wait long enough before starting the client pod. But that is okay, you can still continue on and we will see how to refresh the client configuration.

Return to your Git repository and create an a-bootfiul-client.properties file with the following contents:

message = New message

Then push this file to your repository so it will be accessible by the Spring configuration server application. In order to see this new configuration file in action, you’ll need to refresh your client application. You can do this by sending an empty POST request to the /refresh endpoint:

curl -X POST http://168.1.140.71:31936/refresh

Now if you visit the /message endpoint again, you should see your new message!

$ curl http://168.1.140.71:31936/message
New message

Conclusion

In this tutorial, we adapted the “Centralized Configuration” guide from the Spring website to run on Bluemix Kubernetes.  The Spring configuration server allows your applications to pull their config from a central location at start, as well as have their configuration refreshed while running (through Spring Actuator).

More How-tos stories

How to Backup Your IBM Cloud Linux Server

This post covers how to backup entire partitions in Linux systems. The process utilizes the tar command in IBM Cloud's unique rescue environment and showcases the simplicity and flexibility of the process.

Continue reading

Speed up your WordPress with IBM Cloud

WordPress is one of the most popular content management systems available, but the many websites and blogs that use it experience issues with speed. At IBM Cloud, there are several solutions that can help alleviate some of these issues and allow you to have a better and faster WordPress experience.

Continue reading

Container Native Monitoring Insights with Elastic on IBM Cloud

Introduction to container native monitoring In this blog post, we will discuss how Elastic easily deploys with the IBM Cloud Kubernetes Service (IKS). This provides full visibility of your containerized workloads and operational consistency with container deployments in a multi-cloud architecture. We will deploy a Kubernetes cluster in IBM Cloud and layer in the Elastic […]

Continue reading