Centralized Configuration for Spring Apps on Bluemix Kubernetes

5 min read

By: Jeffrey Ruffolo

Centralized Configuration for Spring Apps on Bluemix Kubernetes

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:

<br>
message = Hello world!<br>

 

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.

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

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:

<br>
spring.cloud.config.server.git.username<br>
spring.cloud.config.server.git.password<br>

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:

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

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

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

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:

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

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

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

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

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

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:

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

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

<br>
apiVersion: v1<br>
kind: Service<br>
metadata:<br>
  name: client-service<br>
  namespace: default<br>
spec:<br>
  type: NodePort<br>
  ports:<br>
    - port: 8080<br>
  selector:<br>
    name: config-client<p></p>
<p>---</p>
<p>apiVersion: v1<br>
kind: Service<br>
metadata:<br>
  name: config-service<br>
  namespace: default<br>
spec:<br>
  ports:<br>
    - port: 8888<br>
  selector:<br>
    name: config-service<br>
</p>

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:

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

<br>
$ curl http://168.1.140.71:31936/message<br>
Hello world<br>

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:

<br>
message = New message<br>

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:

<br>
curl -X POST http://168.1.140.71:31936/refresh<br>

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

<br>
$ curl http://168.1.140.71:31936/message<br>
New message<br>

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

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