In the previous chapter, we read about how to create a Sample Node.js Application on EKS. In this chapter, we are gonna find out how to handle applications such as MySQL or Cassandra or Redis since they have storage involved.
Suppose, we are trying to provision, say for example a MySQL Service on Kubernetes, what happens to the data if the MySQL Pod goes down momentarily? Does the data get lost as well? We are gonna learn how to handle such kinds of services.
So these type of services are called StatefulSets which have a persistent storage attached to them. Basically, we create a volume when the Pod gets created and it gets allocated to the Pod. If the MySQL Service Pod accidentally goes down, the volume gets detached and when the new MySQL Pod spawns up, the existing volume gets attached. Let's see how we can make it work.
Considering our EKS cluster with node(s) are running, we are gonna create a file called
mysql-pv.yml In this example, we are gonna create volumes and map it to MySQL Service.
apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv-volume labels: type: local spec: storageClassName: manual capacity: storage: 15Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/src" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 15Gi
In the above code, we can modify the storage to be allocated based on our use case. Also, there are 3 types of Access Modes. They are:-
- ReadWriteOnce: The volume can be mounted as read-write by a single node
- ReadOnlyMany: The volume can be mounted read-only by many nodes
- ReadWriteMany: The volume can be mounted as read-write by many nodes
What is the difference between Persistent Volume and Persistent Volume Claim ?
A Persistent Volume (PV) is the "physical" volume on the host machine( in our case the node running on AWS) that stores our persistent data. A Persistent Volume Claim (PVC) is a request for the platform to create a PV for us, and then we can attach PV(s) to our pods via a PVC.
Now, let us create the PV and the PVC. We use the following command:-
kubectl create -f mysql-pv.yml
Next, we create MySQL Deployment file. Create a file called
mysql-deployment.yml and add the following code:-
apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - image: mysql:8.0 name: mysql env: - name: MYSQL_ROOT_PASSWORD value: "qwertyuiop" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim
The above code will pull a mysql8.0 from Docker hub and create a deployment for the same. It'll configure the default mysql password as "qwertyuiop" which is the value we have mentioned for the key
Note: In production use case, we need to make use of secrets which we will discuss in later chapters.
Also, it'll map the Pod to the
mysql-pv-claim PVC, which we created earlier.
Let's run the above Deployment file by running the command:-
kubectl apply -f mysql-deployment.yaml
Next, let's create a
mysql-service.yml file which will create the MySQL Service.
apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 selector: app: mysql clusterIP: None
If we mention clusterIP as
none, the service will not loadbalance the request amongst all replicas of the Deployment. In such a case, we have to manually fetch the IP address of the Pod in order to connect to the MySQL Pod.
To run this, we can run the following command:-
kubectl apply -f mysql-service.yml
To access the MySQL instance, access the pod created by the deployment.
kubectl get pods
This will give us the name of the currently running MySql pod.
kubectl exec -it <mysql_pod_name> /bin/sh
You'll be able to enter the MySQL Pod, now let us run the MySQL cli command to login to our database:-
qwertyuiop is the password which we defined in the deployment file.
Voila, now we can create databases, tables, users etc.
Note: Even if the pod is deleted the data will still remain as long as the volume is not deleted.
Similarly, this is how we will handle Services which are StatefulSets like Cassandra, Redis etc.
In the next chapter, we are gonna learn how to handle Secrets i.e. sensitive information like Passwords in Kubernetes. Cheers!