Storage Persistente en GKE

Kubernetes se ha establecido como la herramienta predilecta para desplegar, escalar y gestionar aplicaciones en la nube. Una de las principales razones es su robustez y flexibilidad es su sistema de manejo de volúmenes, diseñado para abordar uno de los desafíos más grandes en la contenerización: la persistencia de datos.

En este caso estaremos realizando una introducción sobre Volumenes efimeros y persistentes en GKE.

Tipos de Volumenes

En este caso los vamos a estar clasificando en 2 tipos Efimeros y Persistentes.

Volumenes efímeros:

Este tipo de Volumen se asignan a nivel de pods y dependen del ciclo de vida de los pods. Se utilizan cuando los datos o la informacion no deben ser mantenidos a lo largo del tiempo (es decir que no debe ser presistente).

Con este tipo de volumenes, cuando el ciclo de vida del pod finalice, tambien finalizará la de los datos. Los volumenes no mantendran una persistencia de datos.

Algunos ejemplos:

  • emptyDir:
    • Cuando un pod storage se define este tipo de volume, se crea cuando el pod es asignado a un nodo del cluster.
    • Se asigna (como indica el nombre) un directorio vacío.
    • Es compartido para todos los Contendores dentro del pod.
    • Cuando el ciclo de vida del pod finaliza. Tambien finaliza la del emptyDir volume y sus datos son eliminados.
    • Cuando un contenedor Crashea los datos no son eliminados.
    • Algunos usos posibles:
      • Espacio de trabajo temporal (scratch space).
      • Guardar puntos de control en cálculos largos para recuperarse de fallos.
      • Mantener archivos que un contenedor de Content-Manager obtiene mientras un contenedor de servidor web proporciona los datos.

Ephemerals con propositos particulares:

  • ConfigMaps:
    • Es una forma de inyectar datos de configuración en los pods.
    • Se referencia dentro de las especificaciones del pod.
  • Secrets:
    • Se utiliza para pasar a los pods información sensible de manear segura como passwords.

Volumenes Persistentes:

  • Son independientes.
  • No dependen del ciclo de vida de los Pods.
  • Pueden ser PersistenVolumes o PersistentVolumesClaim.

Los tipos que estaremos viendo hoy:

  • PersistenVolume (PV):
    • Es la declaración del storage persistente presentado en el cluster. Se provisiona utilizando Storage Classes. Tienen una vida independiente a la de los pods.
    • El tipo de Storage es definido por las StorageClasses.
  • PersistentVolumeClaim (PVC):
    • Es el solicitante configurado a nivel del pod para consumir el PV.
    • El request puede especificar niveles especificos de recursos, size y modelos de acceso.

¿Que es un StatefulSet?

Es un tipo de objeto declarativo de K8s que se utiliza para gestionar aplicaciones con estado persistente.

Gestiona la implementación y escalamiento de un set de Pods y provee garantias sobre el ordeniamiento y uniqueness de cada Pod.

La diferencia con los deployments es que se maneja una identidad para cada pod. Se crean con las mismas especificaciones pero no son intercambiables. Se setean identificadores persistentes que se mantienen durante los reschedules.

Se utilizan para apps que requieran:

  • Identificadores de Red unicos.
  • Storage Persistente y estable.
  • Implementación y escalamiento unico y de manera ordenada.
  • Rolling Updates automaticos.

Laboratorio: probando PersistentVolumes en GKE

Vamos a arrancar con el lab!

Primero, podemos corroborar que tenemos un GKE Standard Cluster desplegado en nuestro ambiente de laboratorio de GCP:

Conectarse al cluster

Como siempre debemos hacer en Cloud Shell o Gcloud, utilizaremos las Enviroment Variables para guardar la zona y el nombre del Cluster de GKE:

export my_zone=us-central1-a
export my_cluster=standard-cluster-1

Luego, vamos a setear el autocompletado de Kubectl en cloud shell:

source <(kubectl completion bash)

Ahora, nos vamos a conectar a nuestro cluster utilizando el siguiente comando:

gcloud container clusters get-credentials $my_cluster --zone $my_zone

Este es el output que debería generarse:

Crear PVC

Ahora utilizaremos el siguiente yaml file para declarar nuestro PersistenVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: hello-web-disk
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi

Como veremos en la siguiente imagen el PVC es creado en K8s:

Podremos verificar el correcto despliegue utilizando el siguiente comando:

kubectl get persistentvolumeclaim

Crear Pod

Ahora crearemos un Pod para poder montar el PV utiilzando el PVC. Declaración del Pod:

kind: Pod
apiVersion: v1
metadata:
  name: pvc-demo-pod
spec:
  containers:
    - name: frontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: pvc-demo-volume
  volumes:
    - name: pvc-demo-volume
      persistentVolumeClaim:
        claimName: hello-web-disk

Como podemos ver se declara el PVC en

  • specs.containers.frontend.mountPath: donde referenciamos el path de mount y el PVC.
  • specs.volumes: aquí declaramos el volumenb referenciando al PVC creado en el paso anterior.

Para desplegarlo utilizaremos el siguiente comando:

kubectl apply -f nginx-fronted.yaml

Podemos ver los pods desplegados

Prueba de Persistencia

Realizaremos una pequeña prueba de persistencia.

Primero, ingresaremos al bash del pod creado utilizando el siguiente comando:

kubectl exec -it pvc-demo-pod -- sh

Luego crearemos un archivo html en nuestro mountPath:

echo Test webpage in a persistent volume!>/var/www/html/index.html
chmod +x /var/www/html/index.html

Ahora eliminaremos el pod:

kubectl delete pod pvc-demo-pod

Verificamos la existencia del PVC:

kubectl get persistentvolumeclaim

Re-creamos el pod:

Para desplegarlo utilizaremos el siguiente comando:

kubectl apply -f nginx-fronted.yaml

Y verificamos la persistencia leyendo el archivo creado en el paso anterior.

cat /var/www/html/index.html

Crear StatefulSet

Ahora crearemos un StatefulSet.

Utilizaremos el siguiente yaml:

kind: Service
apiVersion: v1
metadata:
  name: statefulset-demo-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  type: LoadBalancer
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-demo
spec:
  selector:
    matchLabels:
      app: MyApp
  serviceName: statefulset-demo-service
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: MyApp
    spec:
      containers:
      - name: stateful-set-container
        image: nginx
        ports:
        - containerPort: 80
          name: http
        volumeMounts:
        - name: hello-web-disk
          mountPath: "/var/www/html"
  volumeClaimTemplates:
  - metadata:
      name: hello-web-disk
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 30Gi

La caracteristica diferenciada de este yaml es que en lugar de declarar el volumen a nivel del pod, declaramos el volumeClaimTemplates, donde especificamos los datos de nuestro PVC directamente dentro de este mismo yaml.

Esto generará que se creen nuevos PVCs a partir de la aplicación de este archivo.

Lo desplegamos utilizando el comando “kubectl apply” ejecutado anteriormente, pero cambiando el archivo:

kubectl apply -f statefulset-demo.yaml

Podemos observar los pods creados:

Y como comentamos anteriormente los PVC creados.

Esto, al igual que en punto anterior nos dará persistencia de discos, pero un StatefulSet nos da otros features de una capa de abstracción mayor.


Posted

in

, ,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.