top of page

Deploying a Java based application using Docker and kubernetes using Minikube.

1. Installing Docker & Kubernetes on an Ubuntu AWS EC2 Machine:


Minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes. Launch an EC2 instance (t2-medium) with SSH and Inbound port for the application and make sure to have:

  • 2GB of free memory

  • 2 CPUs or more

  • 20GB of free disk space

  • git installed

ree

Make sure you have Docker installed on your Ubuntu machine. If not, you can install it using the following command:

sudo apt-get update
sudo apt-get install docker.io

Install kubectl: You need to have kubectl installed to interact with the Kubernetes cluster created by Minikube. You can install kubectl using the following command:

sudo snap install kubectl --classic

Install Minikube: You can install Minikube on Ubuntu using a package manager like curl or by downloading the binary. Here's how to install it using curl:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ 

Run the following command to add your user to the "docker" group:

sudo usermod -aG docker $USER

This command appends your user to the "docker" group, where $USER is your username.After adding your user to the "docker" group, you need to apply the group changes to your current session.

newgrp docker 

Now, you should be able to start Minikube with the Docker driver:

minikube start --driver=docker

This command will download and run a Docker container with the Minikube Kubernetes cluster inside.

Verify Minikube: After the Minikube cluster is up and running, you can verify its status with status command. It should display that the cluster is running.

minikube status

To see the kubectl configuration use the command:

kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/ubuntu/.minikube/ca.crt
    extensions:
    - extension:
        last-update: Sat, 21 Oct 2023 07:01:05 UTC
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: cluster_info
    server: https://192.168.49.2:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        last-update: Sat, 21 Oct 2023 07:01:05 UTC
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /home/ubuntu/.minikube/profiles/minikube/client.crt
    client-key: /home/ubuntu/.minikube/profiles/minikube/client.key

To show the cluster information:

kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To check running nodes use the following command:

kubectl get nodes
ubuntu@ip-172-31-81-209:~$ kubectl get nodes
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   25m   v1.27.4

To ssh into the Minikube VM:

minikube ssh
ubuntu@ip-172-31-81-209:~$ minikube ssh
docker@minikube:~$ 

2. Our Java Application:

├── README.md
├── kubernetes
│   ├── productcatalogue-service.yaml
│   ├── shopfront-service.yaml
│   └── stockmanager-service.yaml
├── productcatalogue
│   ├── Dockerfile
│   ├── pom.xml
│   ├── product-catalogue.yml
│   └── src                                                            
├── shopfront
│   ├── Dockerfile
│   ├── pom.xml
│   └── src
└── stockmanager
|    ├── Dockerfile
|    ├── pom.xml
|    └── src

3. Let's Install the dependencies:


a. Install maven

apt-get install maven -y

b. Set the maven home as a variable

export MAVEN_HOME=/usr/share/maven
ubuntu@ip-172-31-81-209:~ echo $MAVEN_HOME
/usr/share/maven

c. Build the image for micro-service shopfront

cd shopfront
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ ls
Dockerfile  pom.xml  src

4. Let's Build and Push the images to DockerHub for each services


a. Now run mvn clean install from inside that folder so it can build part of our microservice

mvn clean install 
mvn clean install
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/1.5.22.RELEASE/spring-boot-starter-parent-1.5.22.RELEASE.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  29.019 s
[INFO] Finished at: 2023-10-21T10:26:50Z
[INFO] ------------------------------------------------------------------------

Now if we do ls we will see <target> directory where we have shopfront-0.0.1-SNAPSHOT.jar

ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ ls
Dockerfile  pom.xml  src  target
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ 
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ cd target/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront/target$ ls
classes            generated-test-sources  maven-status                  shopfront-0.0.1-SNAPSHOT.jar.original  test-classes
generated-sources  maven-archiver          shopfront-0.0.1-SNAPSHOT.jar  surefire-reports

b. Create the docker image

docker build -t <dockerhub-username>/<image-name>:tag .
docker build -t nishant277/shopfront:latest .
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
nishant277/shopfront          latest    e71412eef061   3 minutes ago   320MB

