Kubernetes: Almacenamiento en Kubernetes
Ejercicio 1: Desplegando un servidor web persistente
Siguiendo la guía explicada en el Ejemplo 2: Gestión dinámica de volúmenes, vamos a crear un servidor web que permita la ejecución de scripts PHP con almacenamiento persistente.
Para realizar esta actividad vamos a usar asignación dinámica de volúmenes y puedes usar, como modelos, los ficheros del ejemplo 2.
- pvc-ejemplo2.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-ejemplo2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- deploy-ejemplo2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ejemplo2
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: volumen-ejemplo2
persistentVolumeClaim:
claimName: pvc-ejemplo2
containers:
- name: contenedor-nginx
image: nginx
ports:
- name: http-server
containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: volumen-ejemplo2
- srv-ejemplo2.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ejemplo2
spec:
type: NodePort
ports:
- name: service-http
port: 80
targetPort: http-server
selector:
app: nginx
Realiza los siguientes pasos:
- Crea un fichero yaml para definir un recurso
PersistentVolumenClaim
que se llame pvc-webserver y para solicitar un volumen de 2Gb.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-webserver
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
Crea el recurso y comprueba que se ha asociado un volumen de forma dinámica a la solicitud.
kubectl apply -f pvc-webserver.yaml kubectl get pv,pvc
Crea un fichero yaml para desplegar un servidor web desde la imagen php:7.4-apache, asocia el volumen al Pod que se va a crear e indica el punto de montaje en el DocumentRoot del servidor: /var/www/html.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-persistente
labels:
app: php
spec:
replicas: 1
selector:
matchLabels:
app: php
template:
metadata:
labels:
app: php
spec:
volumes:
- name: volumen-persistente
persistentVolumeClaim:
claimName: pvc-webserver
containers:
- name: contenedor-php
image: php:7.4-apache
ports:
- name: http-server
containerPort: 80
volumeMounts:
- mountPath: "/var/www/html"
name: volumen-persistente
Despliega el servidor y crea un fichero info.php en /var/www/html, con el siguiente contenido: <?php phpinfo(); ?>.
kubectl apply -f deploy-webserver.yaml kubectl exec -it web-persistente-5c8b8f6b4f-8q9q8 -- /bin/bash echo "<?php phpinfo(); ?>" > /var/www/html/info.php
Define y crea un Service NodePort, accede desde un navegador al fichero info.php y comprueba que se visualiza de forma correcta.
apiVersion: v1
kind: Service
metadata:
name: srv-webserver
spec:
type: NodePort
ports:
- name: service-http
port: 80
targetPort: http-server
selector:
app: php
kubectl apply -f srv-webserver.yaml
Comprobemos la persistencia: elimina el Deployment, vuelve a crearlo y vuelve a acceder desde el navegador al fichero info.php. ¿Se sigue visualizando?
kubectl delete -f deploy-webserver.yaml kubectl apply -f deploy-webserver.yaml
Entrega
1. Pantallazo con la definición del recurso PersistentVolumenClaim.
2. Pantallazo donde se visualice los recursos pv y pvc que se han creado.
3. Pantallazo donde se vea el fichero yaml para el despliegue.
4. Pantallazo donde se vea el acceso a info.php.
5. Pantallazo donde se vea que se ha eliminado y se ha vuelto a crear el despliegue y se sigue sirviendo el fichero info.php.
Ejercicio 2: Haciendo persistente la aplicación GuestBook
En este ejercicio vamos a volver a desplegar nuestra aplicación GuestBook, que realizamos en el taller 4 y 5, para añadirle persistencia a la base de datos redis.
Por lo tanto necesitaremos solicitar un volumen, que se asociará de forma dinámica.
Creando el despliegue de redis para que guarde la información en un directorio
Si estudiamos la documentación de la imagen redis en Docker Hub, para que la información de la base de datos se guarde en un directorio /data
del contenedor hay que ejecutar con docker:
docker run --name some-redis -d redis redis-server --appendonly yes
Es decir, hay que crear el contenedor ejecutando el proceso redis-server con los argumentos --appendonly yes
.
Por lo tanto tenemos que cambiar el fichero de definición del Deployment de redis, redis-deployment.yaml de la siguiente manera:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: backend
template:
metadata:
labels:
app: redis
tier: backend
spec:
volumes:
- name: volumen-redis
persistentVolumeClaim:
claimName: xxxxxxxxxxxx
containers:
- name: contenedor-redis
image: redis
command: ["redis-server"]
args: ["--appendonly", "yes"]
ports:
- name: redis-server
containerPort: 6379
volumeMounts:
- mountPath: xxxxxxxxxxxx
name: volumen-redis
Hemos usado el parámetro command para ejecutar el proceso, y el parámetro args para indicar los argumentos.
Nota: Los valores xxxxxxxxxxxx tendrás que rellenarlos durante la realización de la actividad.
Pasos a seguir
Realiza los siguientes pasos:
- Crea un fichero yaml para definir un recurso
PersistentVolumenClaim
que se llamepvc-redis
y para solicitar un volumen de 3Gb.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-redis
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Crea el recurso y comprueba que se ha asociado un volumen de forma dinámica a la solicitud.
kubectl apply -f pvc-redis.yaml kubectl get pv,pvc
Modifica el fichero del despliegue de redis, modificando las xxxxxxxxxxxx por los valores correctos: el nombre del
PersistentVolumenClaim
y el directorio de montaje en el contenedor (como hemos visto anteriormente es/data
).
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: backend
template:
metadata:
labels:
app: redis
tier: backend
spec:
volumes:
- name: volumen-redis
persistentVolumeClaim:
claimName: pvc-redis
containers:
- name: contenedor-redis
image: redis
command: ["redis-server"]
args: ["--appendonly", "yes"]
ports:
- name: redis-server
containerPort: 6379
volumeMounts:
- mountPath: /data
name: volumen-redis
Crea el despliegue de redis. El despliegue de la aplicación guestbook y la creación de los Services de acceso se hace con los ficheros que ya utilizamos anteriormente: guestbook-deployment.yaml, guestbook-srv.yaml y redis-srv.yaml.
kubectl apply -f redis-deployment.yaml kubectl apply -f .
Accede a la aplicación y escribe algunos mensajes.
Comprobemos la persistencia: elimina el despliegue de redis, vuelve a crearlo, vuelve a acceder desde el navegador y comprueba que los mensajes no se han perdido.
kubectl delete -f redis-deployment.yaml kubectl apply -f redis-deployment.yaml
Entrega
1. Pantallazo con la definición del recurso PersistentVolumenClaim.
2. Pantallazo donde se visualicen los recursos pv y pvc que se han creado.
3. Pantallazo donde se vea el fichero yaml modificado para el despliegue de redis.
4. Pantallazo donde se vea el acceso a la aplicación con los mensajes escritos.
5. Pantallazo donde se vea que se ha eliminado y se ha vuelto a crear el despliegue de redis y que se sigue sirviendo la aplicación con los mensajes.
Ejercicio 3: Haciendo persistente la aplicación Nextcloud
Esta actividad es la continuación de la actividad realizada en el taller 5.
Siguiendo la guía que hemos desarrollado en Ejemplo 3: Wordpress con almacenamiento persistente vamos a configurar el despliegue de Nextcloud para que use volúmenes (vamos a usar dos volúmenes, uno para la aplicación y otro para la base de datos) para que la información no se pierda.
kubectl create configmap bd-datos --from-literal=bd_user=nazareth \
--from-literal=bd_dbname=nextcloud \
--from-literal=bd_host=mariadb-service \
-o yaml --dry-run=client > configmap-bd.yaml
kubectl create secret generic bd-secret --from-literal=bd_password=nazareth \
--from-literal=bd_root_password=nazareth \
-o yaml --dry-run=client > configmap-bd-secret.yaml
- nextcloud-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextcloud-deployment
labels:
app: nextcloud
type: frontend
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
type: frontend
template:
metadata:
labels:
app: nextcloud
type: frontend
spec:
containers:
- name: nextcloud
image: nextcloud:latest
ports:
- containerPort: 80
name: nextcloud-http
- containerPort: 443
name: nextcloud-https
env:
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_dbname
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_password
- name: MYSQL_HOST
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_host
- nextcloud-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: nextcloud-service
labels:
app: nextcloud
type: frontend
spec:
type: NodePort
ports:
- name: http-nextcloud-srv
port: 80
targetPort: nextcloud-http
selector:
app: nextcloud
type: frontend
- mariadb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-deployment
labels:
app: nextcloud
type: database
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
type: database
template:
metadata:
labels:
app: nextcloud
type: database
spec:
containers:
- name: mariadb
image: mariadb:10.5
ports:
- containerPort: 3306
name: mariadb-port
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_root_password
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_dbname
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_password
- mariadb-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: mariadb-service
labels:
app: nextcloud
type: database
spec:
selector:
app: nextcloud
type: database
ports:
- port: 3306
targetPort: mariadb-port
type: ClusterIP
Realiza los siguientes pasos:
- Crea los ficheros yaml para definir los recursos PersistentVolumenClaim para solicitar dos volúmenes de 4Gb.
- pvc-nextcloud.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nextcloud
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
- pvc-mysql.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
Crea esos recursos y comprueba que se ha asociado un volumen de forma dinámica a cada solicitud.
kubectl apply -f pvc-nextcloud.yaml kubectl apply -f pvc-mysql.yaml kubectl get pv,pvc
Modifica los ficheros de despliegue de la aplicación y la base de datos para asociar los volúmenes a cada uno. Según la documentación de la imagen Nextcloud en Docker Hub, la forma más sencilla de hacer persistente la aplicación es montar el volumen en el directorio /var/www/html/.
- nextcloud-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextcloud-deployment
labels:
app: nextcloud
type: frontend
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
type: frontend
template:
metadata:
labels:
app: nextcloud
type: frontend
spec:
volumes:
- name: nextcloud-vol
persistentVolumeClaim:
claimName: pvc-nextcloud
containers:
- name: nextcloud
image: nextcloud:latest
ports:
- containerPort: 80
name: nextcloud-http
- containerPort: 443
name: nextcloud-https
env:
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_dbname
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_password
- name: MYSQL_HOST
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_host
volumeMounts:
- name: nextcloud-vol
mountPath: /var/www/html
- mariadb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-deployment
labels:
app: nextcloud
type: database
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
type: database
template:
metadata:
labels:
app: nextcloud
type: database
spec:
volumes:
- name: mariadb-vol
persistentVolumeClaim:
claimName: pvc-mysql
containers:
- name: mariadb
image: mariadb:10.5
ports:
- containerPort: 3306
name: mariadb-port
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_root_password
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_dbname
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: bd-datos
key: bd_user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: bd-secret
key: bd_password
volumeMounts:
- name: mariadb-vol
mountPath: /var/lib/mysql
Accede a la aplicación, configúrala y sube un fichero.
Comprobemos la persistencia: elimina los despliegues, vuelve a crearlos y vuelve a acceder desde el navegador y comprueba que la aplicación está configurada y mantiene el fichero que habías subido.
kubectl delete -f nextcloud-deployment.yaml kubectl delete -f mariadb-deployment.yaml