In Part 1 we built a docker container for a basic Spring Boot application. In this post we look at some of the basic elements of kubernetes deployments and then see how we can run our application in a kubernetes cluster.

Environment Setup

In this guide I won’t focus too much on getting your local environment setup because there are already so many helpful resources out there. During this series, I use docker desktop with kubernetes support enabled. I’ve found it to be the easiest way to get started with kubernetes quickly on a local machine. Here are a few helpful links to get your local environment configured:

Pods

Pods are the most basic unit in a kubernetes cluster. They are capable of running multiple containers, but typically we see a one container per Pod philosophy. This makes it much easier to manage and conceptualize because we can think of them as a layer around our containers that allows kubernetes to manage a container. Kubernetes also provides networking and volume storage capabilities to Pods. The kubernetes docs have an in-depth overview of Pods.

Running a Spring Boot Application in a Pod

Now that we know a little about Pods, this next step is to get the docker image we built last time running in a Pod (if you need to rebuild the image you can do that with ./gradlew bootBuildImage). In order to run the application, run the following command using the kubernetes command line tool - kubectl:

 kubectl run demo --image=docker.io/library/springbooktk8s:0.0.1-SNAPSHOT --port=8080

With this command kubernetes creates a Pod named demo which can be used to reference the Pod later. The image flag instructs kubernetes to run the image built for the Spring Boot application as a container in the Pod. The port option allows for other nodes within the cluster to be able to access the container on the specified port.

To check that status of the Pod, run the command kubectl get pods (this returns information about any running Pods).

NAME              READY   STATUS    RESTARTS   AGE
demo              1/1     Running   0          4s

When running the cli command, kubernetes is creating a definition of a Pod for us. To take a look at that definition we can run the previous command but as a dry run and output as yaml:

kubectl run demo --image=docker.io/library/springbooktk8s:0.0.1-SNAPSHOT --dry-run=client -o yaml

Which should generate output that looks similar to this:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: demo
  name: demo
spec:
  containers:
  - image: docker.io/library/springbooktk8s:0.0.1-SNAPSHOT
    name: demo
    ports:
    - containerPort: 8080
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

There’s a few field to note in this yaml:

  • apiVersion refers to the version of the kubernetes api
  • kind determines what type of kubernetes resource being defined, in this case a Pod
  • metadata.name is a mandatory field so that kubernetes has a way of identifying the resource
  • spec.containers defines the containers running in the Pod. The defintion here is a combination of defautls and options provided earlier to kubectl run For now we can ignore the rest of the fields, we go into details where necessary on those.

Accessing the Application

At this point, we might be tempted to point the browser to http://localhost:8080/actuator/health to see the running application’s health. By default, Pods and their containers are only be accessible within the cluster. To access the application, the request needs to be made within the cluster. To do this, first find the Pod’s IP Address by running:

kubect describe pod demo

In this output find a section that looks like:

Name:         demo
Namespace:    default
Priority:     0
Node:         docker-desktop/192.168.65.4
Start Time:   Sat, 10 Apr 2021 12:25:09 -0400
Labels:       run=demo
Annotations:  <none>
Status:       Running
IP:           10.1.0.18

For this example, the IP Address of the Pod’s Cluster IP Address is 10.1.0.18. Next, run a busybox container that a shell can be access and wget can be run from using:

kubectl run -i --tty --rm debug --image=busybox --restart=Never --

Once the shell prompt is available, make a request to the container using:

wget -qO- http://10.1.0.18:8080/actuator/health

And there should be an output similar to:

{"status":"UP","groups":["liveness","readiness"]}

And now we have access the application from within the cluster. When we’re done, type exit and the buxybox container and its Pod is shutdown. Containers such as this are useful when debugging containers running in kubernetes.

Recap

In this post, we have run a Docker image for a Spring Boot Application in a kubernetes Pod. We then saw what the Pod definition looked like. Finally, we ran a busybox container in a different Pod that could be used to access the application through the actuator. As always, the sample code can be found on github. Thanks for reading!

Continue on to Part 3

Other Useful Commands

Here are some other useful kubectl commands to try out:

  • kubectl logs demo to see the most recent logs
  • kubectl logs -f demo to follow the logs
  • kubectl delete pod demo to delete the Pod
  • kubectl get pod demo to see the status of the Pod
  • kubectl describe pod demo to see a detailed description of the Pod
  • kubectl get pod demo -o yaml|json to see the full yaml or json definition of the Pod