Kubernetes is an container orchestration tool.
In this tutorial we would be using minikube and little bit of GCP K8S (Google Cloud Platform Kubernetes).
Why do we need a container orchestration ?
Suppose we have 100 instances of Microservice A and 1000 instances of Microserice B, it would be cumbersome to handle each and every containers, there we would be needing a Container Orchestration framework like Kubernetes.
Below is the architecture of Kubernetes:
Cluster = Master node(s) + Worker node(s)
Node means a machine (for eg. AWS EC2).
Kubernetes Components:
Pod: smallest deployable unit in Kubernetes. It contains single or multiple containers.
ReplicaSet: it keeps monitoring and maintains the specified number of pods running.
Deployment: It is the combination of multiple ReplicaSet.
Service: It is the final output of all the above moving parts. Internally it behaves like a load balancer and distributes the load among the pods. See the below diagram:
Each Pod has an unique IP address.
There are different Service Types:
1. Cluster IP (default one)
2. Node Port
3. Load Balancer
The smallest deployable unit in Kubernetes is Pod and not Container.
Within a pod the containers can talk to each other using localhost.
Service creates the permanent IP address.
Whenever we say:
Kubectl create deployment…. => deployment, ReplicaSet, pod.
Kubectl expose deployment… => service
Default deployment strategy through Kubernetes is “rolling updates”, which means the new version deployment happens incrementally and simultaneously the old version is un-deployment fully.
Another pic depicting a container, pod, node and cluster :
There are some more components of Kubernetes which are placed outside a pod:
Secrets: It stores the credentials.
Config Map: It stores the config changes of applications.
ETCD: It is the key-value database which stores the Secrets and Config.
Architecture of Kubernetes:
Each k8 cluster has a Master node and some Worker nodes.
If you are using kubectl or eksctl to create cluster, then your basically dont have to worry about the above architecture, it will take care of it.
How to deploy an Spring boot docker image to kubernetes cluster ?
If you want to deploy to AWS, then you have to install CLI and eksctl first on your instances and then you have to proceed with the deployment commands. And there is a associated billing cost as well.
And if you want to deploy to GCP, there CLI and kubectl are already installed. And there is no associated billing cost. First you need to connect to the GCP kubernetes cluster. For that you can launch the Cloud Shell of GCP. Then click CONNECT:
You can copy the command-line command and execute it in the Cloud Shell. With that you will be connected to GCP Kubernetes cluster.
Next you have to deploy the application.
In this tutorial we will be using Minikube & Kubectl.
Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node.
Kubectl is a command line tool to connect to the kubernetes cluster.
Steps for Minikube installation on your local windows machine :
Download the minikube-installer.exe and kubectl.exe from the official site. Rename the minikube-installer.exe to minikube.exe and put it in a folder in your system (say – C:\Prasanna\minikube).
Go to Environment Variable -> System Variables -> Path.
Add the above folder path which contains the downloaded exe file to the Path variable.
To test whether minikube is working type below command:
minikube version
Now to run minikube we have to use a driver like – docker, Hyper-V or Virtual Box.
In this tutorial we will use docker.
So, start the Docker Desktop first.
Then call the below command:
minikube start
It will take some time and will start the minikube.
To check whether minikube has started successfully or not:
minikube status
You should see something like below:
To check the cluster info:
kubectl cluster-info
To check the available nodes:
kubectl get nodes
How to deploy a application on the cluster :
To deploy an sprint boot application to kubernetes cluster you can run below command to pull the image from the docker repository :
kubectl create deployment <app-name> --image=docker-account/docker-repo-name:image-name
app-name is the name of the spring boot application that you want to give.
Using kubectl you can deploy your application to anywhere – in your local, in your on-premise data center or even on cloud.
Next you have to expose the above deployment to the outside world in the form of creating a service, below is the command for the same:
kubectl expose deployment <app-name> --type=LoadBalancer --port=8080
To check the status of the deployed application you can go to Services & Ingress url in GCP ui.
And for your local environment you can call below command:
kubectl get deployments
To see the full description of your deployed application:
kubectl describe deployment <app-name>
To see the pods:
kubectl get pods
To see the logs of the pods:
kubectl logs <pod-name>
To see the services:
kubectl get service
To know the URL of the exposed service:
minikube service <service-name> --url
It will give you a URL something like below:
http://127.0.0.1:63085/
You should know the exact API to call in the above URL.
To see the health of the pods you can run the dashboard like this:
minikube dashboard
The dashboard looks like below:
Shutting down all created services & cluster:
Its not mandatory, but its always better to delete all the services we created as part of the above exercise.
To delete the service fire the below command:
kubectl delete service <service-name>
Delete the deployment:
kubectl delete deployment <deployment-name>
To stop the node:
minikube stop
Delete the local kubernetes cluster and clear the VM and all associate files:
minikube delete
Another way to deploy the application :
You can also use an .yaml file to deploy the same application to kubernetes cluster.
The below is an sample Deployment.yaml file that creates a ReplicaSet to bring up three my-springboot-app
Pods:
apiVersion: apps/v1 # Kubernetes API version kind: Deployment # Specifies whether its a Deployment or Service. metadata: # Meta data of the resource that we are creating. name: my-springboot-app-deployment labels: app: my-springboot-app spec: replicas: 3 selector: matchLabels: app: my-springboot-app template: metadata: labels: app: my-springboot-app spec: containers: - name: my-springboot-app image: my-springboot-app:1.14.2 ports: - containerPort: 8080
Then you have to fire the below command to execute the above yaml file:
kubectl apply -f Deployment.yaml
To check the status of the pods:
kubectl get deployments
The above deployment will deploy the application to 3 different pods (and hence different IP addresses), so which pod will get called when you call the URL of the endpoint ?
Here service comes into picture, it acts like a load balancer to the deployment. You need to have another .yaml file for service in your application like below.
Service.yaml :
apiVersion: v1 kind: Service metadata: name: my-springboot-app-service spec: selector: app: my-springboot-app #This name should be same as in Deployment.yml file ports: - protocol: "TCP" port: 8080 # Port where the service is running in cluster. targetPort: 8080 # Port that is exposed as a Service. type: NodePort
Then you have to fire the below command to execute the above yaml file:
kubectl apply -f Service.yaml
To check whether service is up or not:
kubectl get service
To get the IP of the node you can fire below command:
kubectl get nodes -o wide
Some other useful K8S commands:
kubectl get event kubectl get pod kubectl get replicaset kubectl get service kubectl get deployment
We can also use plural for the above command, like below :
kubectl get pods
so forth and so on…
every pod has an internal IP address:
Kubectl get pods -o wide
To describe what a pod is
Kubectl explain pods Kubectl describe pod <pod-id>
To delete a pod:
Kubectl delete pods <pod-id>
but….. it will create another pod automatically. This is being done by the ReplicaSet– it keeps monitoring and maintains the specified number of pods running.
To add 2 new pods:
kubectl scale deployment <app-name> --replicas=3
Deploying a new version of application:
Kubectl set image deployment <app-name> <container-name>=<image name>
Some other commands:
kubectl get events --sort-by=.metadata.creationTimestamp kubectl explain replicaset Kubectl get compnentstatuses
Config Map & Secrets :
These are required if you want to store your credentials in a separate files away from the application in a common place.