Volúmenes en Kubernetes

Cuando comencé a escribir sobre Docker, te conté cómo funcionan los diferentes tipos de almacenamiento que podemos asignar a un contenedor. Ahora que ya sabes de Kubernetes, vamos a ver cómo se configuran los volúmenes que utilizarán nuestros pods.

Un ejemplo sin volumen

Para este artículo voy a utilizar el mismo ejemplo que te mostré en este post con Docker, para que puedas ver cuáles son las diferencias al incorporarlo en Kubernetes.

Lo primero que voy a hacer es crear un pod con postgres sin ningún volumen, para que puedas ver el resultado y entender bien cuál es nuestro objetivo:

apiVersion: v1
kind: Pod
metadata:
  name: mypostgres
spec:
  containers:
  - name: postgres
    image: postgres

Como ves es un pod super simple donde sólo tengo un contenedor con la imagen de postgres. Para crear este nuevo pod en tu clúster puedes hacerlo con el siguiente comando:

kubectl apply -f pod-without-volume.yaml 

Lo siguiente que vamos a hacer es acceder al mismo y lanzar los siguientes comandos:

#Access to the pod
kubectl exec -it mypostgres -- /bin/bash

#Create a postgress db
createdb -U postgres mydb

#Access to my postgress db
psql -U postgres mydb

#Create a table
CREATE TABLE products (id int, name varchar(100));

#Create a product into my table
INSERT INTO products (id, name) VALUES (1, 'Wheel');

#List products
SELECT * from products;

#Exit postgress client
\q

Lo que acabas de hacer es crear una nueva base de datos llamada mydb que contiene una tabla llamada products que a su vez contiene un registro, el cual listamos para confirmar que está ahí. Por último, salimos del cliente de postgres pero continuamos dentro del contenedor. Ahora abre un nuevo terminal y vigila el estado del pod mypostgres:

kubectl get pod mypostgres --watch

De nuevo en el primer terminal lanza el siguiente comando para ver los procesos que se están ejecutando:

ps aux

Verás que el proceso de postgres tiene el PID 1. Mata el proceso para que el pod se reinicie:

kill 1

En el otro terminal verás que el pod termina y vuelve a iniciarse:

El pod se reinicia después de matar el proceso de postgres

Accede de nuevo a tu pod y lanza el siguiente comando:

#Access to the pod
kubectl exec -it mypostgres -- /bin/bash

#Access to my postgress db
psql -U postgres mydb

En este momento verás que el intento de acceso a la base de datos da error diciendo que no existe.

No existe la base de datos al reiniciar el pod

Esto es debido a que cuando el pod se reinicia o se destruye toda la información que se ha generado dentro del mismo se pierde. Es por ello que necesitamos los volúmenes, para no perder el trabajo realizado en pods que necesitan almacenar información.

Ahora vamos a crear el mismo pod con un volumen asociado.

Pod con volumen

En el mismo ejemplo agrega las siguientes lineas al YAML anterior y cambia el nombre del pod a mypostgres-withvolume:

apiVersion: v1
kind: Pod
metadata:
  name: mypostgres-withvolume
spec:
  containers:
  - name: postgres
    image: postgres
    volumeMounts:
    - name: postgres-data
      mountPath: /var/lib/postgresql/data
  volumes:
  - name: postgres-data
    emptyDir: {}

Como ves, tenemos un nuevo apartado llamado volumeMounts donde puedes añadir uno o más volúmenes y el path al cual estará asociado. Por otro lado tenemos la sección volumes donde especificamos de qué tipo es el volumen que estamos asociando, en este caso emptyDir. Existen muchos otros que nos aportan un valor adicional, que veremos en un siguiente post.

Lanza esta nueva configuración para crear un nuevo pod con un volumen asociado:

kubectl apply -f pod-without-volume.yaml 

Repite el proceso anterior para crear la base de datos, la tabla y el registro:

#Access to the pod
kubectl exec -it mypostgres-withvolume -- /bin/bash

#Create a postgress db
createdb -U postgres mydb

#Access to my postgress db
psql -U postgres mydb

#Create a table
CREATE TABLE products (id int, name varchar(100));

#Create a product into my table
INSERT INTO products (id, name) VALUES (1, 'Wheel');

#List products
SELECT * from products;

#Exit postgress client
\q

Elimina el proceso con PID 1, para que el pod se reinicie y podamos comprobar si esta vez los cambios en nuestro postgres siguen ahí.

Vuelve a acceder a mypostgres-withvolume e intenta lanzar los siguiente comandos. Comprobarás que la base de datos mydb y la tabla products sigue ahí:

#Access to the pod
kubectl exec -it mypostgres -- /bin/bash

#Access to my postgress db
psql -U postgres mydb

#List databases
\l

#list tables
\dt

#list products
select * from products;

Sin embargo, si eliminamos el pod completamente y lo volvemos a lanzar verás que dicho volumen no se mantiene, por lo que tendremos que pensar en algo más si queremos que aun no existiendo el pod los datos permanezcan 😉

¡Saludos!