Kubernetes LEMP Setup

This is part seven of a series of lab tasks from KodeKloud for Kubernetes. Master blog listing all parts can be seen here. Make sure to follow setup instructions for minikube on your PC.

The Nautilus DevOps team want to deploy a static website on Kubernetes cluster. They are going to use Nginx, phpfpm and MySQL for the 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 some secrets for MySQL.
  • Create a secret named mysql-root-pass wih key/value pairs as follows: name: password value: R00t
$ kubectl create secret generic mysql-root-pass \
> --from-literal=password=R00t 
secret/mysql-root-pass created
$
  • Create a secret named mysql-user-pass with key/value pairs as follows: name: username value: kodekloud_cap name: password value: ksH85UJjhb
$ kubectl create secret generic mysql-user-pass \
--from-literal=username=kodekloud_cap --from-literal=password=ksH85UJjhb
secret/mysql-user-pass created
$
  • Create a secret named mysql-db-url with key/value pairs as follows: name: database value: kodekloud_db8
$ kubectl create secret generic mysql-db-url \
--from-literal=database=kodekloud_db8
secret/mysql-db-url created
$
  • Create a secret named mysql-host with key/value pairs as follows: name: host value: mysql-service
$ kubectl create secret generic mysql-host \
--from-literal=host=mysql-service
secret/mysql-host created
$
  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
configmap/php-config created
$ kubectl get configmaps 
NAME               DATA   AGE
kube-root-ca.crt   1      12d
php-config         1      12s
$
  1. Create a deployment named lemp-wp. For this, create a dry-run deployment specification:
$ kubectl create deployment lemp-wp --dry-run=client \
--image=webdevops/php-nginx:alpine-3-php7 \
-o yaml > lemp-deployment.yaml
$
  1. Create two containers under it. First container must be nginx-php-container using image webdevops/php-nginx:alpine-3-php7 and second container must be mysql-container from image mysql:5.6. Mount php-config configmap in nginx container at /opt/docker/etc/php/php.ini location.

  2. Add some environment variables for both containers:

  • 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.
💡
Edit the YAML created in previous step and make necessary changes. Final version of deployment YAML can be found here. And apply so the deployment spec can take effect.
$ kubectl apply -f deploy-lemp-stack/deployment.yaml 
deployment.apps/lemp-wp created
$ kubectl get pods 
NAME                       READY   STATUS    RESTARTS   AGE
lemp-wp-75c86cf5b8-4pf25   2/2     Running   0          100s
$
  1. Create a node port type service lemp-service to expose the web application, nodePort must be 30008.
apiVersion: v1
kind: Service
metadata:
  labels:
    app: lemp-wp
  name: lemp-service # Important!
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30008 # Important!
  selector:
    app: lemp-wp
  type: NodePort
  1. Create a service for mysql named mysql-service and its port must be 3306.
apiVersion: v1
kind: Service
metadata:
  name: mysql-service # Important!
spec:
  selector:
    app: lemp-wp
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306 # Important!
  1. We already have a /tmp/index.php file on jump_host server. It is available here.
  • Copy this file into the nginx container under 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.
$ kubectl cp deploy-lemp-stack/index.php \
<REPLACE_WITH_REAL_POD_NAME>:/app/ -c nginx-php-container 
# Verify
$ kubectl exec <REPLACE_WITH_REAL_POD_NAME> \
-- cat /app/index.php
...
$

Once done, you must be able to access this website using Website button on the top bar, please note that you should see Connected successfully message while accessing this page.

💡
To test this locally on minikube, get the service URL using minikube service lemp-service --url and visit the link to make sure you get `Connected successfully message.

Cleanup

$ kubectl delete secret mysql-db-url mysql-host mysql-root-pass mysql-user-pass 
secret "mysql-db-url" deleted
secret "mysql-host" deleted
secret "mysql-root-pass" deleted
secret "mysql-user-pass" deleted
$ kubectl delete configmap php-config
configmap "php-config" deleted
$ kubectl delete deployment lemp-wp
deployment.apps "lemp-wp" deleted
$

Note: The kubectl on jump_host has been configured to work with the kubernetes cluster.