INTRODUCTION
Abid Anjum
Senior Full Stack Developer Architect | Java Spring Boot Microservices | Mobile Apps Engineer Android IOS Flutter | Asp.net Core C# | BI Expert | GIS Developer
We are going to look at the features and benefits of using a Kubernetes cluster to deploy your application
PREREQUISITES
FIRST THINGS FIRST: CREATING A DOCKER IMAGE
FROM openjdk:11-jre-alpine WORKDIR /tmp COPY target/springkubedemo-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
This is a very basic Dockerfile but it will do for our example.
The first line tells us to use the 11-jre-alpine image from the openJDK repository as our base image. The second line tells the image that it should work from the /tmp directory. The third line copies the compiled JAR (which is compiled with the mvn clean install command) file from your target folder to the Docker image (you might have to rename the file depending on the name of your project).
Finally, we tell our image to use the java command as entry point, meaning that once the Docker image starts running, it has to execute that command.
You can now push this image to your favourite Docker registry, as Kubernetes will need to pull this image from the registry later. If you do not have a Docker registry, I suggest using Docker Hub. If you are using Docker Hub, you can use the following commands to build and push your application to the registry:
docker build -t DOCKER_HUB_USERNAME/APPLICATION_NAME .
docker push DOCKER_HUB_USERNAME/APPLICATION_NAME
WHERE THE MAGIC HAPPENS: DEPLOYING YOUR APPLICATION ON THE KUBERNETES CLUSTER
All Kubernetes configurations are written in YAML. The reason for this is that Kubernetes configuration files are meant to be easily readable by the human eye and the Kubernetes team decided to use YAML instead of JSON.
DEPLOYMENT
Now that the Docker image is created, we can now deploy it on the Kubernetes cluster. First we need to create a deployment configuration file. This file contains the configuration on how the application should run.
apiVersion: apps/v1
kind: Deployment
metadata:
name: springkubedemo
labels:
app: springkubedemo
spec:
replicas: 1
selector:
matchLabels:
app: springkubedemo
spec:
containers:
- name: springkubedemo
image: anjum/springkubedemo
ports:
- containerPort: 8080
There’s a lot going on here which I will be explaining step by step. The first two lines are telling which Kubernetes API version is being used and what kind of Kubernetes object is being applied. As we want to create a new Deployment, we use the Deployment object (easy, right?).
Lines 3 to 6 are just basic metadata tags so the developer knows which application (s)he is working with. This does not affect the behaviour of the application in any way.
领英推荐
Lines 7 to 21 are specifying how the container should be made and which image it has to run. This is the image that we created with the Dockerfile earlier in this post. After that, it describes the port that the container should listen to, which is 8080 in this case. The replica value specifies how many ‘instances’ (also called Pods) that should be running. If the application is expecting a lot of requests, it might be useful to declare a higher number of replicas instead of only one. Lines 13 to EOF are specifying the environment variables that the container uses. They can either be hard-coded like SPRING_PROFILES_ACTIVE or a Secret or ConfigMap can be created, which can then be used in a Deployment configuration, as in the example above.
SERVICE
The Deployment is up and running, but we need some way to access our pod from the outside world. This is where a Service comes in. A Service provides external access to a set of Pods and decides which pod should handle the request.
apiVersion: v1
kind: Service
metadata:
name: springkubedemo
spec:
type: NodePort
selector:
app: springkubedemo
ports:
- protocol: TCP
port: 8080
nodePort: 30011
The first four lines should be familiar. Instead of a Deployment, we are now declaring a Service.
There are three types of services you can declare: ClusterIP, NodePort and LoadBalancer. It is not recommended to use NodePort in a production environment because of the limited options. Instead you might want to use a LoadBalancer. Most big cloud providers can provide a LoadBalancer for you. Another option is to use an Ingress, which is a recommended and popular option. If you want to learn more about this, I suggest you consult the official Kubernetes documentation. The nodePort value can be left out if you want Kubernetes to assign a random NodePort to your service.
The selector value is meant to find the Pods with the same value as spec.selector.matchLabels from the Deployment configuration. This is how the Service is able to find our Pods.
APPLYING THE CONFIGURATION
Now that we have our YAML files, we can apply them to the cluster. You can even combine the two configurations into one file and separate them with ---. You can use this separator to prevent having too many YAML configuration files.
You can apply the configuration by using the following command:
kubectl apply -f k8s/springkubedemo-deployment.yaml
The output will be something like:
deployment.apps/springkubedemo created
service/springkubedemo created
The application is now accessible through https://IP_ADDRESS:NODE_PORT. So if you are using Minikube, the IP should be https://192.168.99.100:30080/.
CONCLUSION
There is a lot of documentation available on the internet if you want to learn more about the power of Kubernetes. Think about the options and features that are available when using this platform. You can integrate it with your CI / CD tools (automated deployments!), autoscaling, … . The options are endless. If you have any questions or feedback, I would love to hear them from you.