Blog de Amazon Web Services (AWS)

Desplegando un Almacenamiento de Objetos compatible con S3 en Las Zonas Locales de AWS

Por Leonardo Solano, Senior Hybrid Cloud Solution Architect, Cloud Acceleration Team-Latam

Con el anuncio de la expansión global de las Zonas Locales de AWS, se abre la posibilidad de migrar cargas de trabajo que habían estado restringidas a infraestructura on-premises debido a requerimientos de latencia, residencia de datos u otros requerimientos de procesamiento de datos locales. Las Zonas Locales disponibles actualmente cuentan en su gran mayoría con servicios como Amazon Elastic Compute Cloud (EC2), Amazon Elastic Block Storage (EBS), Amazon Elastic Container Service (ECS), Amazon Elastic Kubernetes Service (EKS), Amazon Virtual Private Cloud (VPC) y Elastic Load Balancing (ELB), sin embargo, existen necesidades en algunas empresas de contar con capacidades de almacenamiento de objetos como el provisto por el servicio Amazon Simple Storage Service (S3). Entre los casos de uso se puede encontrar soluciones de respaldo, almacenamiento de objetos estáticos para portales web, o archivado de datos.

El almacenamiento de objetos S3 se encuentra de manera nativa en las regiones de AWS, mas no en las Zonas Locales (al momento de la publicación de este blogpost). Para su uso en las Zonas Locales es posible utilizar soluciones de software de terceros disponibles en el AWS Marketplace, como la presentada en este blog post. Hybrid Cloud Object Storage es una solución de almacenamiento de objetos distribuida de alto rendimiento que puede ser desplegada  sobre instancias de EC2 con volúmenes EBS y es mantenida y soportada directamente por MinIO.

Descripción de la Solución

El objetivo de este blogposts es describir el proceso para  desplegar la solución de Hybrid Cloud Object Storage de MinIO sobre instancias EC2 en una Zona local de AWS, esto debido a que a la fecha de escritura de este blogposts el servicio de Almacenamiento de Objetos Nativo de AWS Amazon S3 no se encuentra disponible en las Zonas Locales de AWS anunciadas re:invent de 2021.

En este blogpost se describe paso a paso cómo desplegar la solución de almacenamiento de objetos de MinIO en modo distribuido en una Zona Local de AWS, además de explicar cómo se interactúa con esta solución, usando el CLI de AWS.

La arquitectura a implementar en este blogpost es la siguiente:

Prerequisitos

  • Cuenta de AWS.
  • Credenciales de administrador.
  • VPC en la región de la que depende la Zona Local.

En esta arquitectura se desplegará el Modo Distribuido de MinIO en instancias EC2, dentro de una Zona Local de AWS. Esta arquitectura contará con 2 nodos en el cluster de MinIO y cada nodo contará con 4 volúmenes EBS de 8GB tipo GP2. De acuerdo a la guía de implementación de MinIO en el modo distribuido el cluster debe tener una cantidad de discos múltiplo de 2.

Para poder preparar el ambiente es indispensable contar con una VPC con Subnets extendidas hacia una Zona Local. Para este ejemplo se cuenta con una VPC en la región de la cual depende la Zona Local con un CIDR 10.0.0.0/16.

Posteriormente, será necesario crear dos Subnets en la Zona Local: una pública y una privada para mantener un nivel de aislamiento para una carga de trabajo que se expone a Internet.

Las instancias EC2 de MinIO serán desplegadas en una Subnet privada y serán accesibles para administración a través de una Jump Box desplegada en la Subnet pública. Finalmente, es necesario asociar un Gateway de Internet en el VPC y modificar la tabla de enrutamiento asociada a la Subnet Pública con una ruta 0.0.0.0/0 direccionando al Gateway de Internet.

Creación de la Subnet Pública en la consola de AWS:

Creación de la Subnet Privada en la consola de AWS:

Implementación

A continuación se describe a grandes rasgos los pasos requeridos para desplegar la solución de MinIO, estos serán detallados en el resto de esta publicación.

  • Crear dos instancias EC2 tipo t3.medium en la consola de AWS con al menos 4 volúmenes EBS (ver guía de MinIO de despliegue Distribuido de MinIO) adicionales al volumen de boot.
  • Acceder via SSH cada una de las instancias y modificar el archivo /etc/hosts para agregar las direcciones IP de cada Host del cluster, paso requerido para el despliegue Distribuido de MinIO.
  • Crear los directorios de montaje de cada una de las unidades que serán usadas por MinIO para almacenar los objetos, darles formato, montar las unidades y garantizar permisos de escritura y lectura en los folders de montaje.
  • Iniciar el servicio de MinIO en los dos nodos usando algunos parámetros que describiremos en un momento.
  • Configurar un Balanceador de carga de Aplicaciones o ALB y crear un target-group para permitir el balanceo del Front-End. Adicionalmente crearemos otro target-group para el acceso API de MinIO.
  • Usar el almacenamiento de objetos vía la consola web y vía el CLI de AWS para S3, para comprobar el funcionamiento de la solución.

