Deploy LAMP Stack on Kubernetes
Problem detailed
This is part two of a series of lab tasks from KodeKloud for Kubernetes. Master blog listing all parts can be seen here.
The Nautilus DevOps team want to deploy a PHP website on Kubernetes cluster. They are going to use Apache as a web server and Mysql for database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:
1. Create a config map php-config
for php.ini
with variables_order = "EGPCS"
data.
$ echo 'variables_order = "EGPCS"' > php.ini
$ kubectl create configmap php-config --from-file php.ini
$ # Verify
$ kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 2d20h
php-config 1 11s
$ kubectl describe configmap php-config
Name: php-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
php.ini:
----
variables_order = "EGPCS"
BinaryData
====
Events: <none>
2. Create a deployment named lamp-wp
.
3. Create two containers under it. First container must be httpd-php-container
using image webdevops/php-apache:alpine-3-php7
and second container must be mysql-container
from image mysql:5.6
. Mount php-config
configmap in httpd container at /opt/docker/etc/php/php.ini
location.
For tasks 2 and 3 above, we'll create a deployment YAML using dry-run
edit and then apply the deployment.
$ kubectl create deployment lamp-wp \
--image=webdevops/php-apache:alpine-3-php7 \
--dry-run=client -o yaml > lamp-wp.yaml
You can get the fully modified YAML from GitHub link. Use the following command to apply/create deployment:
$ kubectl apply -f deploy-lamp-stack-on-k8/lamp-wp.yaml
deployment.apps/lamp-wp created
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
lamp-wp 0/1 1 0 11s
4. Create kubernetes generic secrets for mysql related values like myql root password, mysql user, mysql password, mysql host and mysql database. Set any values of your choice.
$ kubectl create secret generic db-config \
--from-literal=MYSQL_ROOT_PASSWORD=kodekloud_root \
--from-literal=MYSQL_DATABASE=kodekloud \
--from-literal=MYSQL_USER=kodekloud_user \
--from-literal=MYSQL_PASSWORD=kodekloud_user \
--from-literal=MYSQL_HOST=mysql-service
$ kubectl get secrets
NAME TYPE DATA AGE
db-config Opaque 5 9s
5. Add some environment variables for both containers:
a) MYSQL_ROOT_PASSWORD
, MYSQL_DATABASE
, MYSQL_USER
, MYSQL_PASSWORD
and MYSQL_HOST
. Take their values from the secrets you created. Please make sure to use env
field (do not use envFrom
) to define the name-value pair of environment variables.
- Create a node port type service
lamp-service
to expose the web application,nodePort
must be30008
.
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: lamp-wp
name: lamp-service # Same as mentioned above
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30008 # Same as mentioned above
selector:
app: lamp-wp
type: NodePort
status:
loadBalancer: {}
Create and verify the service:
$ kubectl apply -f deploy-lamp-stack-on-k8/lamp-service.yaml
service/lamp-service created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d20h
lamp-service NodePort 10.100.48.196 <none> 80:30008/TCP 4s
- Create a service for mysql named
mysql-service
and its port must be3306
.
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: lamp-wp
ports:
- protocol: TCP
port: 3306
targetPort: 3306 # Important!
Create and verify MySQL service:
$ kubectl apply -f deploy-lamp-stack-on-k8/mysql-service.yaml
service/mysql-service created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d20h
lamp-service NodePort 10.100.48.196 <none> 80:30008/TCP 2m24s
mysql-service ClusterIP 10.109.198.49 <none> 3306/TCP 3s
- We already have
/tmp/index.php
file onjump_host
server. For this get theindex.php
file from GitHub link.
a) Copy this file into httpd container under Apache document root i.e /app
and replace the dummy values for mysql related variables with the environment variables you have set for mysql related parameters. Please make sure you do not hard code the mysql related details in this file, you must use the environment variables to fetch those values.
index.php
file using following kubectl
command. also note the next command that helps you get the URL for testing.$ kubectl get pods
NAME READY STATUS RESTARTS AGE
lamp-wp-7ccc648dc8-kv2sg 2/2 Running 0 29m
$ kubectl cp deploy-lamp-stack-on-k8/index.php <REPALCE_WITH_POD_NAME>:/app/ -c httpd-php-container
$ minikube service lamp-service --url
b) You must be able to access this index.php
on node port 30008
at the end, please note that you should see Connected successfully
message while accessing this page.
http://192.168.49.2:30008
to see it working. URL might be slightly different.Clean Up
$ kubectl delete deployment lamp-wp
deployment.apps "lamp-wp" deleted
$ kubectl delete svc lamp-service mysql-service
service "lamp-service" deleted
service "mysql-service" deleted
Subscribe to my newsletter
Read articles from Rajesh Pethe directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rajesh Pethe
Rajesh Pethe
Passionate software engineer with 17+ years of experience in design and development of full life cycle commercial applications. Functional experience include Financial, Telecom and E-Commerce applications. Primary technical stack includes but not limited to Python, Django, REST, SQL, Perl, Unix/Linux. Secondary technical skills include Java, Angular and React JS. DevOps skills include CiCD, AWS, Docker, Kubernetes and Terraform.