0
0

Deploying and Building Spring Boot Apps with Cloud Manager and Kubernetes

Two-Clicks to Success Tutorial
Docs EInnovator Posted 03 Jun 20

Deploying and Building Spring Boot Apps with Cloud Manager & Kubernetes

Cloud Manager is a Kubernetes (K8s) platform and web front-end (Web UI) aimed to simplify the experience of deploying, scaling and configuring applications, services, and jobs. More generally, Cloud Manager provides an effective way to setup and manage K8s resources based on a web UI, while avoiding the need to low-level configuration using YAML manifest files, and scripts that call command-line tools. It can also be used for setup easily CI/CD pipelines to build Docker images from source code in Git repositories.

In this tutorial, you will learn how to build and deploy a Java/Spring Boot app, and its dependencies, to a Kubernetes cluster using Cloud Manager. The topics covered include:

  • How to deploy a MySQL database to store application state
  • How to deploy, scale, and configure an application from an existing Docker image
  • How to deploy a support service for the app — we will deploy a SSO Gateway for user authentication
  • How to configure deployments with service Connectors and Bindings
  • How to setup a DNS route for your application — using a Domain+Route and Ingress
  • How to take a snapshoot/backup your application data from MySQL database using Cloud Manager

For illustration purposes, we will use a sample app Superheros implemented with Spring Boot and built with Maven, that uses MySQL for persistent storage, and an SSO Gateway for authentication.

The source app for Superheros is available on a public Git repository: Superheros Git Repo. A pre-build docker image is also available in a Docker Hub repository: einnovator/einnovator-sample-superheros. In this tutorial, we start by using the pre-build docker image to illustrate how to deploy, configure, and scale an application using Cloud Manager. And in a later section, we show how to use Cloud Manager to setup a simple CI/CD pipeline to create a new docker image with a single click.

Getting Started

Cloud Manager is deployed as a Docker image, together with a few support services (micro-service dependencies). It can be installed on-premises, including your laptop or your organization data-center, or on a public cloud. This tutorial illustrates the different steps using Cloud Manager installation on EInnovator public cloud. This allows you to get started quickly in deploying applications without having to setup a self-managed K8s cluster. If you want to follow this approach while following this tutorial, you simply have to register for an account in https://cloud.einnovator.org. If have an account already, you are are done and can move forward with the rest of the tutorial.

Alternatively, you might prefer to run Cloud Manager in your own K8s cluster – e.g. on your laptop, a on-premises cluster, or other public cloud. In this case, check the documentation on how to install cloud manager on-premises —
Deploying Cloud Manager on-permises. We provide easy scripts to install Cloud Manager and all dependencies. At startup time, you need to register as an administrator user and setup the credentials to access you cluster (one or more). Once you have done, you can continue following this tutorial the same way as if you are using the EInnovator public cloud.

When you login to Cloud Manager, you should be able to see the dashboard for Cloud Manager, as shown below:

Cloud Manager Dashboard

A pre-requisite to deploy applications and services in Kubernetes and CloudManager, beyond having an accessible cluster, it to create a (Name)Space. In EInnovator public cloud, when you first login a space is automatically created for you with name {username}-default. You can use this one, or another you that you create. Once you have a Space created, you can navigate to the its details page as shown below:

Space Details

Deploying a MySQL Server

We start by deploying a MySQL server to keep the persistent state for your application. Head to the solution Marketplace page, by clicking on the button Install or toolbar top-right button Marketplace. This shows you the list of all marketplace solutions setup in Cloud Manager. They are organized as Solution Catalogs/Repositories, while some might show up as standalone Solutions. Use the search input to quickly locate MySql from a Catalog. (Ignore Helm catalogs in your search.)

Select the MySQL solution, to show the solution details. Selected the dedicate Dedicated Server plan and enter the resource settings as follow:

  • 1 single instance
  • The amount of memory (e.g. 1Gb)
  • Ephemeral storage size (e.g. min is 1Gb)
  • Permanent storage size (e.g. min is 1Gb)
  • Press INSTALL, and enter the following additional details in the modal dialog:
    • Name for your MySQL Deployment (e.g. mysql)
    • Select your target Space. Should have the last accessed/created Space pre-selected.
    • Press INSTALL again

Wait a few seconds for the deployment to get started. Confirm that the container running the MySQL database server is deployed, by checking the status Running (green). You can also check the logs by clicking on the Log tab.

