Deploy your first scaleable PHP/MySQL Web application in Kubernetes
In this article, I talk about how to deploy PHP/Mysql Web application on top of Kubernetes.
At the end of this article, you will get to know how to deploy PHP/Mysql Web application on top of Kubernetes. In my previous article, I talk about how to use docker to deploy a PHP application.
https://www.dhirubhai.net/pulse/docker-php-developers-raghav-agarwal/
Prerequisite
- Having Knowledge of containerization tools like Docker, Podman, cri-o.
- Kubernetes cluster ( Single Node will also be okay).
Background
Docker is a great tool when you have to divide your application into multiple components or we can say that for each program/service of your application you need a different operating system for security as well as for ease of managing and running them as a single app. Here program/service you can consider for an example as PHP, Mysql. So far it is good but what in case of if your application is running on top on docker container and that container might be terminated or in case of traffic increases how you manage the loads? or how you update the application if version2 of your app comes with having zero downtime? Here the roles of Kubernetes comes in play. Kubernetes will take care of all things from scaling to distributing traffic, orchestation, rolling updates of containers.
So this is the reason we used the Kubernetes tool for orchestrating the containers. Other tools are also available for orchestrating the containers.
- Docker Swarm
- Apache Mesos
Creating PVC for both PHP and Mysql
Mysql and PHP each require a PresistentVolume to store data. Because as any of pods goes down the data present inside the pod will also be lost. So for this is require a Persistent volume claim (PVC).
Many Cluster environments have a default storage class installed. When the storage class is not specified in the PresistentVolume Claim, the cluster default storage class is used instead.
When a PresistentVolumeClaim is created, a PresistentVolume is dynamically provisioned based on the storage class configuration.
Creating a PVC resources
- Mysql
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: db-pvc labels: name: dbpvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi
- Create PVC from Kubectl Command
kubectl create -f <file_name.yml>
- For Confirmation:
kubectl get pvc db-pvc
2. For PHP
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: frontend-pvc labels: name: frontendpvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi
- Create PVC from Kubectl Command
kubectl create -f <file_name.yml>
- For Confirmation:
kubectl get pvc frontend-pvc
Creating Deployment for both PHP and Mysql
In Kubernetes deployment is a resource object in Kubernetes that provides declarative updates to applications. A deployment allows you to describe an application's lifecycle such as which image to use, the no of pods there should be, and the way in which they should be updated
Creating Deployment Resource for
- Database
apiVersion: apps/v1 kind: Deployment metadata: name: mydb-deployment spec: replicas: 1 selector: matchLabels: env: production-db template: metadata: name: mydb-pod labels: env: production-db spec: volumes: - name: db-vol persistentVolumeClaim: claimName: db-pvc containers: - name: database image: ragh19/phpproject:mysql_v1 volumeMounts: - mountPath: /var/lib/mysql name: db-vol
Here we are using a public image for MySQL present on Docker Hub tagged as ragh19/phpproject:mysql_v1.
- Create Deployment from Kubectl Command
kubectl create -f <file_name.yml>
- For Confirmation:
kubectl get deployment mydb-deployment
2. PHP
apiVersion: apps/v1 kind: Deployment metadata: name: myphp-deployment spec: replicas: 3 selector: matchLabels: env: production-frontend template: metadata: name: myfrontend-pod labels: env: production-frontend spec: volumes: - name: front-vol persistentVolumeClaim: claimName: frontend-pvc containers: - name: frontend image: ragh19/phpproject:web_v1 volumeMounts: - mountPath: /var/www/html name: front-vol
Here we are using a public image for MySQL present on Docker Hub tagged as ragh19/phpproject:web_v1.
- Create Deployment from Kubectl Command
kubectl create -f <file_name.yml>
- For Confirmation:
kubectl get deployment myphp-deployment
Creating Service for both PHP and Mysql
A service on Kubernetes is an abstraction that defines a logical set of pods and policies by which to access them. In Kubernetes services is of 3 types depending on the use-case which service you want to use.
- ClusterIP
- NodePort
- LoadBalancer
I am not going into deep dive which service should be used, Every service has different use-case. In my case, I am using NodePort as a service that exposed your application to the outside world having NodePort.
Creating Service Resource for
- Database
apiVersion: v1 kind: Service metadata: name: mydb-service spec: type: NodePort ports: - targetPort: 3306 port: 3306 nodePort: 30008 selector: env: production-db
Here Database service is exposed to 30008 port no. You can access this database service by IP and Port No having database username as root and password is redhat.
- Create Service from Kubectl Command
kubectl create -f <file_name.yml>
- For Confirmation:
kubectl get svc mydb-service
2. For PHP
apiVersion: v1 kind: Service metadata: name: myphp-service spec: type: NodePort ports: - targetPort: 80 port: 80 nodePort: 30009 selector: env: production-frontend
Here PHP service is exposed to 30009 port no. You can access PHP application by IP and port no in the browser.
Creating sample index.php file for testing connectivity between PHP application and database.
<?php $conn = new mysqli("mydb-service", "root", "redhat", "mydb"); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT name FROM user"; $result = $conn->query($sql); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo $row['name']."<br>"; } } else { echo "0 results"; } $conn->close();
Instead of using the IP of pod in the arguments of mysqli. I am using a database service name mydb-service for connectivity.
Conclusion
So in this article, we see how to deploy your first web application on top of Kubernetes. We just touch the surface of Kubernetes. Many more features like ingress, RollingUpdates, Storageclass are also being used. Following up on this post, I need a guy who can help in the understanding of ingress, How can we use ingress in AWS?
- Future Implenatations:
How to used Ingress for same php-mysql application and having CI/CD to show the power of rolling updates.
Code is available on GitHub
Yo
wanted to check the image used. Not able to find on git hub