Sunday, April 16, 2017
This section provides the steps needed to run the Spring Boot micro service as a Docker container inside Kubernetes.

  • Copy the MyFirstApp-0.0.1-SNAPSHOT.jar built in the previous section to another folder say C:\MyFirstApp.
  • Let us now create a Docker container using this standalone jar. We need to introduce the Docker file. Create a file with name Dockerfile in C:\MyFirstApp and add the following lines. 
FROM java:8
ADD MyFirstApp-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

  • Dockerfile and the MyFirstApp-0.0.1-SNAPSHOT.jar should be under the same folder.
Create Dockerfile
  • Understanding the elements of a basic Dockerfile.
  1. FROM specifies the base image on which container is built. In this case we use java:8 which uses Java container as both the build and runtime environment.
  2. ADD element copies the standalone Jar to app.jar.
  3. ENTRYPOINT specifies a command that will be executed when the container starts. In this case “java –jar app.jar”.
    Note from Kubernetes:
    When using a single VM of Kubernetes, it’s really handy to reuse the minikube’s built-in Docker daemon; as this means you don’t have to build a docker registry on your host machine and push the image into it - you can just build inside the same docker daemon as minikube which speeds up local experiments. Just make sure you tag your Docker image with something other than ‘latest’ and use that tag while you pull the image. Otherwise, if you do not specify version of your image, it will be assumed as :latest, with pull image policy of Always correspondingly, which may eventually result in ErrImagePull as you may not have any versions of your Docker image out there in the default docker registry (usually DockerHub) yet.

    • To start Kubernetes cluster use “minikube start”. This should start a local Kubernetes cluster on your laptop. You can see a minikube VM entry added in Oracle VM Virtual Box Manager.
    Oracle VM Virtual Box - minikube instance

    • Once you start minikube the console would look like this. Now we are ready to deploy applications on kubernetes.
    minikube start
    • Get the minikube IP using the command "minikube ip". We will run the containerized app on this IP.
    minikube IP 
    •  Run “minikube docker-env” to get the environment of built-in docker daemon.
    minikube docker-env
    • Run the last command displayed above to configure the shell for the docker environment.
    Set the docker environment
    • Verify by running “docker ps” command. You should see several kubernetes related containers already running.
    docker ps listing
    • Go to the folder where we copied the Spring Boot standalone Jar. We already have the Dockerfile here. Run the command "docker build –t myfirstapp:v1 ." to build the docker image. It is important to specify the version tag when working with Kubernetes environment. This command should pull the java libraries, add the Spring Boot application, set the entry point and build the container for us.

    Build docker image
    • Verify if the container is listed by running the "docker images" command. We will see an entry for the myfirstapp container.
    docker images listing
    • Now it is time to start our container in kubernetes. We will leverage kubectl to run this container.
    kubectl run myfirstapp –image=myfirstapp:v1 –port=8080
    

    kubectl run

    • Launch the minikube dashboard and verify if the application is created. Run the command “minikube dashboard” this should launch a browser and display the dashboard. You can see the app running in dashboard.
    minikube dashboard launch
    Kubernetes dashboard
    • Some useful commands. Use “kubectl get pods” to get the list of pods in the cluster. Use “kubectl get services” to get list of services running in the cluster.
    kubectl get pods
    kubectl get services
    • Next step is to expose this application for external access as a service.  Use the command “kubectl expose deployment myfirstapp –type=NodePort”.
    kubectl expose service

    • Run the “kubectl get services” command again to see if myfirstapp is listed.
    kuebctl get services listing exposed service
    • Verify if the application works. Using the browser. Type the URL http://192.168.99.103:31608/sayhello to invoke the API.  (or) Run the command “minkube service myfirstapp”. This should automatically launch the browser. Append the URL sayhello to get the message.
    minikube service myfirstapp
    Launch myfirstapp API from kubernetes IP

    Now we have successfully deployed and run a Spring Boot application as a container on Kubernetes.
    This section provides a quick introduction on how to develop a simple micro service which exposes a REST API using Spring Boot.

    The intent is to do a simple “/sayhello” API which returns “Hello” as the output.

    • Open the Spring Tool Suite (STS) and click on Spring Starter Project.
    Create a Spring Starter Project

    • Fill in the application details. For this example we would use Java 8 and Maven as the build system.
    Spring Starter Project application details


    • Since we are exposing APIs from this application enable Web Services under Web. Refer the snapshot below.
    Spring Starter Project Enable Web Services
    • Finish the application wizard and you would see the Spring project created and ready for use in Spring Tool Suite IDE. Under Maven dependencies all the dependent jars are already loaded. Also notice that pom.xml is created.
    Spring Starter Project Application

    • Now let us understand the top level class.
    package com.sourcetricks;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MyFirstAppApplication {
    
       public static void main(String[] args) {
         SpringApplication.run(MyFirstAppApplication.class, args);
       }
    }
    

    @SpringBootApplication is a convenience annotation. The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes if you are familiar with Spring annotations.

    Otherwise we have one line of code in main program which launches the application.

    • Now let us introduce a new class HelloController which exposes the /sayhello API. This is achieved using @RestController and @RequestMapping annotations as shown below.

    package com.sourcetricks;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        @RequestMapping("/sayhello")
        public String hello() {
          return "Hello";
        }
    }
    


    • Now we can run the project as a Java application in the STS IDE and we should start to see the embedded tomcat coming up on port 8080.

    2017-04-16 07:27:43.657  INFO 17584 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    2017-04-16 07:27:43.790  INFO 17584 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
    2017-04-16 07:27:43.799  INFO 17584 --- [           main] com.sourcetricks.MyFirstAppApplication   : Started MyFirstAppApplication in 7.816 seconds (JVM running for 10.038)
    


    • Open a browser and invoke the /sayhello API we introduced.
    Spring Boot Application - Launch Web Service
    • Next step is to package this application into a standalone application using Maven. If you notice the generated pom.xml file you will see the necessary build plugins already added since we selected Maven as the build system during project creation.
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
    
     <groupId>com.sourcetricks</groupId>
     <artifactId>MyFirstApp</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>jar</packaging>
    
     <name>MyFirstApp</name>
     <description>This is my first Spring Boot Web Service</description>
    
     <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.2.RELEASE</version>
      <relativePath/>
      <!-- lookup parent from repository -->
     </parent>
    
     <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
     </properties>
    
     <dependencies>
      <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web-services</artifactId>
      </dependency>
    
      <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
      </dependency>
     </dependencies>
    
     <build>
      <plugins>
       <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
       </plugin>
      </plugins>
     </build>
    </project>
    


    • Go to the workspace folder where the application is stored in your workspace and run “mvn package” command. This builds and packages the application. You should see “MyFirstApp-0.0.1-SNAPSHOT.jar” bundled with all dependencies.
    Maven standalone application package

    • You can test if the application starts up by running the command “java –jar MyFirstApp-0.0.1-SNAPSHOT.jar”. The same browser test can be done on the exposed API.

    Now we are ready with a simple micro service based on Spring Boot. 

    This section lists the pre-requisite tools needed to run Spring Boot, Dockers and Kubernetes. Installation steps needed for each of the tools is summarized.

    Apache Maven 

    Maven is the build tool used for this article. Maven is based on the concept of a project object model (POM) Maven can manage build, reporting and documentation from a central piece of information.
    1. Download Maven from this link https://maven.apache.org/download.cgi
    2. For Windows download the Binary ZIP archive
    3. Unzip to a folder say C:\Program Files\apache-maven-3.5.0.
    4. Update the PATH environment variable to include C:\Program Files\apache-maven-3.5.0\bin. 
    5. Verify status of installation using “mvn –v” from a command prompt.
    C:\>mvn -v
    C:\
    Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T01:09:0
    6+05:30)
    Maven home: C:\INSTALLS\apache-maven-3.5.0\bin\..
    Java version: 1.8.0_65, vendor: Oracle Corporation
    Java home: C:\Program Files\Java\jdk1.8.0_65\jre
    Default locale: en_US, platform encoding: Cp1252
    OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

    We are now good to go with Maven.

    Spring Tool Suite (STS)

    The Spring Tool Suite (STS) is an Eclipse based development environment that is customized for developing Spring applications. The Spring Tool Suite (STS) is a ready to use distribution of the latest Eclipse releases with the Spring IDE components pre-installed.

    1. Download STS from this link https://spring.io/tools/sts
    2. Unzip the downloaded file to a folder say C:\INSTALLS\sts-bundle. 
    3. The installation view of Spring Tool Suite (STS) would look as below.
    4. Launch the STS.exe and verify if the Spring Tool Suite IDE opens.
    5. We are not good to go with Spring Tool Suite (STS).
    Spring Tool Suite Installation View

    Docker

    For older Windows systems (Windows 7) the recommended approach to experiment with Docker is to use the Docker Toolbox.


    Docker Toolbox installation flow

    • The Docker Tool box installation creates the following applications on the desktop.
    1. Oracle VM Virtual Box
    2. Docker QuickStart Terminal
    3. Kitematic (Alpha)
    • Sample installation view of Docker Toolbox installation.
    Docker Toolbox installation

    For newer Windows systems (e.g. Windows 10) the Docker for Windows package can be used. The Docker for Windows install package includes everything you need to run Docker on a Windows system.

    For rest of this article Docker Toolbox based installation would be used as reference.

    Kubernetes

    Minikube is a tool that makes it easy to run Kubernetes locally. Minikube runs a single-node Kubernetes cluster inside a VM on your laptop.
    • Download the minikube-windows-amd64.exe file from this link https://github.com/kubernetes/minikube 
    • Rename minikube-windows-amd64.exe to minikube.exe.
    • Add minikube.exe to Windows path variable.
    To deploy and manage applications on Kubernetes we will need to use the Kubernetes command-line tool, kubectl. It lets you inspect your cluster resources, create, delete, and update components.
    Note: In the link v1.4.0 is the VERSION tag. If the above link is not working try this command to download the stable release of kubectl.

    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/windows/amd64/kubectl.exe
    Now we have the required tools to experiment and play around with Kubernetes, Docker containers and Spring boot applications.

    This page provides a quick reference on the steps needed to run a Spring Boot application as a Docker container inside Kubernetes on Windows. This would be ready reference for anyone wanting to experiment with micro services architecture.

    How to run a Spring Boot application as a Docker container inside Kubernetes on Windows - Introduction

    This section provides a quick introduction to Spring Boot, Dockers and Kubernetes.

    SpringBoot
    Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.  Spring Boot is a rapid application development platform. It uses various components of Spring, but has additional elements like the ability to package your application as a runnable jar, which includes an embedded tomcat (or jetty) server.


    Dockers
    Docker is an open platform for developing, shipping, and running applications. Docker provides the ability to package and run an application in a loosely isolated environment called a container. Container based virtualization uses the kernel on host’s operating system to run multiple guest instances. Each container has its own root file system, processes, memory, devices and network ports.


    Kubernetes

    Kubernetes is an open-source system for automating deployment, scaling and management of containerized applications across a cluster of nodes. Kubernetes is a powerful system, developed by Google, for managing containerized applications in a clustered environment. It aims to provide better ways of managing related, distributed components across varied infrastructure.


    Wednesday, February 4, 2015
    Scala Traits defines object types by providing signature of the supported methods. This tutorial provides a quick introduction to Scala Traits.

    Some key points on Scala Traits.
    1. Scala Traits are like interfaces in Java. 
    2. Scala Traits can have default implementations for certain methods unlike Java interfaces. 
    3. Scala Traits don't have any constructor parameters.
    4. Scala class inherits only one super class but supports mixing multiple traits.
    Let us look into a simple example to understand Scala Traits. Scala Traits are defined using the keyword trait and looks like a class definition. In this example we define a trait called Vehicle which can have both abstract methods and concrete methods.

    trait Vehicle {
      // Abstract methods
      def make() : String
      def speed() : Int
      // Concrete methods
      def specs() = { 
        println(make)
        println(speed)
      }
    }
    

    Let us write a class which extends the trait Vehicle. Concrete implementation needs to be provided only for the traits abstract methods.

    class Car extends Vehicle {
      def make() : String = { "Ford" }
      def speed() : Int = { 150 }
    }
    
    object ScalaTraitsTest {
      def main(args:Array[String]) {
        val c = new Car
        c.specs
      }
    }
    

    This program produces the following output.

    Ford
    150
    

    Scala Traits and Diamond Problem

    For C++ programmers whenever topic of multiple inheritance is discussed the focus is on the topic of diamond problem. Here classes Derived1 and Derived2 inherit from Base and Derived3 inherits from both Derived1 and Derived2. If both Derived1 and Derived2 override a method in Base there is ambiguity in Derived3 on which implementation should be inherited. In C++ developers need to override each conflicted method at the bottom of the diamond to resolve the ambiguity.

    Diamond Problem with Multiple Inheritance
    Java doesn't support multiple inheritance prior to Java 8 and hence avoid the diamond problem. But in Java 8 with the introduction of default methods on interfaces Java is subject to diamond problem. Again the conflicted method needs to be implemented at the bottom of diamond to resolve ambiguity.

    Scala provide a simple solution to resolve the diamond problem by considering the order in which Traits are inherited. The implementation in the super type that is furthest to the right is considered. If the class/ trait inheriting provides a overridden implementation then this is considered.

    Let us analyze Scala solution to Diamond problem with an example.
    trait Base {
      def print
    }
    
    trait Derived1 extends Base {
      override def print() = { println("I am Derived1") }
    }
    
    trait Derived2 extends Base {
      override def print() = { println("I am Derived2") }
    }
    
    class Derived3 extends Derived1 with Derived2 {
    }
    
    object DiamondTest {
      def main(args:Array[String]) {
        val d = new Derived3
        d.print
      }
    }
    
    Here the super type Derived2 is farthest to the right and produces the following output.
    I am Derived2
    
    If the clsas Derived3 has its own implementation for the method as below.
    class Derived3 extends Derived1 with Derived2 {
       override def print() = { println("I am Derived3") }
    }
    
    Output is.
    I am Derived3
    

    Proceed to read other Scala Tutorials.

    Contact Form

    Name

    Email *

    Message *

    Back to Top