c. Let's do the same build process for productcatalogue micro-service now

ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd productcatalogue/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ ls
Dockerfile  pom.xml  product-catalogue.yml  src
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$
mvn clean install
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ ls
Dockerfile  pom.xml  product-catalogue.yml  src  target
docker build -t nishant277/productcatalogue:latest .
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
nishant277/productcatalogue   latest    ce435c338475   6 seconds ago   291MB
nishant277/shopfront          latest    e71412eef061   9 minutes ago   320MB

d. Let's do the same build process for last micro-service stockmanager now

ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd stockmanager/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ ls
Dockerfile  pom.xml  src
mvn clean install
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ ls
Dockerfile  build  pom.xml  src  target
docker build -t nishant277/stockmanager:latest .

Now if we check we have 3 images for each services

ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED          SIZE
nishant277/stockmanager       latest    1b88249cb428   4 seconds ago    317MB
nishant277/productcatalogue   latest    ce435c338475   3 minutes ago    291MB
nishant277/shopfront          latest    e71412eef061   12 minutes ago   320MB

e. Let's push the images to the dockerhub

ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: nishant277
Password: 
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker push nishant277/stockmanager
Using default tag: latest
The push refers to repository [docker.io/nishant277/stockmanager]
d88146d4d2f1: Pushed 
1aaddf64804f: Mounted from library/openjdk 

f. Push all the respective images to the DockerHub.

ree

5. Let's deploy the services to our K8s cluster

ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd kubernetes/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$

Our manifest files for each services

ubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$ ls
productcatalogue-service.yaml  shopfront-service.yaml  stockmanager-service.yaml
ubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$ kubectl apply -f shopfront-service.yaml 
service/shopfront created
deployment.apps/shopfront created
ubuntu@ip-172-31-89-196:~/java-docker-k8s/kubernetes$ kubectl apply -f productcatalogue-service.yaml 
service/productcatalogue unchanged
deployment.apps/productcatalogue created

Let's test the application inside the cluster by doing ssh

minikube ssh
minikube ssh
docker@minikube:
ubuntu@ip-172-31-89-196:~ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          3h18m
shopfront    NodePort    10.105.228.45   <none>        8010:32683/TCP   151m

Now we will test the application inside the container

docker@minikube:~$ curl http://192.168.49.2:32683
<!DOCTYPE html>


<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->


    <title>Welcome to the Docker Java Shopfront!</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />


    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />


    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid" style="background-color: #ff203b">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Docker Java Shopfront</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Help</a></li>
            </ul>
        </div>
    </div>
</nav>


<div class="container-fluid">
    <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
                <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
            </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <h1 class="page-header">Welcome to the Docker Java Shopfront!</h1>
            <h2 class="sub-header">Please select a product!</h2>
            <div class="table-responsive">


                <table class="table table-striped" id="product-table">
                    <thead>
                    <tr>
                        <th>Product Num</th>
                        <th>SKU</th>
                        <th>Name</th>
                        <th>Description</th>
                        <th>Price £</th>
                        <th>Qty Available</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr>
                        <td>1</td>
                        <td>default</td>
                        <td>Widget</td>
                        <td>Premium ACME Widgets</td>
                        <td>1.20</td>
                        <td>999</td>
                    </tr>
                    <tr>
                        <td>2</td>
                        <td>default</td>
                        <td>Sprocket</td>
                        <td>Grade B sprockets</td>
                        <td>4.10</td>
                        <td>999</td>
                    </tr>
                    <tr>
                        <td>3</td>
                        <td>default</td>
                        <td>Anvil</td>
                        <td>Large Anvils</td>
                        <td>45.50</td>
                        <td>999</td>
                    </tr>
                    <tr>
                        <td>4</td>
                        <td>default</td>
                        <td>Cogs</td>
                        <td>Grade Y cogs</td>
                        <td>1.80</td>
                        <td>999</td>
                    </tr>
                    <tr>
                        <td>5</td>
                        <td>default</td>
                        <td>Multitool</td>
                        <td>Multitools</td>
                        <td>154.10</td>
                        <td>999</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>docker@minikube:~$ 

Test the application (local minikube)

kubectl get svc                  
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP          4h8m
productcatalogue   NodePort    10.105.98.100   <none>        8020:30139/TCP   35m
shopfront          NodePort    10.105.228.45   <none>        8010:32683/TCP   3h21m
minikube service productcatalogue
ree








 
 
 

Comments


bottom of page