En la jaula de un geek

Los README son para los cobardes. Sé valiente. Ejecuta el programa.

«

»

Nov 26

Kubernetes con volumen NFS (Centos 8)

La mentalidad de los contenedores es que sus datos se pierden tras borrarse, así que los datos que necesitamos que no se pierdan, deberán ir en volumenes.

En caso de tener un Kubernetes desplegado en una Cloud, lo recomendable es utilizar el sistema de estos, pero si tenemos nuestro propio sistema, nos tendremos que apañar con lo que podamos.

El más sencillo de todos es asociar el volumen a una carpeta compartida por NFS.

Explicación

Lo primero a tener en cuenta es que compartiremos una carpeta de un servidor utilizando NFS, cualquier nodo que despliegue el pod, montará la unidad con NFS, en caso de que el servidor NFS se caiga o no sea posible conectar con él, la carpeta del contenedor dejará de funcionar, así que nuestro pod funcionará, no llegará a caerse por defecto, pero no funcionará correctamente.
Tener en cuenta esto es muy importante, ya que si nuestro pod está bien configurado y Kubernetes detecta esta caída del servicio, es posible que intente volver a desplegar un nuevo pod para matar al anterior, pero este nuevo pod fallará por no poder conectar al servidor NFS, y así una y otra vez.

El otro punto importante es que NFS únicamente comparte la unidad, no se encarga de replicas, así que, si los datos del servidor se pierden, se perdería todo, con lo que sería altamente recomendable tener un sistema de copias de seguridad.

Este artículo está planteado para ser una base de cómo preparar un servidor NFS y desplegar un Nginx que lo utilice, para ello utilizaré servidores CentOS y un Kubernetes.

1- NFS Server

Necesitamos un servidor que haga de servidor, así que instalamos todo.

dnf install nfs-utils nfs4-acl-tools -y
systemctl enable --now nfs-server
firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload

Ahora creamos una carpeta y la compartimos

mkdir -p /mnt/nfsShare/storage1
vi /etc/exports

En CentOS 8 es necesario añadir el no_root_squash para poder escribir en la carpeta compartida sin problemas.

/mnt/nfsShare/storage1 192.168.1.0/24(rw,sync,no_root_squash)

Exportamos la unidad

exportfs -rav

Podemos mostrar la lista de todas las carpetas compartidas.

exportfs  -v

2- NFS Client en nodos

En cada nodo de Kubernetes hay que instalar las aplicaciones necesarias para que puedan montar carpetas compartidas, si un nodo no lo tiene, al revisar los logs del pod, veremos un error montando la partición.

dnf install nfs-utils nfs4-acl-tools -y

3- Desplegar Nginx con NFS

Lo primero será preparar el PersistentVolume donde se indicará la ruta hacia el servidor, la ruta y el tamaño del storage, nfs-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-storage
spec:
  storageClassName: storage-nfs
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteMany
  nfs:
    server: nfsServer.domain.intranet
    path: "/mnt/nfsShare/storage1"

Lo siguiente será conectar el PersistentVolumeClaim que utilizaremos en el despliegue, nfs-pvc-nginx.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-nginx
spec:
  storageClassName: storage-nfs
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

Utilizando el ejemplo de la documentación oficial, con la pequeña modificación de que se anclará su carpeta de publicación a la carpeta compartida por NFS, nginx-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-nfs-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nfs-storage
          mountPath: "/usr/share/nginx/html"
      volumes:
        - name: nfs-storage
          persistentVolumeClaim:
            claimName: nfs-nginx

Una vez tenemos los 3 ficheros, los aplicamos.

kubectl create -f nfs-pv.yaml
kubectl create -f nfs-pvc-nginx.yaml
kubectl create -f nginx-deployment.yaml

Podemos comprobar que el PersistentVolume esté creado.

kubectl get pv

Resultado:

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS        REASON   AGE
nfs-storage                                1Gi        RWX            Retain           Bound    default/nfs-nginx       storage-nfs                  106s

El PersistentVolumeClaim.

kubectl get pvc

Resultado:

NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS        AGE
nfs-nginx       Bound    nfs-storage                                1Gi        RWX            storage-nfs         2m5s

Y finalmente, los pods.

kubectl get pods -o wide -l app=nginx

Resultado:

NAME                                    READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
nginx-nfs-deployment-559d6cb454-9h6vg   1/1     Running   0          28s     10.244.93.4      temp101   <none>           <none>
nginx-nfs-deployment-559d6cb454-gzrgd   1/1     Running   0          28s     10.244.173.200   temp102   <none>           <none>

Para hacer la prueba, podemos acceder dentro de uno de los pods, crear un index.html y confirmar que podemos verlo.

kubectl exec -it nginx-nfs-deployment-559d6cb454-9h6vg -- bash
cd /usr/share/nginx/html
echo "Hello NFS" > index.html
curl localhost

Lo que nos devolverá el contenido del index.html

Si modificamos este fichero desde el host de NFS, veremos el cambio inmediatamente.

Final

Partiendo de este ejemplo, podremos desplegar cualquier contenedor conectando sus volumenes a un NFS, así no nos tendremos que preocupar de replicas entre diferentes nodos o pérdida de datos.

Aun así, hay que tener en cuenta los problemas de rendimiento que puede tener la red.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar