DEV Community

Cover image for Running springboot app on kubernetes with private repository
Arvind Kumar GS
Arvind Kumar GS

Posted on • Edited on

Running springboot app on kubernetes with private repository

Instructions to build a single node cluster on Minikube with a private repository running on http. It runs a spring boot application container. This container is built from an image pulled from the private repository. Minikube will by default run in a virtual machine. So to make the registry available to the VM in minikube you will need to configure it to use the registry. The flow diagram is as follows:
Flow diagram

Pre-requisites

  • jdk11
  • docker
  • minikube
  • kubectl

Setup

Start Docker Daemon

  • Get IP address or url of where your registry runs. IP address can be obtained from cmd ip addr

  • Replace IP in below command with the actual ip or url.

$ echo '{"insecure-registries": ["IP:5000"]}' > /etc/docker/daemon.json 
  • Start docker daemon
$ sudo systemctl start docker 
  • Verify insecure registry
$ docker info -f '{{json .RegistryConfig.IndexConfigs}}' 

This should list as:
{"IP:5000":{"Name":"IP:5000","Mirrors":[],"Secure":false,"Official":false},"docker.io":{"Name":"docker.io","Mirrors":[],"Secure":true,"Official":true}}

Start Minikube

  • To start minikube configured to use the private registry, run below command. NOTE: Replace DRIVER with correct driver which is one of: [virtualbox, vmwarefusion, kvm2, kvm, hyperkit]
$ minikube start --vm-driver=DRIVER --insecure-registry="IP:5000" 

Start private registry

  • If running on local start registry as:
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2 

Getting Started

Create a basic Spring Boot application:

$ curl https://start.spring.io/starter.tgz -d dependencies=webflux -d dependencies=actuator | tar -xzvf - 

Add an endpoint (src/main/java/com/example/demo/Home.java):

package com.example.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class Home { @GetMapping("/") public String home() { return "Hello World"; } } 

Containerize (Dockerfile):

FROM openjdk:8-jdk-alpine as build WORKDIR /workspace/app COPY target/*.jar app.jar RUN mkdir target && cd target && jar -xf ../*.jar FROM openjdk:8-jdk-alpine VOLUME /tmp ARG DEPENDENCY=/workspace/app/target COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.demo.DemoApplication"] 

Run and test...

$ ./mvnw package $ docker build -t IP:5000/apps/demo . $ docker run -p 8080:8080 IP:5000/apps/demo $ curl localhost:8080 Hello World 

Stash the image to our private repository:

$ docker push IP:5000/apps/demo 

Deploy to Kubernetes

Create a basic manifest:

$ kubectl create deployment demo --image=IP:5000/apps/demo --dry-run -o=yaml > deployment.yaml $ echo --- >> deployment.yaml $ kubectl create service nodeport demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml 

Apply it:

$ kubectl apply -f deployment.yaml 

Test

Check if deployment is up

$ kubectl get deployments.app demo 

Next check if service is running

$ kubectl get service demo 

NOTE: Make a note of the port. For example if port is mentioned as 8080:32614, then copy 32614. This is the port on which the service is available

Consume service

Get IP

$ kubectl get endpoints kubernetes 

Make a note of the IP, ignore the port number. Example - if endpoint: '192.168.39.138:8443', then IP: 192.168.39.138

Get Port

$ kubectl get service demo 

Port is the second part of ':' delimiter. Example - if PORT is '8080:32614/TCP', then our port is 32614

Call springboot app, substituting IP below with ip obtained above and PORT with port obtained above

$ curl IP:PORT Hello World 

Alternatives

As a corollary, if you are running a test or doing development and don't want to push your image to a private repository or dockerhub, then you can reuse Minikube's built-in docker daemon. So you can build images inside the same docker daemon as Minikube, which speeds up local experiments.

For this, run last line from

$ minikube docker-env 

You can now use Docker at the command line of your host Mac/Linux machine to communicate with the Docker daemon inside the Minikube VM:

$ docker ps 

Next you need add following line to deployments.yaml after name of image @line:23

imagePullPolicy: Never 

More info here

The instructions and code are available at github


References
https://github.com/dsyer/kubernetes-intro
https://www.howtoforge.com/learning-kubernetes-locally-via-minikube-on-linux-manjaro-archlinux
Image credit: https://blog.nebrass.fr/playing-with-spring-boot-on-kubernetes/

Top comments (0)