Use case: Web application (Moodle) + DB with Volume backend¶
In this page we will deploy a typical service: a web application (moodle) connected to a DB (mysql), which uses a persistent volume in the backend.
1. Claim persistent volume¶
Let’s first allocate the Ceph volume that the DB will use to store its data. Create the following file volclaim.json:
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "db-vol"
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "4Gi"
}
},
"storageClassName": "hdd"
}
}
Note the StorageClassName whose name is hdd for our Platform, the name we give to the volume, db-vol, and the requested size, 4 GB.
Apply the request:
$ kubectl create -f volclaim.json
persistentvolumeclaim/db-vol created
Let’s query the volume status:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
db-vol Bound pvc-fbf4bd91-5229-11e9-95ff-549f35ad4eca 4Gi RWO hdd 9s
2. Create secret password¶
Let’s now record the password that we will use to access the MySQL DB. The password is created with the following command:
kubectl create secret generic mysql-pass --from-literal=password=$PASSWORD
where $PASSWORD is a strong password. Keep note of it as it won’t be displayed again. To query the secrets:
$ kubectl get secrets
NAME TYPE DATA AGE
mysql-pass Opaque 1 9s
3. Deploy MySQL¶
Let’s create the database. Create the following file mysql-vol.yaml:
apiVersion: v1
kind: Service
metadata:
name: mysql-db
labels:
app: moodle
spec:
ports:
- port: 3306
selector:
app: moodle
tier: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-db
labels:
app: moodle
spec:
selector:
matchLabels:
app: moodle
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: moodle
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-data
ports:
- containerPort: 3306
name: mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: db-vol
This files describes two objects:
the MySQL deployment (name: mysql-db)
the correspondent service (name: mysql-db) that exposes the database (port 3306) to the other deployments.
Note:
the environment variable MYSQL_ROOT_PASSWORD whose value is gathered from the previously stored secret mysql-pass;
the persistent volume db-vol mounted on the directory /var/lib/mysql.
Create the deployment:
$ kubectl create -f mysql-vol.yaml
service/mysql-db created
deployment.apps/mysql-db created
Check:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql-db ClusterIP None <none> 3306/TCP 78m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-db-cc64cdbdd-t4b5s 1/1 Running 0 78m
Before continuing, we need to set some parameter in MySQL otherwise Moodle won’t be installed. Let’s log in the container:
$ kubectl exec -ti mysql-db-cc64cdbdd-t4b5s bash
root@mysql-db-cc64cdbdd-t4b5s:/#
root@mysql-db-cc64cdbdd-t4b5s:/# mysql -u root -p$PASSWORD
mysql> set global innodb_large_prefix = `ON`;
mysql> set global innodb_file_format=Barracuda;
mysql> exit
where $PASSWORD is the password stored in the secret.
Of course it would be better to change the configuration and restart the MySQL service, but with the current implementation stopping the service leads to stopping and recreating the pod, so the configuration is lost.
TODO: Understand how to set the configuration parameters in the YAML file!
4. Deploy Moodle¶
Create the file moodle.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mymoodle
labels:
app: moodle
spec:
selector:
matchLabels:
app: moodle
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: moodle
tier: frontend
spec:
containers:
- image: bitnami/moodle:latest
name: mymoodle
env:
- name: MOODLE_DATABASE_USER
value: "root"
- name: MOODLE_DATABASE_NAME
value: "moodle"
- name: MOODLE_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
- name: MARIADB_HOST
value: mysql-db
Note the deployment name, moodle, and the environment parameters. In particular the parameter $MARIADB_HOST will access the database using the DB service name, mysql-db.
Issue the command:
$ kubectl create -f moodle.yaml
deployment.apps/mymoodle created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mymoodle-9d6c59c8b-mpf68 1/1 Running 0 66m
The installation will take some time. Meanwhile we can access the container and check that we can access the database using the DB service name:
root@mymoodle-9d6c59c8b-mpf68:/# mysql -u root -h mysql-db -p$PASSWORD
MySQL [(none)]>
The installation is completed when ps aux run on the container will show the following processes:
root@mymoodle-9d6c59c8b-mpf68:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 151 0.0 0.0 279032 33660 ? S 14:28 0:00 /opt/bitnami/apache/bin/httpd -f /opt/bitnami/apache/conf/httpd.conf -D FOREGROUND
...
We can now expose moodle:
$ kubectl expose deployment mymoodle --type="LoadBalancer" --port 80
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mymoodle LoadBalancer 10.152.183.49 90.147.190.19 80:30192/TCP 116s
Finally, open a bowser and type the EXTERNAL-IP that LoadBalancer assigned to the service (in this case: 90.147.190.19). Happy Moodl’ing!
Log in Moodle as an Admin with username and password that you can read in the moodle container environmental variables (env) MOODLE_USERNAME and MOODLE_PASSWORD.