Quick Guide to Developing Microservices on Kubernetes and Docker
As Java developers we’re often really busy with large backlogs, customer issues and countless disruptions. It can be quite daunting finding the time to learn all about things like Kubernetes and its associated tools and technologies (kubectl, OpenShift, oc, Docker and Rkt and standards like CNCF and OCI). Its well worth doing if you have the time mind you! We recommend you dive into Kubernetes and see where that takes you whenever you get some spare time :).
On the fabric8 project we’ve been focused on making it easy for developers to create, build, deploy and manage microservices on top of Kubernetes for some time.
Up to now we’ve mostly focused on the end to end lifecycle of creating new microservices, then changing code through continuous delivery then having continuous improvement. Lately we’ve been focused more on the pre-git-push phase. Where you’re hacking code on your laptop and trying things out before you want to commit and push into your git repository.
Lots of Java developers are used to using application servers, creating deployment units (jars/wars), deploying them and running them in app servers using Maven. Then they can use Maven from the command line or easily inside their IDE to do most of the work.
So we figured, why not make Kubernetes look and feel like an application server to a Java developer? So you build and deploy your application from maven like you would with other maven plugins like spring-boot, tomcat, jetty, wildfly, karaf et al. Then you can get started quickly by just treating Kubernetes as a kind of application server.
Kubernetes is actually way more awesome than an application server; its more like an application cloud as:
- kubernetes can keep running multiple instances of each of your apps including automatic restarts on software or hardware failures
- automatic load balancing when invoking your apps
- each app instance is isolated as a separate process so its much easier to monitor metrics and logs
Setup your maven project
Do you have an existing maven project for your Java app? Maybe its a Spring Boot or WildFly Swarm app; or a flat classpath, fat jar? If you don’t have a maven app to hand, visit start.spring.io and create one.
Note that all the fabric8 quickstarts already have the fabric8 maven plugin enabled so you don’t need to do the above!
Now that we have enabled the fabric8 maven plugin for our project we can have some fun!
Starting and stopping a local kubernetes cluster
To develop on kubernetes you will need a kubernetes cluster; just like you need an instance of an application server to deploy your app. If someone in your organisation has provided you with a kubernetes cluster then feel free to use that; you just need to connect to it via the kubectl too.
However if you don’t have any kubernetes clusters to hand its very easy to spin up your own local cluster. Using a local kubernetes cluster is really handy for development; it lets you build your app and run it locally before you do a git commit and trigger the CI / CD pipeline.
Before you start please make sure you have the prerequisites installed for your platform (basically a recent Apache Maven distro and have a working hypervisor for your platform like xhyve, hyper-v or kvm).
Now with the fabric8-maven-plugin you just use the goal fabric8:cluster-start to spin up a local cluster:
Wait a few minutes for some stuff to download and then you’ve now got a local installation of a Kubernetes cluster running on your machine! No installation of Docker, VirtualBox or Vagrant is required!
Want to use OpenShift instead of Kubernetes? Use this command instead:
mvn fabric8:cluster-start -Dfabric8.cluster.kind=openshift
You can now use the kubectl command line to get pods and whatnot:
kubectl get pod
When you’re done and want to stop the kubernetes cluster just use fabric8:cluster-stop
you can restart it again at any time via fabric8:cluster-start
Running your app
The simplest way to run your app is viafabric8:run
This will build your app (compile code, run tests, generate the jar and package it up into an immutable docker image), generate the kubernetes manifest and deploy it then tail the log output so you can see how your app behaves. If you hit Ctrl-C it then terminates the app.
So that the fabric8:run goal works kinda like other run goals in other maven projects like spring-boot, tomcat, jetty, karaf and wildfly.
Deploy or undeploy your app
Deploying your app is a little like running fabric8:run in the background.
To deploy your app into kubernetes you use the fabric8:deploy goal
This will build your java code and run your unit tests, generate the docker image, create the kubernetes manifest and deploy them into kubernetes.
To remove our app from kubernetes just use the fabric8:undeploy goal
Once you’ve deployed your app you probably want to check its logs. So you can type:
then hit Ctrl-C to terminate tailing the log.
If you don’t want to keep tailing the log and just want to see the current log output try this:
mvn fabric8:log -Dfabric8.log.follow=false
Start and stop
If you have deployed your app you sometimes want to stop it running so that you can later on start it again. e.g. since its using up resources on your laptop or its invoking some other microservice that you wish to take offline.
mvn fabric8:stop … mvn fabric8:start
You can also use fabric8:start to scale up your app to more than one pod if you wish
mvn fabric8:start -Dfabric8.replicas=2
You can also use the kubectl command line too:
kubectl scale — replicas=2 deployment myappname
Outside of unit tests we highly recommend you try and run your apps and do all your integration and system testing inside Kubernetes. Then you are spending most of your time using a production-like environment (rather than your laptop with its different operating system, networks and storage etc). It also means you can easily deploy multiple microservices into the same namespace and test combinations of microservices easily.
To debug your app, just run the fabric8:debug goal
This will use the default Java remote debugging port of 5005. You can specify a different port if you wish
mvn fabric8:debug -Dfabric8.debug.port=8000
Once that goal is running the debug port will be open on your laptop (localhost) which then connects using port forwarding to your most recent running pod for your app.
So you can now just start a Remote debug execution in your IDE (like you do to debug remote application server instances) and you can set breakpoints and debug your pod while its inside kubernetes.
e.g. in IntelliJ here’s how you add a Run/Debug execution:
add a new Remote kind of Run/Debug configuration
give the Run/Debug configuration a title
To see this in action check out the video below.
Continuous Delivery and Releasing
Once you are ready to start releasing your code run this command:
This will import your local project into fabric8.
If your code is not already hosted in a git repository it will create a new git repository and import your code. Then it’ll show you a link to open the project in the fabric8 console so you can add a Continuous Delivery pipeline to your project to enable a Jenkins build for full CI / CD
To see all of these maven goals in action check out this short video:
local java development with kubernetes and docker using fabric8 maven plugin
So once you’ve started a cluster (cluster-start) the fabric8 maven goals are very similar to other application server based maven plugins; run, deploy/undeploy, start/stop are the main goals with log and debug pretty handy too.
Once you are familiar with those and you’ve done some development on kubernetes with the fabric8 maven plugin you might start to try out using the kubectl tool also which is handy for querying or watching the state of kubernetes, performing updates to them. e.g. to watch pods start and stop type:
kubectl get pod -w
For a live introduction to Fabric8, attend my Devoxx US talk in San Jose, California on March 21. The talk is called develop microservices faster with an open source platform based on docker, kubernetes and jenkins".