Pre-requisitos:

  • Todos los nodos del cluster deben usar las mismas credenciales de root de Minio, lo cual se garantiza usando las variables de ambiente MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
  • El número total de discos en el cluster debe ser múltiplo de 2
  • Todos los nodos corriendo el modo distribuido de MinIO deben ser homogéneos, mismo sistema operativo, mismo número de discos y las mismas interconexiones de red.
  • La solución MinIO en modo distribuido requiere que no exista un defase de sincronización horaria mayor a 15 minutos entre las instancias que integran el cluster. Si se quiere garantizar mayor exactitud, se recomienda usar un servicio de NTP. Para instancias Amazon Linux 2 y Ubuntu la sincronización de hora no requiere administración adicional pues por defecto se sincroniza utilizando los relojes de Amazon Time Sync Service. Para mas detalles ver: EC2 Set Time.
  • Haber ejecutado previamente el proceso de opt-in de la Zona Local, diligenciando esta forma.
  • Haber habilitado la Zona Local en EC2-Settings en la opción “Manage”:

aws ec2 describe-instance-type-offerings --location-type "availability-zone"

 --filters Name=location,Values=<Zonename>

En el campo <Zonename> se debe indicar el nombre de la zona local, en este caso us-east-1-mia-1a.

Proceso de Implementación de MinIO:

  1. Iniciar instancias EC2.
  • Validar que el tipo de instancia se encuentre disponible en la Zona Local a utilizar.
  • Definir como nombre “MinIO-Server-Nodes” y en QuickStart seleccionar Ubuntu, y escoger el AMI Ubuntu Server 18.04 (Conforme a la guía de Soporte de Plataformas en MinIO).

  • Seleccionar el tipo de instancia EC2 como t3.medium.
  • Ingresar la cantidad de 2 en número de instancias.
  • Crear un nuevo “key-pair” para accesar a la instancia de forma segura vía SSH.
  • Seleccionar el VPC ID donde fueron creadas las Subnets de la Zona Local y finalmente escoger la Subnet Privada y mantener deshabilitada la asignación automática de direcciones IP.

  • En la sección del grupo de seguridad deberá habilitarse el puerto TCP 9000 de ingreso desde cualquier IP, el cual será usado para el acceso al API de S3. También deberá habilitarse el puerto TCP 40000 para el acceso de la consola web.

  • Agregamos 4 volumes (adicionales al root volumen) de 8 GB cada uno de la familia gp2. Finalmente, presionar el botón Launch Instance.

  • Ahora con las instancias ya ejecutándose, será necesario tomar nota de las direcciones IP privadas de las dos instancias MinIO-Server. En este caso son:

host1-10.0.3.140,host2-10.0.3.146

  1. En el JumpBox será necesario cargar en el directorio raíz el archivo “.pem“ que se generó al momento de la creación de las instancias EC2, y darle los permisos necesarios al archivo ( chmod 400 xxxxx.pem). El Jumpbox puede ser una instancia EC2 Amazon Linux 2 de tamaño t3.medium, desplegada en la subnet pública de la Zona Local de AWS.
  2. Acceder via SSH cada una de las instancias y modificar el archivo /etc/hosts para agregar las direcciones IP de cada Host del cluster, esto con el fin de que, al iniciar el servicio de MinIO, los nodos del cluster se puedan ver entre sí:
ssh -i "minio.pem" ubuntu@10.0.3.140

ssh -i "minio.pem" ubuntu@10.0.3.146



ubuntu@ip-10-0-3-146:~$ vim /etc/hosts

host1 10.0.3.140

host2 10.0.3.146
  1. Montar los volúmenes EBS en folders de montaje que después usaremos para lanzar el cluster de MinIO, además de darle formato xfs a cada unidad:
  • Crear los directorios donde se van a mapear los volúmenes de EBS asignados a cada instancia del cluster , tecleando los siguientes comandos:
sudo mkdir /mnt/data1

sudo mkdir /mnt/data2

sudo mkdir /mnt/data3

sudo mkdir /mnt/data4
  • Listamos los volúmenes asociados en las 4 del cluster instancias con el fin de identificar el nombre de cada uno, para después realizar tanto para dar formato y hacer el montaje de cada volumen en las instancias:
