Part II — Spring Boot App Development With Skaffold, Kustomize, and Jib

Mario Scalas
Oct 17, 2020 · 5 min read

This is the second part of a series of articles where I describe my development workflow and CI/CD practices. If you are interested in knowing the motivations, take a look at the introductory article.

In this article, I will describe how I develop a Spring Boot app (or microservice) using Skaffold and Google Jib. This article assumes familiarity with Spring, Maven, Docker, and Kubernetes: I’m not going to explain them here since the focus is the development workflow, not the technology itself.

The App

The app that we are going to use in these examples is quite a simple: it exposes a GET HTTP endpoint that returns a “Hello World” salute.

Since we want to show the deployment process and not provide a complex application, this will suffice our goal.

Why using Skaffold, Kustomize and Jib

We can leverage the same tools for both local development and CI/CD workflows. Let’s take a look at these tools.

Skaffold is a tool, developed by Google, that

[…] handles the workflow for building, pushing and deploying your application, allowing you to focus on what matters most: writing code.

In practice, you have your favourite IDE, you write your code and deploy it to cluster.

You usually run Skaffold in background while coding, either in dev or debug mode, so that build and deployment happens transparently to you.

Skaffold uses a descriptor file called skaffold.yaml where you describe your service, build actions and related metadata. It supports several build backends (e.g., local Docker for Desktop or remote Cloud Build) and also different backends for generating the Kubernetes YAML descriptors that are then applied to the target cluster (like Helm or Kustomize).

I’m used to Kustomize, so by skaffold.yaml is configured accordingly. And, by the way, it also included in Kubectl 1.14.x onwards :)

In Kubernetes world there are several tools that helps DevOps to deploy software applications consistently, you may have heard of Helm . I find the use of placeholders in my YAML descriptors to be … disturbing. With Kustomize, instead, you provide a base skeleton and then patches for them: in this way we can provide a base deployment and then only describe the differences for different environments (e.g., the amount of replicas).

Google provides extensions for some popular IDEs like Visual Studio Code and IntelliJ Idea, so you can benefit a bit of ease to use. Anyway, who’s scared of using the command line these days? :)

In order to build Docker images, we could either write our own Dockerfile or use Jib, a tool (developed by Google) for containerizing Java applications, which is good for any Spring Boot app.

I use Jib because it helps build images in a way that is:

* Fast — Deploy your changes fast. Jib separates your application into multiple layers, splitting dependencies from classes. Now you don’t have to wait for Docker to rebuild your entire Java application — just deploy the layers that changed.

* Reproducible — Rebuilding your container image with the same contents always generates the same image. Never trigger an unnecessary update again.

* Daemonless — Reduce your CLI dependencies. Build your Docker image from within Maven or Gradle and push to any registry of your choice. No more writing Dockerfiles and calling docker build/push.

Additionally, Jibs enforces some good practices, like distroless containers, that reduce the attack surface .

For the purpose of using Jib and Skaffold together, we just have to add the Jib Maven plugin to our pom.xml and we are done and update the skaffold.yaml file.

Note that Spring devs are actively supporting Cloud Native Buildpacks from Spring Boot 2.3.x, so you may want to use their support instead of using Jib but since Skaffold provides out-of-the-box support for Jib I will stick with it for … historical reasons (well, yes, I’m too lazy to change things unless I gain some real advantages :))

The Git repository structure

The sample application code is available on GitHub and it has a familiar layout, being generating with Spring Initialzr . Then there are

Project source code layout
  • skaffold.yaml — the Skaffold deployment descriptor
  • kustomization/ — contains the YAML descriptors organized by profile

In skaffold.yaml we configure the usage of Jib for building the image and two profiles:

  • local — which will be automatically activate if you use Docker for Desktop
  • aws — which must we are going to use in our CI/CD pipeline:

Note that there is no Docker registry prefix since we are going to use environment variables to set them at build time when building on AWS with CodeBuild.

All Kubernetes descriptors are provided in kustomization/base/ directory, where they are used by default. I like to keep YAML descriptors separated so I have

  • app.deployment.yaml — the deployment resource for this application (which image, how many replicas, environment variables, …)
  • app.service.yaml — the load balanced service resource that will act as entry point for our sample app;
  • app.cm.yaml — a simple configuration map that we pull configuration options from and then use in app.deployment.yaml

Being an example, the only changes we execute in aws profile are:

  1. to update the number of replicas to 2;
  2. to change the Kubernetes namespace to “hello-world-application” in order to match the one we are going to use in our dev cluster.

Note that these are just a couple of arbitrary changes to make this example less boring: take a look at Kustomize documentation in order to understand more.

Creating your own microservices

If you want to create your own microservices, I’ve written a Maven Archetype that you can use for your own convenience: nothing fancy but at least your can start without copying and pasting code around ;)

Conclusions

Well, there is nothing more to be explained here: we have our simple service to deploy to our cluster. Please familiarize with it and try to change it and see how Skaffold reacts: take a look at the README.md if you need some more practical insight about the code or need more references!

In next part we are going to take a look at how to create our infrastructure for supporting our development workflow in AWS using AWS CDK.

The Startup

Get smarter at building your thing. Join The Startup’s +724K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store