Spring Application Deployed with Kubernetes
Step by step building an application using Spring Boot and deployed via Docker on Kubernetes with Helm
full course- Setup: IDE and New Project
- Create the Data Repository
- Building a Service Layer
- Create a REST Controller
- Logging, Tracing and Error Handling
- Documentation and Code Coverage
- Database as a Service
- Containerize the Service With Docker
- Docker Registry
- Automated Build Pipeline
- Helm for Deployment
- Setting up a Kubernetes Cluster
- Automating Deployment (for CICD)
- System Design
- Messaging and Event Driven Design
- Web UI with React
- Containerizing our UI
- UI Build Pipeline
- Put the UI in to Helm
- Creating an Ingress in Kubernetes
- Simplify Deployment
- Conclusion and Review
Now we’re going to take our functional service and containerize it. This will allow us to control the deployment environment that our java spring boot service runs in as well as provide some additional security and isolation from application updates that can break our application.
Containerization Overview
If you’ve spent any amount of time in software development you may be familiar with a common scenario: you have an application that ‘runs’ in production, but it hasn’t been touched in months (or years!). An audit by the operations or security team has determined that an operation system or library is out of date and needs to be upgraded. Of course, they do the upgrade without notifying the application developers and the update somehow breaks the functionality of the application. Now its your responsibility to update your application and since its a key component it is now a high priority. However, the developer that actually wrote the application is long gone and you have no idea what needs to be done to get it back up and running. Part of the reason that this happens is that your application is not just the java code, but is actually the whole stack that the software runs on but that stack is ‘owned’ by different parts of the organization.
Since these parts are easily upgraded and ownership is distributed, we can quickly encounter issues. But this is necessary because security is a priority for any application. Operations refers to the ‘surface area’ of security and in this application there is A LOT of surface area. There’s the server that is deployed, the operating system that is running on that hardware, all of the libraries either installed with the operating system or afterward, the JDK as well as the application that was written. We need a solution that allows us to control the stack (for our functionality purposes) but also secure it (for our security needs).
Containers
Docker is a solution that allows development teams to ‘own the stack’ but also provides a high level of security in that containers can be made inaccessible once they are deployed. Additionally, if we’re using a microservice architecture we can easily replace one container with another (possibly on an entirely different stack) so we can have a combination of secure ‘legacy’ services that do their job and are not prioritized for updates as well as new services or upgraded services. We don’t have to do sweeping OS or JDK (or other library) updates across our organization anymore because the containers lock out any vulnerabilities from being exposed. Additionally, if we get to a point where a service is so far out of date that it would take more time analyzing it and refactoring it than it would be to drop it and write it from scratch we can do that too… but we can do it on our timeline.
Additionally, each container (containing the entire stack that is needed to run the application) can be versioned and managed in an artifact repository similarly to maven.
These containers can be deployed in a container management system and the best way to secure them is to not allow access to them at all (via SSH, for example). If we’re never going to be able to log into them, then the only way we’re going to be able to deal with a container application that is failing is to spin up a new one and tear down the failing one. This means that our applications need to be stateless. They also need to expose all of their logs somehow (we’ll get into that later). These may be major concerns for your application, so make sure that containerized applications fit your need.
This is just a really high level overview of containers and containerization. There is much better, more detailed documentation out there and you should really familiarize yourself with the tools you’ll be using.
Containerizing our Service
All of these features seem great and thankfully taking advantage of them is very easy.
Install Docker
Install the docker tool using the package manager appropriate for your operating system.
Create a Dockerfile
A dockerfile is going to specify the stack that is going to be created in the container. All we need is an OS and JDK so our dockerfile is very simple
Create a Dockerfile
in the root of your application.
FROM openjdk:11.0.6-jdk-slim-buster
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
We can now use docker to build the image
docker build -t medium/medium-customer
We should see something like this in the logs:
Successfully built 61c5fd6e8cc4
Successfully tagged medium/medium-customer:latest
and we can confirm with docker (the image was build to our local docker repo, just like a mvn install
would build a jar to our .m2 artifact repository)
docker image list
should return
medium/medium-customer latest 7f9b379551d8 50 years ago 260MB
Build and Commit
git checkout -b docker
mvn clean install
git add .
git commit -m "dockerfile"
git push --set-upstream origin jib
git checkout master
git merge jib
git push
0 comments on “Containerize the Service With Docker”Add yours →