ubuntu@ip-10-0-3-146:~$ lsblk

NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT

loop0          7:0    0   47M  1 loop /snap/snapd/16010

loop1          7:1    0 55.5M  1 loop /snap/core18/2409

loop2          7:2    0 25.1M  1 loop /snap/amazon-ssm-agent/5656

nvme1n1      259:0    0    8G  0 disk 

nvme3n1      259:1    0    8G  0 disk 

nvme2n1      259:2    0    8G  0 disk 

nvme4n1      259:3    0    8G  0 disk 

nvme0n1      259:4    0    8G  0 disk

├─nvme0n1p1  259:5    0  7.9G  0 part /

├─nvme0n1p14 259:6    0    4M  0 part

└─nvme0n1p15 259:7    0  106M  0 part /boot/efi
  • Damos formato XFS a cada volumen:
sudo mkfs -t xfs /dev/nvme1n1

sudo mkfs -t xfs /dev/nvme2n1

sudo mkfs -t xfs /dev/nvme3n1

sudo mkfs -t xfs /dev/nvme4n1
  • Montamos los volúmenes a la instancia:
sudo mount /dev/nvme1n1 /mnt/data1

sudo mount /dev/nvme2n1 /mnt/data2

sudo mount /dev/nvme3n1 /mnt/data3

sudo mount /dev/nvme4n1 /mnt/data4
  • Modificamos los permisos de escritura y lectura de los folders creados para cada volumen:
sudo chmod ugo+rwx /mnt/data1

sudo chmod ugo+rwx /mnt/data2

sudo chmod ugo+rwx /mnt/data3

sudo chmod ugo+rwx /mnt/data4
  1. Ahora vamos a iniciar el servicio de MinIO desde el Shell siguiendo estos pasos:
  • Primero debemos crear credenciales de acceso a MinIO, mediante las variables de ambiente en Linux en los dos nodos:
MINIO_ROOT_USER=minioadmin

MINIO_ROOT_PASSWORD=minioadmin123#
  • Ahora debemos descargar el instalador de MinIO:
wget https://dl.min.io/server/minio/release/linux-amd64/minio

chmod +x minio

  • Ahora lanzamos MinIO definiendo el listado de servidores, sumado a los nombres de los discos a usar. Adicionalmente definimos el puerto TCP a usar para acceso a la consola web de MinIO en cada uno de los nodos del cluster así:
