Esto es una prueba de concepto de cómo funcionan los PersistentVolume en kubernetes. Creo un PersistentVolume y a partir de un PersistentVolumeClaim lo comparto entre dos contenedores. Un contenedor (aplicación java) escribe texto en el volumen. Mientras que el otro contenedor(un nginx) publica el contenido del volumen. He utilizado Kind.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: /mnt/c/Users/yo/kubernetes/volumes
containerPath: /host
Esto nos construye un cluster de kubernetes con un sólo nodo. Que hace las tareas de controlador y worker.
kind create cluster --config kind-cluster.yaml
nodes.extraMounts.hostPath es una ruta del equipo donde corre el KIND. Es un directorio de tu ordenador, donde estás haciendo las pruebas.
nodes.extraMounts.containerPath directorio del nodo del cluster kind donde se monta el directorio del hostPath.
Si haces un docker exec al contenedor del nodo y haces un ls, ves lo mismo que tu ordenador tenga en hostPath. Además se actualiza en caliente. Si creas un fichero en tu ordenador, aparece también dentro. Que tiene su lógica, pero hay que probarlo.
Desde tu ordenador
$ ls /mnt/c/Users/yo/kubernetes/volumes
index.html
staticFiles
Entrando al contenedor
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ffa8f1cdf222 kindest/node:v1.19.1 "/usr/local/bin/entr…" 4 days ago Up 37 seconds 127.0.0.1:38857->6443/tcp kind-control-plane
$ docker exec -it kind-control-plane bash
root@kind-control-plane:/# ls /host
index.html
staticFiles
apiVersion: v1
kind: PersistentVolume
metadata:
name: volume001-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /host
hostPath.path indica el directorio del host del que se "saca" el volumen. Es el que tenemos que haber indicado antes al crear el cluster con el valor containerPath. Aquí hay que tener en cuenta que el KIND es el host para el cluster de kubernetes. No confundir con el directorio de tu ordenador.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: volumeClaimAAA-pvc
spec:
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteOnce
storageClassName: ""
Aquí pedimos que nos de un 1 GB
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
volumeMounts:
- name: staticfiles
mountPath: /usr/share/nginx/html
- name: quarkus
image: yo/randomIndexQuarkus:1.0.0-SNAPSHOT
volumeMounts:
- name: staticfiles
mountPath: /generatedFiles
volumes:
- name: staticfiles
persistentVolumeClaim:
claimName: volumeClaimAAA-pvc
Empezando por abajo. volumes.name Es el nombre con el que vamos a presentar el volumen a los contenedores. En el campo claimName hacemos la referencia al nombre del PersistentVolumeClaim
spec.containers.volumeMount En el name hacemos referencia al nombre indicado en el volumes. Y en mountPath indicamos el directorio donde se va a montar el volumen dentro del contenedor
spec.volumes.claimName Es el nombre del PersistentVolumeClaim referenciado en el anterior yaml. Este volumen se comparte entre los dos siguientes contenedores.
nginx se está montando el claim en /usr/share/nginx/html, que es el directorio por defecto donde nginx sirve estáticos html.
yo/randomIndexQuarkus:1.0.0-SNAPHOST es una aplicación quarkus que escribe cadenas al azar en un fichero /generatedFiles/index.html. /generatedFiles es la misma ruta en la que se monta el claim para ese contenedor dentro del pod
while(true) {
String randomString = RandomStringUtils.randomAlphabetic(50);
List<String> lines = Collections.singletonList( randomString );
File file = new File("/generatedFiles/index.html");
FileUtils.writeLines(file, lines, StringUtils.CR , Boolean.TRUE);
}
El proceso java de dentro del contenedor de quarkus está constantemente escribiendo líneas nuevas al fichero index.html. Este fichero está alojado en un PersistentVolume compartido con el nginx. Por lo que si accedemos al nginx de dentro