In the previous two tutorials we covered how to setup local Kubernetes (Minikube) and deploy a SpringBoot application. You can find these tutorials below.
- Setup Kubernetes Locally – Deploy SpringBoot Application – Step by Step Tutorial
- Deploy SpringBoot Application to Kubernetes(Minikube) Using Deployment yaml file
In this tutorial, we would now cover how to deploy SpringBoot application with MySQL database. In this case, we would take the following steps:
- Create a deployment for MySQL
- Create a deployment for our SpringBoot Application
We would cover the following sub-topics:
- Create the Deployment YAML for MySQL
- Test the MySQL Deployment
- Modify the Application Properties file
- Create the Application YAML File
- Deploy and Test the Application
1. Create the Deployment Yaml for MySQL
This deployment file for MySQL would be used to setup MySQL in the Kubernetes cluster. It would pull the MySQL image from the local or remote repository, create a new database, and spin up the container inside the cluster. This deployment file would have three parts: Service, PersistentVolumeClaim and Deployment.
Service
As you already know, the service is used to expose the deployment and make it accessible from outside and from other pods. The service part of the mysql-deployment.yaml file is given below:
# Define a 'Service' To Expose MySQL to Other Services apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql tier: database spec: ports: - port: 3307 targetPort: 3307 selector: app: mysql tier: database clusterIP: None # DNS is used, so clusterIP is not needed
PersistentVolumeClaim
A PersistentVolume is a piece of storage provided in a cluster either dynamically or by an administrator.
A PersistentVolumeClaim(PVC) is a request for storage (PV) by a user. Think of it as a pod made specially for providing storage space for other pods.
The PVC is defined in the MySQL deployment file. This is specified in the deployment file as follows:
# Define a 'Persistent Volume Claim'(PVC) for MySQL Storage, dynamically provisioned by cluster apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim # name of PVC essential for identifying the storage data labels: app: mysql tier: database spec: accessModes: - ReadWriteOnce #This specifies the mode of the claim that we are trying to create. resources: requests: storage: 1Gi #This will tell kubernetes about the amount of space we are trying to claim.
Deployment
The actual deployment specification is given below:
# Deployment specification begins here apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql tier: database spec: selector: # mySQL Pod Should contain same labels matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: # Must match 'Service' and 'Deployment' selectors app: mysql tier: database spec: containers: - name: mysql image: mysql imagePullPolicy: "IfNotPresent" env: - name: MYSQL_ROOT_PASSWORD value: root - name: MYSQL_DATABASE value: fleetdb ports: - containerPort: 3307 name: mysql volumeMounts: - mountPath: /var/lib/mysql name: mysql-persistance-storage volumes: - name: mysql-persistance-storage persistentVolumeClaim: claimName: mysql-pv-claim
I would recommend you watch to video tutorial in my YouTube Channel for a more detailed explanation of the various part of the deployment file. The complete mysql-deployment.yaml file can be found here.
2. Test the MySQL Deployment
You now need to actually apply the deployment using the command below.
kubectl apply -f mysql-deployment.yaml
This command would deploy the service and spin up the containers (pods) in Minikube.
You can then verify that the pods are created using the kubectl get pods command
Access the MySQL Database inside the cluster
Now that the MySQL is deployed, we would like to connect to the node right inside the cluster. You can use the command below:
kubectl exec -it <pod_name> bash
Then use the command below to connect to the MySQL server.
mysql -h mysql -u root -p
3. Modify the Application Properties File
We need to modify the application.properties file so that instead of using the hardcoded environment variables for the database, we need to make the values dynamic. So in this case, we can connect to the MySQL port running inside the cluster.
You actually only need to change the username, password and url like so:
spring.datasource.password=${DB_USERNAME} spring.datasource.username=${DB_PASSWORD} spring.datasource.url=jdbc:mysql://${DB_HOST}/${DB_NAME}?useSSL=false
The useSSL=false line indicates that the database server need not be verified.
4. Create the Application Deployment
Similar to the mysql-deployment, the app-deployment would contain two parts: the service and the deployment. These are shown below:
the deployment part
The deployment part of the app-deployment.yaml file is given below:
--- apiVersion: apps/v1 kind: Deployment metadata: name: fleetms-v2 spec: selector: matchLabels: app: fleetms-v2 replicas: 3 template: metadata: labels: app: fleetms-v2 spec: containers: - name: fleetms-v2 image: fleetms-v2:1.0 ports: - containerPort: 8080 env: # Setting Environmental Variables - name: DB_HOST # Setting Database host address value: mysql - name: DB_NAME # Setting Database name value: fleetdb - name: DB_USERNAME # Setting Database username value: root - name: DB_PASSWORD # Setting Database password value: root # This seperator --- below is MANDATORY!!! ---
the service part
The service part of the file is given below:
# Define a 'Service' To Expose the application apiVersion: v1 kind: Service metadata: name: fleetms-service spec: ports: - protocol: "TCP" port: 8080 # Port inside the cluster targetPort: # Port exposed to the outside selector: app: fleetms-v2 type: NodePort
5. Deploy and Test the Application
Now that you have the app-deployment.yaml, you can apply the deployment using the command below after you navigate to the resources folder:
kubectl apply -f app-deployment.yaml
You can then access the application using the node ip (from minikube ip command) and the node port (from kubectl get services command)
I recommend you watch the video in my YouTube Channel for clarification.