Despliegue de una aplicación con contenido persistente en Kubernetes
- Francisco Javier Huete
- Servicios
- March 9, 2025
Índice
Para hacer persistente el contenido de una aplicación a los cambios de versiones en despliegues en Kubernetes hay que tener en cuenta dónde la aplicación almacena los datos. En este sentido, una aplicación puede almacenar los datos en el propio sistema donde se ejecuta o en una base de datos externa. Según esta configuración de la propia aplicación, el despliegue se hará de una de las formas que se recogen en este post.
Hacer persistente la información almacenada en la base de datos
Para hacer persistente la información de una aplicación Python durante su despliegue en Kubernetes hay que usar un volumen para almacenar esta información que debe mantenerse entre las diferentes versiones y despliegues de la aplicación. En este caso, la información persistente se almacena en una base de datos, por tanto es necesario crear un volumen que se asocie al despliegue de este servicio.
Para ello, en primer lugar, se define un recurso de tipo pvc, que creará un volumen persistente en Kubernetes.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-redis
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
A continuación, al definir el despliegue de la base de datos se indica el volumen en el que se deben almacenar de forma persistente la información de la base de datos que se encuentra en el directorio /data
del contenedor. Además, para que el contenedor almacene de forma persistente la información de la base de datos es necesario arrancarlo con el comando redis-server
y con el argumento --appendonly yes
.
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
A partir de la definición de todos los recursos necesarios, se puede desplegar la aplicación que, en este caso, almacena la información de la base de datos en un volumen persistente.
kubectl apply -f pvc-redis.yaml
kubectl apply -f redis-deployment-persistente.yaml
kubectl apply -f redis-service.yaml
kubectl apply -f guestbook-deployment.yaml
kubectl apply -f guestbook-service.yaml
Hacer persistente tanto la información de la aplicación como de la base de datos
En el caso de la aplicación NextCloud, la propia aplicación también almacena información en el document root del servidor web sobre el que se ejecuta, además de en el servidor de base de datos. Por eso, para hacer que la información de esta aplicación sea persistente a los borrados de pods y despliegues en Kubernetes es necesario usar un volumen para la aplicación y otro para la base de datos.
Así, hay que definir dos recursos de tipo pvc para desplegar esta aplicación: uno para usar en el despliegue de la aplicación y otro para usar en el despliegue de la base de datos.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nextcloud
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-mariadb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
Por otra parte, en el despliegue de la aplicación es necesario hacer referencia al volumen en el que se deben almacenar los datos persistentes. En este caso, el volumen se monta en el documen root del servidor web de los contenedores de la aplicación.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextcloud
labels:
app: nextcloud
tier: frontend
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
tier: frontend
template:
metadata:
labels:
app: nextcloud
tier: frontend
spec:
volumes:
- name: volumen-nextcloud
persistentVolumeClaim:
claimName: pvc-nextcloud
containers:
- name: contenedor-nextcloud
image: nextcloud
ports:
- name: nextcloud-port
containerPort: 80
env:
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: nextcloud-datos
key: bd_user
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: nextcloud-datos
key: bd_dbname
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: nextcloud-passwords
key: bd_password
- name: MYSQL_HOST
valueFrom:
configMapKeyRef:
name: nextcloud-datos
key: bd_host
volumeMounts:
- mountPath: "/var/www/html"
name: volumen-nextcloud
Igualmente, también hay que modificar el despliegue de la base de datos para que use el volumen persistente definido previamente.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb
labels:
app: mariadb
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
tier: backend
template:
metadata:
labels:
app: mariadb
tier: backend
spec:
volumes:
- name: volumen-mariadb
persistentVolumeClaim:
claimName: pvc-mariadb
containers:
- name: contenedor-mariadb
image: mariadb:10.5
ports:
- name: mariadb-server
containerPort: 3306
env:
- name: MARIADB_USER
valueFrom:
configMapKeyRef:
name: nextcloud-datos
key: bd_user
- name: MARIADB_DATABASE
valueFrom:
configMapKeyRef:
name: nextcloud-datos
key: bd_dbname
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: nextcloud-passwords
key: bd_password
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: nextcloud-passwords
key: bd_rootpassword
volumeMounts:
- mountPath: "/var/lib/mysql"
name: volumen-mariadb
A partir de estos ficheros, se crean los recursos necesarios para desplegar la aplicación.
kubectl apply -f pvc-nextcloud.yaml
kubectl apply -f pvc-mariadb.yaml
kubectl apply -f mariadb-deployment-persistente.yaml
kubectl apply -f mariadb-service.yaml
kubectl apply -f nextcloud-deployment-persistente.yaml
kubectl apply -f nextcloud-service.yaml