Click on the tab Settings > Mounts and confirm that a volume mount was set up to mount the MySQL data folder. This is a very important aspect to consider, as is allow the container running MySQL server to be shutdown and restarted without lost of data. If only ephemeral storage is used, this will no longer be true — i.e. the data would have been lost when/if the container is shutdown (unless it had been backed up before hand).

Next, we want to create some databases where to store application data. Click on the Manage > Databases tab. Add a couple of databases that will be used later by the apps deployed in this tutorial. You can create has many databases as desired provided that there is enough disk space.

  • Add a database called sso – to be used by the SSO Gateway you will install next..
  • And another database one called superheros — for your application data.

MySql Install

Click also on tab Manage > Users, and confirm that a user root already exists. Feel free to add additional users, if you so want.

Connecting to MySQL using Connectors

In order for applications to connect to the MySQL server you just deployed, they need to be configured with access coordinates and credentials — i.e. URL with IP or DNS hostname and port, the selected database name, and username/password credentials. This is done by setting the appropriate environment variables of the apps with this information. While Kubernetes gives you basic mechanism to do this, such as environment variable settings, ConfigMaps, and Secrets, Cloud Manager provides additional abstractions & mechanisms to further simplify this task. Namely, Connectors and Bindings.

  • A Connector is a named set of key—value pairs defined as JSON object with containing access information. In the case at hand, you should create two Connectors for the MySQL server, to allow apps connect to the two databases we just created.

Click on the Environment > Connectors > Wizard tab, and add two Connectors. Select a database for each, and with root user access. Let the Cloud Manager set the name of the connector automatically – which ends up being database/username. Click on the Advanced radio button, and confirm that the Connector JSON expands as show below (actual IP address and password will be different).

{"name":"sso","username":"root","password":"Xhv5eFRBGEvz","host":"10.245.112.194","port":"3306",
"uri":"mysql://root:Xhv5eFRBGEvz@10.245.112.194/sso?verifyServerCertificate=false&autoReconnect=true&autoReconnectForPools=true&maxReconnects=100&useSSL=false",
"jdbcUrl":"jdbc:mysql://10.245.112.94/sso?user=root&password=Xhv5eFRBGEvz&verifyServerCertificate=false&autoReconnect=true&autoReconnectForPools=true&maxReconnects=100&useSSL=false"}
  • A Binding is JSON-based specification that defines a set of environment variables that should be set automatically for a deployment. The Binding defines a selector (string) that is matched against all Connectors defined in a Space. Once a match is found, the JSON specification is evaluated to resolve the values of the environment variables. A Binding can only be bound to a single Connector (or none, if no match if found), but multiple bindings can connect to the same Connector.

A key point, is that the values of the environment variables specified in the Binding JSON-specification can reference other variables with syntax ${VAR_NAME}. These variable references are resolved from the bound Connector. For example, a Java application with a Binding bound to a MySQL defined Connector can reference a variable named jdbcUrl to get the value of the connection URL string expressed with the JDBC syntax.

Additionally, when a deployment is defined to be implemented in a certain stack, CloudManager use some pre-knowledge about common practices and conventions to infer what the initial settings for a Binding should be. This allow to automate most of the configuration. For example, a binding in a Java/SpringBoot application bound to a connector for a relational database such MySql will have the properites spring.database.* configured automatically.

Next sections, show several examples of this BindingConnector mechanism working in practice.

Deploying a SSO Gateway

A popular and recommended approach used in modern software application and systems development is to rely on backing services to provide common and reusable functionally – the so called micro-services or cloud-native approach. While this idea was initially pushed forward mostly a way to separate stateful from stateless components, it is nevertheless also motivated from the benefits and economy of reuse. This allows applications to focus on the specifics of their use-case, rather than generic middleware issues – such as authentication, document/file storage, user notifications, social comments, payments, etc. The quest for reusability can be argued to be a key goal and best-practice in software engineering. Micro-services architectures take this to the next level – i.e. the distributed system — beyond the level of reusability already provided by the libraries packed together with an app and languages run-times.

Following the micro-services approach, you will deploy a reusable a SSO Gateway from the solution Marketplace to allow your application to support user authentication and access control available out-of-box.

Head on again to the Marketplace page, and seach for select the EInnovator SSO Gateway solution. Ignore the Helm catalogs for this tutorial. Selected the Dedicated Server plan and enter the resource settings as follow:

  • 1 single instance
  • 1Gi as amount of memory
  • Small ephemeral storage size (e.g. 1Gb)
  • Press INSTALL, and enter the following additional details in the modal dialog:
  • Name for your deployment (e.g. sso).
  • Select a hostname (e.g. same as name)
  • Select your target Space
  • Press INSTALL

Confirm that the container running the SSO Gateway starts. Use the status indicator to confirm that is Running (green). You can also check the logs by clicking on the Log tab, and the Meta-Tab tab. This allow you to see progress as the service starts-up, and troubleshoot any issue that might occur.

Click on the Routes tab, and button View App. Confirm that the Admintrator setup page for the SSO Gateway opens in a separate tab in your browser. Register the first user with your email/username and some password. This user is assigned automatically the administrator role. Feel free to take a few minutes to explore the admin console of the SSO Gateway, and then return back to this tutorial.

Back to the Cloud Manager, click on the tab Enviroment > Bindings. Notice that a set of Bindings have been automatically created when this service was deployed. Furthermore, notice that the Binding with selector mysql:sso is bound to the Connector you created early on. Don’t worry about the bindings that don’t have connectors bound yet. This service is prepared to be able to operated correctly even if those other Connectors are missing. Only the MySQL connector is strictly required.

Click on the tab Enviroment > Connectors of the SSO Gateway deployment. Confirm that a Connector was also automatically created with name default. This Connector can be used for other apps deployed in this Space to learn about the HTTP base URL to make requests to this app — by defining a Binding with selector sso. The use of this Connector is shown when we deploy a sample app.

Deploying a Sample Spring Boot App

With all the backing services in place (DB and SSO Gateway), you can not focus on the deployment of your app. We start by using the Docker image for the superheros app already available in a DockerHub public repository. Its called einnovator/einnovator-sample-superheros. In a later section, we show to create a new docker image for the app with CloudManager.

Got back to the details page of your Space, select tab Deployments > Status and click on button Deploy. Enter the following details in the Deployment Creation page:

  • Image: einnovator/einnovator-sample-superheros
  • Registry: DockerHub Public
  • Display Name: Superheros
  • Unique Name: superheros
  • Type : Application
  • Stack : Suite/Spring Boot
  • Leave default instance count (single instance)
  • Leave default Memory 1 GBi
  • Leave default ephemeral Storage in 1 GBi
  • Leave Auto-Configure checkboxes on, including: Bindings, Connectors, and EnvVars
  • Leave Auto-Start Checkbox on
  • Ignore the Advanced Settings
  • Press Deploy

Confirm that the application is deployed and status progresses to Running (green). You can also check the logs by clicking on the Log tab, and the Meta-Tab tab.

Click on the Routes tab, and button View App. Confirm that the the application opens with a list of Superheros already pre-populated. Feel free to explore the app and add new or edit existing Superheros.

Logout from the app (top-right drop down), and confirm that you are send back to the SSO Gateway login page. This happen because the app integrates with the SSO Gateway and a Binding was automatically created to connected to the default HTTP connector created for the SSO Gateway. You can confirm this in the Cloud Manager, by clicking on the tab Enviroment > Bindings. Notice that a set of Bindings have been automatically created the app was deployed. Furthermore, notice that the Binding with selector sso is bound to a Connector. (Don’t worry about the Bindings that don’t have Connectors bound yet. This app and the libraries that is uses are prepared to be able to operated correctly even if those other Connectors are missing. Only the mysql:superheros and sso Connectors are strictly required.)

Head back to the deployment list of the Space dev, and open again the details page for the MySQL deployment. Click on the Manage > SQL tab. On the side menu, select the database superheros to see the tables created by the app — just one actually, Superhero, as this is a very simple app. Click on the table name to see the data. Enter some SQL queries to explore the schema and data. You can also do the same for the database sso.

Deploying Other Marketplace Services

As you could confirm from the Binding list of the deployed app, some of the Bindings where not connected. Specifically, the Notifications Hub, Document Store, Social Hub, and Payment Gateway were missing. This are services that provide additional integration functionality for the app. For example, Socal Hub provides an easy way to attach comments/discussions to each Superhero details page. We leave the detailed discussion on how to leverage this services for another tutorials, and the reference documentation.

Creating a DNS (Sub-)Domain (Optional)

More often than not, you want your apps and some services to be available to the world via a public URL. This is very easy to setup with the Cloud Manager by creating a Domain. From the top-right toolbar press Domains button, to navigate to the Domains listing page. Press Add Domain.