./minio server http://host{1...2}/mnt/data{1...4} --console-address :40000
El rango host{1…2} se refiere a los dos nodos que hemos lanzado com instancias EC2 y que han sido definidos en el archivo /etc/hosts. Adicionalmente el rango /mnt/data{1…4} describe los 4 folders de montaje asociados a los volúmenes EBS asociados a cada instancia EC2. Si se tienen mas servidores o más discos, el comando debe ser modificado siempre separando con 3 puntos (…) los valores que varían.
  • Con el fin de dejar corriendo el proceso de minio en background, podemos enviar un “ctrl + z” en el Shell de Linux y después enviar a background el proceso con “bg”. Para ambientes productivos se sugiere usar un config file con SystemD como se indica en este blog de MinIO

  1. Configurar un ALB y target group para permitir el balanceo del front-end de MinIO. Dado que el cluster de MinIO está compuesto de dos o mas instancias en el modo distribuido, el front-end está ejecutándose de forma concurrente en cada uno de los nodos del cluster, por lo que es requerido desplegar un Load Balancer en frente los nodos del cluster tanto para el uso de la consola Web como para acceso de los llamados vía API. En este sentido, el lanzamiento del cluster se ha realizado por el puerto TCP 40000 para la consola web, y se ha dejado por defecto el acceso vía API por el puerto TCP 9000, el cual mas adelante será usado para consumir los buckets de MinIO desde el AWS CLI para S3.:
  • Debemos crear un Target Group para acceso a la consola Web. En este caso como hemos dedicido lanzar el cluster usando el purto TCP 40000, estre será el mismo puerto usado en el Target Group. Tambien debemos registrar las instancias EC2 donde hemos instalado MinIO. Este Target-Group lo llamaremos “MinIO-Cluster”.

  • Adicionalmente crearemos otro Target Group para acceso vía API a los buckets de MinIO. Por defecto el puerto de APIs de MinIO es el puerto TCP 9000, el mismo que usaremos en el Target Group, registrando las mismas instancias EC2 donde hemos instalado MinIO. Este Target-Group lo llamaremos “MinIO-Cluster-API”.

  • Ahora registramos como target, las instancias de MinIO-Server creados previamente, inicialmente para puerto TCP 40000. Este proceso se debe repetir para el puerto TCP 9000 para poder incluir el nombre del ALB como endpoint de S3 en las pruebas usando AWS CLI.

  • Adicionalmente creamos un ALB escuchando tanto en puerto TCP 40000 como en el puerto 9000 y hacemos forwarding desde el ALB hacia las instancias del Front-End usando los “target-group” creados previamente. En nuestro caso el nombre del ALB será “MinIO-ALB”. En este mismo paso debemos seleccionar el VPC donde tenemos extendidas las subnets hacia la Zona Local de AWS, en este caso Miami (us-east-1-mia-1a).

  • Finalmente, en el campo “listener” vamos a definir  el puerto de escucha como  TCP 40000 y hacemos forwarding hacia el Target-Group que creamos en los pasos anteriores.

  1. Ahora estamos listos para acceder la consola web de MinIO. En este escenario la vamos a acceder usando el nombre de dominio asignado al ALB, en este caso http://minio-alb-XXXXXXX-us.east-1.elb.amazonaws.com:40000 , el cual se encuentra en la consola de AWS > EC2> Load Balancer – Seleccionamos el ALB llamado MinIO-ALB y en el Tab “Description” encontramos en el campo DNS name el FQDN a usar para probar el acceso a la consola Web de MinIO.. Como credenciales de acceso usamos las que se definieron al momento de lanzar el servicio en el paso 4.

  • Vamos ahora a crear un Bucket donde copiaremos los objetos de pruebas desde la máquina local hacia MinIO:

  • Vamos a asignar el nombre “myfirstbucket”, el cual debe ser único dentro del cluster de MinIO y habilitaremos opcionalmente Versioning y Retention (180 dias).

  • Finalmente usando el mismo endpoint de acceso a la consola web pero con puerto TCP 9000 vamos a agregar objetos al Bucket previamente creado, usando un AccessKey y SecretKey que generaremos desde la consola web de MinIO así:
    • Primero creamos el usuario “user1” y le asignamos un password

    • Ahora asignamos un Service Account al usuario, para poder accederlo desde el CLI de AWS.

  • En este punto ya se tiene un AccessKey y un SecretKey

  • Se descargan las credenciales y vamos a subir un (1) archivo de pruebas desde la maquina local usando el AWS CLI para S3 , usando las credenciales recientemente creadas en MinIO las cuales configuraremos mediante el Shell en AWS CLI con  “aws configure”:
  • Para usar la AWS CLI para S3 debemos ejecutar los siguientes comandos:
aws configure set default.s3.signature_version s3v4




aws --endpoint-url https://minio-alb-XXXXXXX.us-east-1.elb.amazonaws.com:9000 s3 ls

Salida:

2022-06-29 16:32:23 myfirstbucket
  • Ahora vamos a subir un archivo de pruebas desde la máquina local hasta el bucket llamado 1GB.bin:
aws --endpoint-url http://minio-alb-XXXXXXX.us-east-1.elb.amazonaws.com:9000 s3 cp 1GB.bin s3://myfirstbucket

Salida:

Completed 23.8 MiB/1000.0 MiB (3.0 MiB/s) with 1 file(s) remaining 

upload: ./1GB.bin to s3://myfirstbucket/1GB.bin
  • Finalmente vamos a validar en la consola web de MinIO el Bucket y el objeto que recientemente cargamos via AWS CLI.

Borrado de la solución

Para borrar la solución se deben seguir los siguientes pasos:

  • Eliminar el ALB que se creó en los pasos anteriores
  • Eliminar los Target-Groups
  • Eliminar las instancias EC2 creadas como parte del cluster de MinIO
  • Eliminar el Jump Box

 

 

Conclusión

Con la expansión global de las Zonas Locales de AWS, teniendo MinIO desplegado como almacenamiento de objetos sobre EC2 compatible con el API de S3, los clientes podrán desplegar casos de uso como Backup, almacenamiento de objetos y archivado de contenido usando funcionalidades como Versionamiento y políticas de retención, además que con la posibilidad de desplegar el modo distribuido las empresas podrán tener una solución compatible con S3 API mucho mas robusta,  soportada en EC2 y en EBS en las zonas metropolitanas donde se han desplegado y anunciado Zonas Locales de AWS.


Acerca do autor

Leonardo Solano es un arquitecto de soluciones de Nube Híbrida en AWS con mas de 20 años de experiencia en el mundo de la Tecnología, obsesionado por brindar a nuestros clientes soluciones innovadoras soportadas en los mas de 200 servicios de AWS. Cuando no está estudiando, está tocando canciones para sus hijos en el Ukulele.