Table of Contents
Introducción
Con la naturaleza distribuida y dinámica de los contenedores, la administración y configuración estática de almacenamiento se ha convertido en un problema complejo en Kubernetes, porque las cargas de trabajo ahora pueden moverse de una máquina virtual (VM) a otra en cuestión de segundos. Para abordar esto, Kubernetes administra los volúmenes con un sistema de volúmenes persistentes (PV), objetos API que representan una configuración y un volumen de almacenamiento, y PersistentVolumeClaims (PVC), una solicitud de almacenamiento que debe satisfacerse a través de un volumen persistente. Además, los controladores de Container Storage Interface (CSI) pueden ayudar automatizar y administrar la gestión y el aprovisionamiento de almacenamiento para cargas de trabajo en contenedores. Estos controladores se encargan de aprovisionar, montar y desmontar volúmenes, eliminarlos y realizar capturas de ellos.
La the cloud provider-csi integra un clúster de Kubernetes con el producto Block Storage de the cloud provider. Un desarrollador puede usar esto para proporcionar volúmenes de Block Storage de forma dinámica para aplicaciones en contenedores en Kubernetes. Sin embargo, las aplicaciones a veces requieren que los datos persistan y se compartan entre varios Droplets. La solución Block Storage CSI predeterminada de the cloud provider no puede admitir el montaje de un volumen de almacenamiento en bloque en muchos Droplets al mismo tiempo. Esto significa que esta es una solución *ReadWriteOnce* (RWO), ya que el volumen se limita a un nodo. El protocolo Network File System (NFS), por otro lado, sí admite la exportación del mismo intercambio a muchos consumidores. Esto se denomina *ReadWriteMany* (RWX), porque muchos nodos pueden montar el volumen con atributos de lectura y escritura. Por lo tanto, podemos usar un servidor NFS en nuestro clúster para proporcionar almacenamiento que pueda aprovechar el respaldo fiable de the cloud provider Block Storage con la flexibilidad de los intercambios NFS.
En este tutorial, configurará el aprovisionamiento dinámico para volúmenes NFS en un clúster Kubernetes (DOKS) en el cual las exportaciones se almacenan en volúmenes de almacenamiento de the cloud provider Block. A continuación, implementará varias instancias de una aplicación Nginx de demostración y probará el intercambio de datos entre cada instancia.
Requisitos previos
Para completar esta guía, necesitará lo siguiente:
- La interfaz de línea de comandos
kubectlinstalada en su computadora local. Puede obtener más información sobre cómo instalar y configurarkubectlen su documentación oficial.
- Un clúster de Kubernetes de the cloud provider con su conexión configurada como
kubectlpredeterminado. Para crear un clúster de Kubernetes en the cloud provider, consulte nuestra Guía rápida de Kubernetes. Verá las instrucciones para configurarkubectlen el paso Establecer conexión con su clúster cuando cree su clúster.
- El administrador de paquetes de Helm instalado en su computadora local y Tiller instalado en su clúster. Para hacerlo, complete los pasos 1 y 2 del tutorial Cómo instalar software en clústeres de Kubernetes con el administrador de paquetes de Helm.
Nota: Al empezar con Helm versión 3.0, no será necesario que Tiller esté instalado para que Helm funcione. Si usa la versión más reciente de Helm, consulte la documentación para la instalación de Helm para hallar instrucciones.
Paso 1: Implementar el servidor NFS con Helm
Para implementar el servidor NFS, usará un gráfico de Helm. La implementación de un gráfico de Helm es una solución automatizada que es más rápida y está menos expuesta a errores si se compara con la creación manual de la implementación de un servidor NFS.
Primero, asegúrese de que el respositorio de gráficos predeterminado stable esté disponible añadiéndolo:
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
A continuación, extraiga los metadatos del repositorio que acaba de añadir. Esto garantizará que el cliente de Helm está actualizado:
helm repo update
Para verificar el acceso al repositorio stable, realice una búsqueda en los gráficos:
helm search repo stable
Esto le proporcionará una lista de gráficos disponibles similar a la siguiente:
[secondary_label Output]
NAME CHART VERSION APP VERSION DESCRIPTION
stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools
stable/aerospike 0.3.2 v4.5.0.5 A Helm chart for Aerospike in Kubernetes
stable/airflow 5.2.4 1.10.4 Airflow is a platform to programmatically autho...
stable/ambassador 5.3.0 0.86.1 A Helm chart for Datawire Ambassador
...
Este resultado implica que su cliente de Helm se encuentra en ejecución y está actualizado.
Ahora que configuró Helm, instale el gráfico de Helm nfs-server-provisioner para configurar el servidor NFS. Si desea examinar el contenido del gráfico, eche un vistazo a la documentación en GitHub.
Cuando implemente el gráfico de Helm, establecerá algunas variables para su servidor NFS a fin de especificar la configuración de su aplicación. También puede investigar otras opciones de configuración y adaptarlas para que se ajusten a las necesidades de la aplicación.
Para instalar el gráfico de Helm, utilice el siguiente comando:
helm install nfs-server stable/nfs-server-provisioner --set persistence.enabled=true,persistence.storageClass=do-block-storage,persistence.size=200Gi
Este comando proporciona un servidor NFS con las siguientes opciones de configuración:
- Añade un volumen persistente para el servidor NFS con el indicador
--set. Esto garantiza que todos los datos compartidos de NFS persistan al reiniciarse el pod.
- Para el almacenamiento persistente, utiliza la clase de almacenamiento
do-block-storage.
- Proporciona un total de
200Gipara que el servidor NFS pueda dividir exportaciones.
Nota: La opción persistence.size determinará la capacidad total de todos los volúmenes NFS que puede proporcionar. En el momento en que se realizó esta publicación, solo DOKS 1.16.2-do.3 y las versiones posteriores eran compatibles con la expansión de volumen, de modo que la tarea de cambiar el tamaño de este volumen se deberá realizar manualmente si usa una versión anterior. Si este es el caso, asegúrese de establecer este tamaño teniendo en cuenta sus necesidades futuras.
Una vez que este comando se aplique, verá un resultado similar al siguiente:
[secondary_label Output]
NAME: nfs-server
LAST DEPLOYED: Thu Feb 13 19:30:07 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The NFS Provisioner service has now been installed.
A storage class named 'nfs' has now been created
and is available to provision dynamic volumes.
You can use this storageclass by creating a PersistentVolumeClaim with the
correct storageClassName attribute. For example:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-dynamic-volume-claim
spec:
storageClassName: "nfs"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
Para ver el servidor NFS que proporcionó, ejecute el siguiente comando:
kubectl get pods
Con esto, se mostrará lo siguiente:
[secondary_label Output]
NAME READY STATUS RESTARTS AGE
nfs-server-nfs-server-provisioner-0 1/1 Running 0 11m
A continuación, busque el storageclass que creó:
kubectl get storageclass
Con esto, se mostrará un resultado similar al siguiente:
[secondary_label Output]
NAME PROVISIONER AGE
do-block-storage (default) www.progressiverobot.com 90m
nfs cluster.local/nfs-server-nfs-server-provisioner 3m
Ahora, dispondrá de un servidor NFS en ejecución y un storageclass que puede usar para el aprovisionamiento dinámico de volúmenes. A continuación, puede crear una implementación que usará este almacenamiento y lo compartirá entre varias instancias.
Paso 2: Implementar una aplicación usando un PersistentVolumeClaim compartido
A través de este paso, creará una implementación de ejemplo en su clúster DOKS para probar la configuración de su almacenamiento. Esta será una aplicación de servidor web de Nginx llamada web.
Para implementar esta aplicación, primero escriba el archivo YAML a fin de especificar la implementación. Abra un archivo nginx-test.yaml con su editor de texto; en este tutorial se usará nano:
nano nginx-test.yaml
En este archivo, añada las siguientes líneas para definir la implementación con un PersistentVolumeClaim llamado nfs-data:
[label nginx-test.yaml]
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:latest
name: nginx
resources: {}
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: nfs-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: nfs
Guarde el archivo y salga del editor de texto.
Esta implementación se configura para usar el PersistentVolumeClaim nfs-data y montarlo en /data.
En la definición de PVC, verá que el valor de storageClassName es nfs. Esto indica al clúster que satisfaga este almacenamiento usando las reglas de nfs storageClass que creó en el paso anterior. Se procesará el nuevo PersistentVolumeClaim y luego se proporcionará un intercambio NFS para satisfacer la instrucción en forma de volumen persistente. El pod intentará montar ese PVC una vez que se haya proporcionado. Cuando finalice el montaje, verificará la funcionalidad ReadWriteMany (RWX).
Ejecute la implementación con el siguiente comando:
kubectl apply -f nginx-test.yaml
Esto generará el siguiente resultado:
[secondary_label Output]
deployment.apps/web created
persistentvolumeclaim/nfs-data created
A continuación, compruebe que el pod web esté girando:
kubectl get pods
Esto dará el siguiente resultado:
[secondary_label Output]
NAME READY STATUS RESTARTS AGE
nfs-server-nfs-server-provisioner-0 1/1 Running 0 23m
<^>web-64965fc79f-b5v7w 1/1 Running 0 4m<^>
Ahora que la implementación de ejemplo está activa y funcionando, puede escalarla a tres instancias usando el comando kubectl scale:
kubectl scale deployment web --replicas=3
Esto generará el siguiente resultado:
[secondary_label Output]
deployment.extensions/web scaled
Ahora, ejecute el comando kubectl get de nuevo:
kubectl get pods
Encontrará las instancias escaladas de la implementación:
[secondary_label Output]
NAME READY STATUS RESTARTS AGE
nfs-server-nfs-server-provisioner-0 1/1 Running 0 24m
<^>web-64965fc79f-q9626<^> 1/1 Running 0 5m
<^>web-64965fc79f-qgd2w<^> 1/1 Running 0 17s
<^>web-64965fc79f-wcjxv<^> 1/1 Running 0 17s
Con esto, dispondrá de tres instancias de su implementación Nginx conectadas en el mismo Volumen persistente. En el siguiente paso, se asegurará de que puedan compartir datos entre ellas.
Paso 3: Validar el intercambio de datos de NFS
Para el paso final, validará el intercambio de datos entre todas las instancias montadas en el intercambio de NFS. Para hacer esto, creará un archivo en el directorio /data en uno de los pods, y luego verificará que exista en el directorio /data de otro pod.
Para validar esto, usará el comando kubectl exec. Este comando le permite especificar un pod y luego aplicar un comando dentro de él. Para obtener más información sobre cómo inspeccionar recursos usando kubectl, vea nuestra ficha de ayuda de kubectl.
Si desea crear un archivo llamado hello_world en uno de sus pods web, utilice kubectl exec para pasar el comando touch. Tenga en cuenta que el número después de web en el nombre del pod será diferente para usted. Por lo tanto, asegúrese de sustituir el nombre resaltado del pod por uno de sus propios pods que encontró en el resultado de kubectl get pods del último paso.
kubectl exec <^>web-64965fc79f-q9626<^> -- touch /data/hello_world
A continuación, cambie el nombre del pod y utilice el comando ls para listar los archivos en el directorio /data de un pod diferente:
kubectl exec <^>web-64965fc79f-qgd2w<^> -- ls /data
Su resultado mostrará el archivo que creó en el primer pod:
[secondary_label Output]
hello_world
Esto muestra que todos los pods comparten datos usando NFS y que su configuración funciona correctamente.
Conclusión
A lo largo de este tutorial, creó un servidor NFS respaldado por the cloud provider Block Storage. El servidor NFS luego usó ese almacenamiento en bloque para proporcionar y exportar intercambios de NFS a cargas de trabajo en un protocolo compatible con RWX. Al hacer esto, pudo solventar una limitación técnica del almacenamiento en bloque de the cloud provider y compartir los mismos datos de PVC en muchos pods. Una vez completado este tutorial, su clúster DOKS quedará configurado para contemplar un conjunto mucho más amplio de casos de uso de implementación.
Si desea obtener más información sobre Kubernetes, vea nuestro programa de Kubernetes para desarrolladores “full-stack” o consulte la documentación del producto para Kubernetes de the cloud provider.