Select a name for your sub-domain Name which should be unique (e.g. your username), and one of the pre-available domains (nativex.cloud, or einnovator.cloud). Save. This will be the domain name used by the deployment run in this tutorial. For example, if the selected (sub-)domain is {username}.nativex.cloud, then an application deployed with this (sub-)domain will be reachable with a URL like http://myapp.{username}.nativex.cloud. Leave the SSL/TLS options off for now.

You can also create Domains that reference “real” DNS domains you own. In this case, enter the domain name, and specify as parent Domain (DNS Root). Using your own domain require that you verify the domain, as explained in the Cloud Manager UI. In this tutorial, we will use the more straightforward approach of creating (sub-)Domains with a provided parent domain.

Building and Deploying a new App Version

Modern software development involves a continuous strife to improve functionality and UI/UX (e.g to fix reported bugs, and/or accommodate new functionality). This leads to the common practice of continous integration/delivery (CI/CD), where new versions of an app need to be rebuild, tested, and deployed frequently. Cloud Manager provides a convenient UI/UX to perform this, in integration with Tekton — a Kubernetes extension for CI/CD pipelines. The goal is to be able to configure a GIT repository for source-code, a target Docker image repository in some registry, select builder task or method, only once, and have Cloud Manager at a press of a click orchestrate Tekton to automatically pull the source code, build the docker image in the Kubernetes cluster, and push to the target image registry.

VCS and Registry Setup

To setup a CI/CD pipeline for your app you need to do a couple of preliminary steps:

  • Define a VCS (Version Control System) with the coordinates/credentials to pull GIT repositories.
    • This is required only to pull the source code from a private repositories.
    • Several credentials types are supported, including: username/token, or usename/password, or JSON token.
    • You can reuse the same VCS setting for all repositories owned by the same account/organization.
    • For example, if your repository is hosted in GitHub you need to define GitHub as VCS configured with your credentials.
    • A wizard is available to configure easily for some of the most popular hosted GIT providers (GitHub, BitBucket, GitLab, GCP, etc.)
  • Define a (docker image) Registry with the coordinates/credentials to push built docker images
    • This is required because registries usually require proper authentication to push new images (in both private and public repositories)
    • As with the VCS, several credentials types are supported
    • You can reuse the same Registry settings for all your apps, as long as they are pushing to the same registry
    • For example, if your repository is hosted in DockerHub you need to define DockerHub as a Registry with your credentials.
    • A wizard is available to configure easily some of the most popular hosted Registry providers (DockerHub, GitHub, GitLab, GCP, etc.)

Image below, show how to configure GitHub as a VCS (left-hand side), and DockerHub as a Registry (right-hand side).

GitHub as VCS DockerHub as Registry

Deployment CI/CD Setup

With the VCS and Registry setup in place, you can configure the superheros deployment builds in the CI/CD > Settings. Add a repository by entering the URL and selecting the VCS. If the repository is public, you can use the generic GIT VCS. If you want o build the superheros app without any changes, you can enter directly the URL https://github.com/einnovator/einnovator-sample-superheros.git. Select the master branch (default). If you want to make changes to the project, you can fork the project and enter you own repository URL.

Next, enter the qualified name of the docker image where you want the built images to be pushed. For example, myusername/superheros if you are using DockerHub. Select also the registry that you just created. Go to the console of the Docker registry you are using and pre-create this new repository to push images.

Finally, select the image builder — jib-maven — and all is setup. Press build to start building a new Docker image using a TaskRun running in temporarily created Pod. You can keep track of progress of the status of the task by pressing refresh on the list of TaskRuns. When status is completed (green), mean that the image was pushed. Open the UI of the target registry, and confirm that the image was pushed to the selected image repository. You can also check the logs of the working pod, to check progress and/or to troubleshoot issues.

Given that you just build a new image, you likely will want to use it. Update the deployment image in tab Settings > Options to the name of the image you just built and pushed. Save the changes. Next, restart the app. Confirm that a new Pod is created and is made to replace the current one. If you have made any changes to the app in our your source repository, open the app and confirm that those changes are reflected in the new pod created for the superheros deployment.

Although there was a few steps involved the first time, now you are all done. Next time you want to update the app, you simply have to push the code to the GIT repository, click build, wait a few minutes, and click restart to deploy the app version. As promised in the sub-title of this tutorial, Literally two clicks to build and redeploy and new version of your apps.

Learning More

Comments and Discussion

Content