One place for hosting & domains

      Cómo crear un grupo de almacenamiento redundante con GlusterFS en Ubuntu 20.04


      Justin Ellingwood escribió una versión anterior de este tutorial.

      Introducción

      Al almacenar datos cruciales, tener un punto único de fallo es muy arriesgado. Si bien muchas bases de datos y otros software permiten extender los datos en el contexto de una sola aplicación, otros sistemas pueden operar a nivel del sistema de archivos para garantizar que los datos se copien a otra ubicación cuando se escribe en disco.

      GlusterFS es un sistema de archivos de almacenamiento conectado a la red que le permite agrupar recursos de almacenamiento de varias máquinas. A su vez, esto permite manipular diversos dispositivos de almacenamiento que se distribuyen entre muchas computadoras como una unidad única y más potente. GlusterFS también faculta la creación de diferentes tipos de configuraciones de almacenamiento, muchas de las cuales son similares en cuanto a funcionalidad a los niveles de RAID. Por ejemplo, puede segmentar datos en diferentes nodos del clúster o implementar la redundancia para obtener una mejor disponibilidad de datos.

      Objetivos

      En esta guía, creará una matriz de almacenamiento agrupada y redundante, también conocida como sistema de archivos distribuidos, o como se la denomina en la documentación de GlusterFS, un grupo de almacenamiento de confianza. Esto proporcionará una funcionalidad similar a una configuración RAID en espejo a través de la red: cada servidor independiente contendrá una copia propia de los datos, lo que permitirá que sus aplicaciones puedan acceder a cualquier copia, y de este modo, contribuirá a la distribución de la carga de lectura.

      Este clúster redundante de GlusterFS consistirá en dos servidores Ubuntu 20.04. Actuará de manera similar a un servidor NAS con RAID en espejo. Después, podrá acceder al clúster desde un tercer servidor Ubuntu 20.04 que se configurará para funcionar como cliente de GlusterFS.

      Nota sobre cómo ejecutar GlusterFS de manera segura

      Cuando se agregan datos a un volumen de GlusterFS, esos datos se sincronizan con cada máquina del grupo de almacenamiento donde se aloja el volumen. Por defecto, el tráfico entre nodos no está cifrado, lo que significa que existe un riesgo de que agentes malintencionados los intercepten.

      Debido a esto, si planea utilizar GlusterFS con fines productivos, se recomienda que lo ejecute en una red aislada. Por ejemplo, podría configurarlo para ejecutar en una nube privada virtual (VPC) o con una VPN que se ejecute entre cada nodo.

      Si planea implementar GlusterFS en DigitalOcean, puede configurarlo en una red aislada agregando la infraestructura de su servidor a una nube privada virtual de DigitalOcean. Para obtener información sobre cómo configurarlo, consulte nuestra documentación sobre productos de VPC.

      Requisitos previos

      Para seguir este tutorial, necesitará tres servidores que ejecuten Ubuntu 20.04. Cada servidor debe tener un usuario no root con privilegios administrativos y un firewall configurado con UFW. Para configurar esto, siga la guía de configuración inicial de servidores para Ubuntu 20.04.

      Nota: Como se indica en la sección de objetivos, este tutorial le servirá como guía para configurar dos de los servidores Ubuntu para que actúen como servidores en su grupo de almacenamiento y el otro para actuar como cliente, el cual utilizará para acceder a estos nodos.

      Para mayor claridad, en este tutorial se hará referencia a estas máquinas con los siguientes nombres de host:

      Nombre de host Función en el grupo de almacenamiento
      gluster0 Servidor
      gluster1 Servidor
      gluster2 Cliente

      Los comandos que deban ejecutarse en gluster0 o gluster1 aparecerán sobre fondos azul y rojo, respectivamente:

      Los comandos que solo deban ejecutarse en el cliente (gluster2) aparecerán sobre un fondo verde:

      Los comandos que puedan o deban ejecutarse en más de una máquina aparecerán sobre un fondo gris:

      Paso 1: Configurar la resolución DNS en cada máquina

      Configurar algún tipo de resolución de nombres de host entre cada equipo puede ayudar a administrar el grupo de almacenamiento de Gluster. De esta manera, cuando en este tutorial tenga que hacer referencia a una de las máquinas en un comando gluster, puede utilizar un nombre de dominio fácil de recordar o incluso un sobrenombre en vez de las respectivas direcciones IP.

      Si no tiene un nombre de dominio extra, o si solo quiere realizar una configuración rápida, en su lugar puede modificar el archivo /etc/hosts en cada computadora. Este es un archivo especial en las máquinas Linux en el que puede configurar de forma estática el sistema para que establezca cualquier nombre de host que figure en el archivo como direcciones IP estáticas.

      Nota: Si quiere configurar los servidores para que se autentiquen con un dominio de su propiedad, primero deberá obtener un nombre de dominio de un registrador de dominios (como Namecheap o Enom) y configurar los registros DNS apropiados.

      Una vez que haya configurado un registro A para cada servidor, puede ir directamente al paso 2. A medida que sigue esta guía, asegúrese de sustituir glusterN.example.com y glusterN con el nombre de dominio que se convierte al servidor correspondiente al que se hace referencia en el comando de ejemplo.

      Si obtuvo la infraestructura de DigitalOcean, podría agregar el nombre de dominio a DigitalOcean y, luego, configurar un registro A único para cada uno de los servidores.

      Con su editor de texto preferido, abra este archivo con privilegios root en cada una de las máquinas. En este caso, utilizaremos nano:

      De forma predeterminada, el archivo tendrá el siguiente aspecto sin los comentarios:

      /etc/hosts

      127.0.1.1 hostname hostname
      127.0.0.1 localhost
      
      ::1 ip6-localhost ip6-loopback
      fe00::0 ip6-localnet
      ff00::0 ip6-mcastprefix
      ff02::1 ip6-allnodes
      ff02::2 ip6-allrouters
      ff02::3 ip6-allhosts
      

      En uno de los servidores Ubuntu, agregue la dirección IP de cada servidor seguida de cualquier nombre que quiera utilizar para referirse a ellos en los comandos que se encuentran debajo de la definición del host local.

      En el siguiente ejemplo, se proporciona a cada servidor un nombre de host largo que coincide con glusterN.example.com y uno corto que coincide con glusterN. Puede cambiar la parte de glusterN.example.com y glusterN de cada línea por cualquier nombre (o nombres separados por espacios individuales) que le gustaría utilizar para acceder a cada servidor. Sin embargo, tenga en cuenta que a lo largo de este tutorial se utilizarán los siguientes ejemplos:

      Nota: Si los servidores son parte de un grupo de infraestructura de la nube privada virtual, en el archivo /etc/hosts debería utilizar la dirección IP privada de cada servidor en vez de sus IP públicas.

      /etc/hosts

      . . .
      127.0.0.1       localhost
      first_ip_address gluster0.example.com gluster0
      second_ip_address gluster1.example.com gluster1
      third_ip_address gluster2.example.com gluster2
      
      . . .
      

      Cuando haya terminado de agregar estas nuevas líneas en el archivo /etc/hosts de una máquina, cópielas y agréguelas en los archivos /etc/hosts de las otras máquinas. Cada archivo /etc/hosts debería contener las mismas líneas, lo que vincula las direcciones IP de los servidores con los nombres que seleccionó.

      Guarde y cierre cada archivo cuando haya terminado. Si utiliza nano, podrá hacerlo presionando CTRL + X, Y y, luego, ENTER.

      Ahora que ha configurado la resolución de nombres de host entre cada servidor, será más sencillo ejecutar los comandos más adelante cuando configure un grupo y un volumen de almacenamiento. A continuación, realizará otro paso que debe completarse en cada uno de los servidores. Concretamente, agregará el archivo de paquetes personal (PPA) oficial del proyecto Gluster a cada uno de los tres servidores Ubuntu para garantizar que pueda instalar la versión más reciente de GlusterFS.

      Paso 2: Configurar las fuentes de software en cada máquina

      Si bien los repositorios APT predeterminados de Ubuntu 20.04 contienen paquetes de GlusterFS, al momento de escribir este artículo, no se trata de las versiones más recientes. Una forma de instalar la versión estable más reciente de GlusterFS (versión 7.6, al momento de redactar este artículo) es agregar el PPA oficial del proyecto Gluster a cada uno de los tres servidores Ubuntu.

      Ejecute el siguiente comando en cada servidor para agregar el PPA para los paquetes de GlusterFS:

      • sudo add-apt-repository ppa:gluster/glusterfs-7

      Cuando se le solicite, presione ENTER para confirmar que realmente quiere agregar el PPA.

      Tras agregar el PPA, actualice el índice local de paquetes de cada servidor. Esto hará que cada servidor sea informado sobre la presencia de los nuevos paquetes disponibles:

      Una vez que agregó el PPA oficial del proyecto Gluster a cada servidor y que actualizó el índice local de paquetes, está listo para instalar los paquetes necesarios de GlusterFS. Sin embargo, dado que dos de las tres máquinas actuarán como servidores de Gluster y la otra como cliente, existen dos procedimientos de instalación y configuración distintos. Primero, instalará y configurará los componentes del servidor.

      Paso 3: Instalar los componentes del servidor y crear un grupo de almacenamiento de confianza

      Un grupo de almacenamiento es toda capacidad de almacenamiento agregada a partir de dos o más recursos de almacenamiento. En este paso, configurará dos de los servidores (gluster0 y gluster1) como componentes del clúster.

      Escriba lo siguiente para instalar el paquete de servidor de GlusterFS en gluster0 y gluster1:

      • sudo apt install glusterfs-server

      Cuando se le solicite, presione Y y, luego, ENTER para confirmar la instalación.

      De manera automática, el proceso de instalación configura GlusterFS para que se ejecute como un servicio systemd. Sin embargo, no inicia automáticamente el servicio ni lo habilita para ejecutarse en el arranque.

      Para iniciar glusterd, el servicio de GlusterFS, ejecute el siguiente comando systemctl start en gluster0 y gluster1:

      • sudo systemctl start glusterd.service

      Luego, ejecute el siguiente comando en ambos servidores. Esto permitirá que el servicio se inicie cuando arranque el servidor:

      • sudo systemctl enable glusterd.service

      A continuación, puede verificar el estado del servicio en uno o en ambos servidores:

      • sudo systemctl status glusterd.service

      Si el servicio está activo y en ejecución, recibirá un resultado similar al siguiente:

      Output

      ● glusterd.service - GlusterFS, a clustered file-system server Loaded: loaded (/lib/systemd/system/glusterd.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-02 21:32:21 UTC; 32s ago Docs: man:glusterd(8) Main PID: 14742 (glusterd) Tasks: 9 (limit: 2362) CGroup: /system.slice/glusterd.service └─14742 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO

      Suponiendo que cumplió con los requisitos previos de la guía de configuración inicial de servidores, habrá configurado un firewall con UFW en cada una de las máquinas. Debido a esto, deberá abrir el firewall en cada nodo para poder establecer comunicaciones entre ellos y crear un grupo de almacenamiento.

      El demonio de Gluster utiliza el puerto 24007, por lo que deberá permitir que cada nodo tenga acceso a ese puerto a través del firewall de cada uno de los otros nodos en su grupo de almacenamiento. Para hacerlo, ejecute el siguiente comando en gluster0. Recuerde cambiar gluster1_ip_address por la dirección IP de gluster1:

      • sudo ufw allow from gluster1_ip_address to any port 24007

      Y ejecute el siguiente comando en gluster1. Una vez más, asegúrese de cambiar gluster0_ip_address por la dirección IP de gluster0:

      • sudo ufw allow from gluster0_ip_address to any port 24007

      También deberá permitir que su máquina cliente (gluster2) tenga acceso a este puerto. De lo contrario, surgirán problemas más adelante cuando intente montar el volumen. Ejecute el siguiente comando tanto en gluster0 como en gluster1 para habilitar el acceso de su máquina cliente a este puerto:

      • sudo ufw allow from gluster2_ip_address to any port 24007

      A continuación, para garantizar que ninguna otra máquina pueda acceder al puerto de Gluster en ninguno de los servidores, agregue una norma general deny tanto en gluster0 como en gluster1:

      Ahora está listo para establecer la comunicación entre gluster0 y gluster1. Para hacerlo, deberá ejecutar el comando gluster peer probe en uno de los nodos. No importa qué nodo utilice, pero en el siguiente ejemplo se muestra la ejecución del comando en gluster0:

      • sudo gluster peer probe gluster1

      Básicamente, este comando le indica a gluster0 que confíe en gluster1 y que lo registre como parte de su grupo de almacenamiento. Si el sondeo es exitoso, devolverá el siguiente resultado:

      Output

      peer probe: success

      Para verificar en cualquier momento la comunicación entre los nodos, puede ejecutar el comando gluster peer status en cualquiera de los dos. En este ejemplo, se ejecuta en gluster1:

      Si ejecuta este comando desde gluster1, mostrará el resultado de la siguiente manera:

      Output

      Number of Peers: 1 Hostname: gluster0.example.com Uuid: a3fae496-c4eb-4b20-9ed2-7840230407be State: Peer in Cluster (Connected)

      En este momento, los dos servidores están comunicados y listos para crear volúmenes de almacenamiento entre sí.

      Paso 4: Crear un volumen de almacenamiento

      Recuerde que el objetivo principal de este tutorial es crear un grupo de almacenamiento redundante. Para ello, configurará un volumen con funcionalidad de réplica, lo que le permitirá mantener varias copias de los datos y evitar que el clúster tenga un punto único de fallo.

      Utilizará el comando gluster volume create con la siguiente sintaxis general para crear un volumen:

      sudo gluster volume create volume_name replica number_of_servers domain1.com:/path/to/data/directory domain2.com:/path/to/data/directory force
      

      A continuación, se describe el significado de los argumentos y las opciones del comando gluster volume create:

      • volume_name: Este es el nombre que utilizará para referirse al volumen una vez que lo haya creado. El siguiente comando de ejemplo crea un volumen denominado volume1.
      • replica number_of_servers: Después del nombre del volumen, puede definir el tipo de volumen que quiere crear. Recuerde que el objetivo de este tutorial es crear un grupo de almacenamiento redundante, por lo que utilizaremos el tipo de volumen replica. Se requiere un argumento que indique en cuántos servidores se replicarán los datos del volumen (en este caso, 2).
      • domain1.com:/… y domain2.com:/…: Estos definen las máquinas y la ubicación del directorio de los bricks (ladrillos) que constituirán volume1. Brick o ladrillo es el término que se utiliza en GlusterFS para hacer referencia a su unidad básica de almacenamiento, que incluye cualquier directorio o máquina que sirva como parte o copia de un volumen mayor. El siguiente ejemplo creará un directorio denominado gluster-storage en el directorio raíz de ambos servidores.
      • force: Esta opción anulará cualquier advertencia u opción que de otro modo podría surgir y detener la creación del volumen.

      Siguiendo las convenciones que se establecieron anteriormente en este tutorial, puede ejecutar este comando para crear un volumen. Tenga en cuenta que puede ejecutarlo desde gluster0, o bien desde gluster1:

      • sudo gluster volume create volume1 replica 2 gluster0.example.com:/gluster-storage gluster1.example.com:/gluster-storage force

      Si el volumen se creó correctamente, obtendrá el siguiente resultado:

      Output

      volume create: volume1: success: please start the volume to access data

      En este punto, el volumen se ha creado pero aún no está activo. Puede iniciar el volumen y habilitarlo para su uso ejecutando el siguiente comando, desde cualquiera de los servidores de Gluster:

      • sudo gluster volume start volume1

      Si el volumen se inició correctamente, verá el siguiente resultado:

      Output

      volume start: volume1: success

      A continuación, compruebe que el volumen está en línea. Ejecute el siguiente comando desde cualquiera de los dos nodos:

      • sudo gluster volume status

      Esto devolverá un resultado similar al siguiente:

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 18801 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19028 Self-heal Daemon on localhost N/A N/A Y 19049 Self-heal Daemon on gluster0.example.com N/A N/A Y 18822 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

      Según este resultado, los ladrillos en ambos servidores están en línea.

      Como paso final para configurar el volumen, deberá abrir firewall en ambos servidores para que su máquina cliente pueda conectarse y montar el volumen. El resultado de muestra del comando anterior muestra que volume1 se está ejecutando en el puerto 49152 en ambas máquinas. Este es el puerto predeterminado de GlusterFS para su volumen inicial, y el siguiente volumen que cree utilizará el puerto 49153, y el siguiente el puerto 49154, y así sucesivamente.

      Ejecute el siguiente comando en gluster0 y gluster1 para permitir que gluster2 acceda a este puerto a través del firewall de cada uno:

      • sudo ufw allow from gluster2_ip_address to any port 49152

      A continuación, para tener una capa de seguridad adicional, agregue otra norma general deny para el puerto del volumen tanto en gluster0 como en gluster1. Esto garantizará que, en cualquiera de los servidores, solo su máquina cliente pueda acceder al volumen:

      Ahora que el volumen está activo y en ejecución, puede configurar la máquina cliente y comenzar a utilizarla de forma remota.

      Paso 5: Instalar y configurar los componentes del cliente

      El volumen ahora está configurado y disponible para que la máquina cliente lo utilice. Sin embargo, antes de comenzar, debe instalar el paquete glusterfs-client desde el PPA que configuró en su máquina cliente en el paso 1. Las dependencias de este paquete incluyen algunas de las bibliotecas y los módulos de traducción comunes de GlusterFS, como así también las herramientas de FUSE necesarias para que funcione.

      Ejecute el siguiente comando en gluster2:

      • sudo apt install glusterfs-client

      En breve, montará el volumen de almacenamiento remoto en el equipo cliente. Sin embargo, antes debe crear un punto de montaje. Generalmente, se ubica en el directorio /mnt, pero puede utilizarse cualquier lugar conveniente.

      Para simplificar, cree un directorio denominado /storage-pool en la máquina cliente para que sirva como el punto de montaje. El nombre de este directorio comienza con una barra diagonal (/) que lo ubica en el directorio raíz, por lo que deberá crearlo con privilegios sudo:

      Ahora puede montar el volumen remoto. Antes, sin embargo, observe la sintaxis del comando mount que utilizará para hacerlo:

      sudo mount -t glusterfs domain1.com:volume_name /path/to/mount/point
      

      mount es una utilidad que se encuentra en muchos sistemas operativos similares a Unix. Se utiliza para montar sistemas de archivos (desde dispositivos de almacenamiento externos, como tarjetas SD o dispositivos USB hasta almacenamiento conectado a la red, como es el caso de este tutorial) a los directorios en el sistema de archivos existente de la máquina. La sintaxis del comando mount que utilizará incluye la opción -t, que requiere tres argumentos: el tipo de sistema de archivos que se montará, el dispositivo en el que se encuentra el sistema de archivos que se montará y el directorio del cliente donde se montará el volumen.

      Observe que en este ejemplo de sintaxis, el argumento del dispositivo indica hacia un nombre de host seguido por dos puntos y el nombre del volumen. GlusterFS abstrae los directorios de almacenamiento reales en cada host, lo que significa que este comando no busca montar el directorio /gluster-storage, sino el volumen volume1.

      También tenga en cuenta que solo debe especificar un miembro del clúster de almacenamiento. Puede ser cualquiera de los nodos, ya que el servicio de GlusterFS los manipula como una sola máquina.

      Ejecute el siguiente comando en la máquina cliente (gluster2) para montar el volumen al directorio /storage-pool que creó:

      • sudo mount -t glusterfs gluster0.example.com:/volume1 /storage-pool

      Luego, ejecute el comando df. Esto mostrará la cantidad de espacio de disco disponible para los sistemas de archivos a los que tiene acceso el usuario que lo invoca:

      Este comando mostrará que el volumen de GlusterFS está montado en la ubicación correcta:

      Output

      Filesystem 1K-blocks Used Available Use% Mounted on . . . gluster0.example.com:/volume1 50633164 1938032 48695132 4% /storage-pool

      Ahora, puede avanzar y comprobar que cualquier dato que escriba en el volumen del cliente se copie a los nodos de su servidor como se esperaba.

      Paso 6: Poner a prueba las características de redundancia

      Ahora que ha configurado el cliente para que utilice el grupo y el volumen de almacenamiento, puede probar su funcionalidad.

      En la máquina cliente (gluster2), diríjase al punto de montaje que definió en el paso anterior:

      A continuación, cree algunos archivos de prueba. El siguiente comando crea diez archivos vacíos diferentes en el grupo de almacenamiento:

      • sudo touch file_{0..9}.test

      Si revisa los directorios de almacenamiento que definió anteriormente en cada host de almacenamiento, descubrirá que todos estos archivos están presentes en cada sistema.

      En gluster0:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

      Del mismo modo, en gluster1:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

      Como muestran estos resultados, los archivos de prueba que agregó al cliente también se escribieron en ambos nodos.

      Si en algún momento uno de los nodos del clúster de almacenamiento se desconecta, podría perder la sincronización con el grupo de almacenamiento si se realizan cambios en el sistema de archivos. Realizar una operación de lectura en el punto de montaje del cliente una vez que el nodo vuelva a estar en línea, alertará al nodo para que obtenga los archivos que faltan:

      Una vez que ha verificado que el volumen de almacenamiento se montó correctamente y que puede replicar los datos en ambas máquinas del clúster, puede bloquear el acceso al grupo de almacenamiento.

      Paso 7: Restringir las características de redundancia

      En este momento, cualquier computadora puede conectarse al volumen de almacenamiento sin ninguna restricción. Para modificar esto configure la opción auth.allow, que define las direcciones IP de los clientes que deberían tener acceso al volumen.

      Si está utilizando la configuración /etc/hosts, los nombres que estableció para cada servidor no se redirigirán correctamente. En su lugar, debe utilizar una dirección IP estática. Por otro lado, si utiliza registros DNS, el nombre de dominio que haya configurado funcionará aquí.

      Ejecute el siguiente comando en cualquiera de los nodos de almacenamiento (gluster0 o gluster1):

      • sudo gluster volume set volume1 auth.allow gluster2_ip_address

      Si el comando se completa correctamente, devolverá el siguiente resultado:

      Output

      volume set: success

      Si en algún momento necesita eliminar la restricción, puede escribir:

      • sudo gluster volume set volume1 auth.allow *

      Esto volverá a permitir las conexiones desde cualquier máquina. Esto no es seguro, pero puede ser útil para depurar problemas.

      Si tiene varios clientes, puede especificar sus direcciones IP o nombres de dominio al mismo tiempo (según esté utilizando la resolución de nombres de host /etc/hosts o DNS), separados por comas:

      • sudo gluster volume set volume1 auth.allow gluster_client1_ip,gluster_client2_ip

      Ahora el grupo de almacenamiento está configurado, protegido y listo para su uso. A continuación, aprenderá algunos comandos que le ayudarán a obtener información sobre el estado del grupo de almacenamiento.

      Paso 8: Obtener información sobre el grupo de almacenamiento con comandos de GlusterFS

      Cuando comienza a modificar algunas de las opciones de configuración del almacenamiento de GlusterFS, puede resultar confuso saber qué opciones tiene disponibles, qué volúmenes están en vivo y qué nodos se asocian con cada volumen.

      Existen diversos comandos disponibles en los nodos que permiten obtener estos datos e interactuar con el grupo de almacenamiento.

      Si quiere obtener información sobre cada uno de los volúmenes, ejecute el comando gluster volume info:

      Output

      Volume Name: volume1 Type: Replicate Volume ID: a1e03075-a223-43ab-a0f6-612585940b0c Status: Started Snapshot Count: 0 Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: gluster0.example.com:/gluster-storage Brick2: gluster1.example.com:/gluster-storage Options Reconfigured: auth.allow: gluster2_ip_address transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off

      Asimismo, para obtener información sobre cualquier punto al que esté conectado este nodo, puede escribir:

      Number of Peers: 1
      
      Hostname: gluster0.example.com
      Uuid: cb00a2fc-2384-41ac-b2a8-e7a1793bb5a9
      State: Peer in Cluster (Connected)
      

      Si quiere obtener información detallada sobre el rendimiento de cada nodo, puede crear el perfil de un volumen escribiendo lo siguiente:

      • sudo gluster volume profile volume_name start

      Cuando se complete el comando, escriba lo siguiente para obtener la información que se recopiló:

      • sudo gluster volume profile volume_name info

      Output

      Brick: gluster0.example.com:/gluster-storage -------------------------------------------- Cumulative Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes Interval 0 Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes . . .

      Tal como se mostró antes, utilice el comando gluster volume status para obtener una lista de todos los componentes asociados de GlusterFS que se ejecutan en cada uno de los nodos:

      • sudo gluster volume status

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 19003 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19040 Self-heal Daemon on localhost N/A N/A Y 19061 Self-heal Daemon on gluster0.example.com N/A N/A Y 19836 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

      Si va a administrar los volúmenes de almacenamiento de GlusterFS, puede ser recomendable ir a la consola de GlusterFS. Esto le permitirá interactuar con el entorno de GlusterFS sin necesidad de anteponer sudo gluster a todo:

      Esto le mostrará un mensaje en el que podrá escribir los comandos. El comando help puede ayudarlo a encaminarse:

      Output

      peer help - display help for peer commands volume help - display help for volume commands volume bitrot help - display help for volume bitrot commands volume quota help - display help for volume quota commands snapshot help - display help for snapshot commands global help - list global commands

      Cuando haya terminado, ejecute exit para salir de la consola de Gluster:

      Con esto, está listo para comenzar a integrar GlusterFS con su próxima aplicación.

      Conclusión

      Al final de este tutorial, tendrá un sistema de almacenamiento redundante que le permitirá escribir simultáneamente en dos servidores separados. Esto puede resultar útil para varias aplicaciones y puede garantizar que los datos estén disponibles incluso cuando un servidor falla.



      Source link

      Cómo implementar Laravel 7 y MySQL en Kubernetes con Helm


      El autor seleccionó la organización Diversity in Tech Fund para que reciba una donación como parte del programa Write for DOnations.

      Introducción

      Laravel es actualmente uno de los frameworks de aplicaciones PHP de código abierto más populares. Generalmente, se implementa con una base de datos de MySQL, pero puede configurarse para utilizar una variedad de opciones de almacenamiento de datos backend. Laravel se enorgullece de aprovechar muchas de las características modernas y el vasto ecosistema de paquetes de PHP.

      Kubernetes es una plataforma de orquestación de contenedores que puede alojarse en los clústeres de Kubernetes de DigitalOcean para que se encargue de una gran parte del trabajo administrativo de configuración y ejecución de contenedores en producción. Helm es un administrador de paquetes de Kubernetes que facilita la configuración e instalación de servicios y pods en Kubernetes.

      En esta guía, creará una aplicación PHP de Laravel, compilará la aplicación en una imagen de Docker e implementará esa imagen en un clúster de Kubernetes de DigitalOcean utilizando el chart de Helm de LAMP. A continuación, configurará un controlador Ingress para agregar SSL y un nombre de dominio personalizado a la aplicación. Al finalizar, tendrá una aplicación de Laravel funcional conectada a una base de datos que se ejecuta en un clúster de Kubernetes.

      Requisitos previos

      Paso 1: Crear una nueva aplicación Laravel

      En este paso, utilizará Docker para crear una nueva aplicación Laravel 7, pero debería poder realizar el mismo procedimiento con una aplicación Laravel existente que utilice MySQL como copia de seguridad de la base de datos. La nueva aplicación que compile verificará que Laravel esté conectada a la base de datos y mostrará el nombre de la base de datos.

      Primero, vaya al directorio de inicio y, luego, utilice un contenedor de Docker composer para crear una nueva aplicación Laravel:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Una vez que esté listo el contenedor y que se hayan instalado todos los paquetes de Composer, debería ver una nueva instalación de Laravel denominada laravel-kubernetes/ en el directorio actual. Diríjase a esa carpeta:

      A partir de aquí, ejecutará el resto de los comandos de este tutorial.

      El objetivo de esta aplicación es probar la conexión de la base de datos y mostrar su nombre en el navegador. Para probar la conexión de la base de datos, abra el archivo ./resources/views/welcome.blade.php en un editor de texto:

      • nano ./resources/views/welcome.blade.php

      Busque la sección <div class="links">...</div> y sustituya el contenido por lo siguiente:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

      Guarde y cierre el archivo.

      Ese es todo el proceso de personalización que deberá realizar en la aplicación predeterminada Laravel para este tutorial. Una vez que haya terminado, este breve fragmento de PHP probará la conexión de la base de datos y mostrará el nombre de dicha base de datos en la pantalla de presentación de Laravel en el navegador web.

      En el siguiente paso, utilizará Docker para compilar una imagen que contenga esta aplicación de Laravel y Docker Compose para probar que se ejecuta de manera local y que se conecta a una base de datos de MySQL.

      Paso 2: Disponer la aplicación de Laravel en un contenedor

      Ahora que creó una nueva aplicación de Laravel, deberá compilar el código en una imagen de Docker y, luego, evaluar la imagen con Docker Compose. Si bien el objetivo de este tutorial es implementar la aplicación en un clúster de Kubernetes, Docker Compose es una forma práctica de probar la imagen y la configuración de Docker de manera local antes de ejecutarla en la nube. Este proceso de retroalimentación rápido puede ser útil para realizar y probar modificaciones pequeñas.

      Primero, con nano o el editor de texto que prefiera, cree un archivo llamado Dockerfile en la raíz de la aplicación de Laravel:

      Añada el siguiente contenido: Docker utilizará este archivo para compilar el código en una imagen:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

      Guarde y cierre el archivo.

      Este archivo Dockerfile comienza con una imagen de Docker de Apache PHP 7.4 que se encuentra en Docker Hub y, luego, instala varios paquetes de Linux que generalmente los requieren las aplicaciones de Laravel. A continuación, crea archivos de configuración de Apache y habilita la reescritura de encabezados. El archivo Dockerfile instala varias extensiones comunes de PHP y agrega una variable de entorno para asegurarse de que los registros de Laravel se transmitan al contenedor a través de stderr. Esto le permitirá ver los registros de Laravel mediante el seguimiento de los registros de Docker Compose o Kubernetes.

      Por último, Dockerfile copia todo el código de la aplicación de Laravel a /var/www/tmp e instala las dependencias de Composer. Después, establece un ENTRYPOINT, pero deberá crear ese archivo, que es lo que haremos a continuación.

      En el directorio raíz de su proyecto, cree un nuevo archivo denominado docker-entrypoint.sh. Este archivo se ejecutará cuando el contenedor se ejecute de manera local o en el clúster de Kubernetes, y copiará el código de la aplicación de Laravel del directorio /var/www/tmp a /var/www/html, donde Apache podrá presentarlo.

      • nano ./docker-entrypoint.sh

      Ahora agregue la siguiente secuencia de comandos:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      La última línea, exec "$@", le indica al shell que ejecute cualquier comando que transmitió como argumento de entrada. Esto es importante porque queremos que Docker siga ejecutando el comando Ejecutar de Apache (apache2-foregrund) después de esta secuencia de comandos. Guarde y cierre el archivo.

      A continuación, cree un archivo .dockerignore en el directorio raíz de la aplicación. Este archivo garantizará que cuando compile la imagen de Docker, no se contamine con archivos de entorno o paquetes que no deberían copiarse allí:

      ./.dockerignore

      .env
      /vendor
      

      Guarde y cierre el archivo.

      El archivo docker-compose.yml es el último que debe crear antes de poder ejecutar la aplicación de manera local con Docker Compose. Sin embargo, durante la configuración de este archivo YAML, deberá ingresar la APP_KEY que generó Laravel durante la instalación. Para encontrar esta clave, abra y busque en el archivo . /.env o ejecute los siguientes comandos cat y grep:

      Verá un resultado similar a este:

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Copie la clave en el portapapeles. Asegúrese de incluir el prefijo base64:. Ahora cree el archivo docker-compose.yml en el directorio raíz de la aplicación:

      • nano ./docker-compose.yml

      Aquí incluiremos la imagen PHP de la aplicación de Laravel y también un contenedor de MySQL para ejecutar la base de datos. Añada el siguiente contenido:

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Utilice la variable APP_KEY que copió en el portapapeles para la variable your_laravel_app_key, y el nombre de usuario de Docker Hub para la variable your_docker_hub_username. Guarde y cierre el archivo.

      Creará la primera imagen de manera local con docker.build. La segunda imagen es la imagen de Docker de MySQL oficial que está disponible en Docker Hub. Ambas requieren diversas variables de entorno, las cuales incluirá cuando ejecute los contenedores.

      Para compilar la imagen de Docker que contiene la aplicación de Laravel, ejecute el siguiente comando. Asegúrese de sustituir your_docker_hub_username por su nombre de usuario o el nombre de usuario de su equipo en Docker Hub, donde se almacenará esta imagen:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      A continuación, puede ejecutar los dos contenedores utilizando Docker Compose con las credenciales necesarias de la base de datos:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      Si quiere, puede modificar las cuatro variables de entorno que se utilizan aquí (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME y DB_PASSWORD) pero, dado que solo está probando la aplicación de manera local, aún no es necesario protegerlas.

      El proceso de iniciar la base de datos de MySQL y preparar los contenedores puede tardar hasta 30 segundos. Una vez que lo estén, puede ver la aplicación de Laravel en su equipo en localhost:8000.

      La aplicación Laravel que ejecutándose de manera local con Docker Compose

      Su aplicación PHP se conectará a la base de datos de MySQL. Tras una conexión exitosa, el texto “Database Connected: localdb”(Base de datos conectada: localdb) aparecerá debajo del logotipo de Laravel.

      Ahora que probó la imagen de Docker de manera local con Docker Compose, puede ejecutar docker-compose down para desactivar los contenedores:

      En la siguiente sección, transferirá la imagen de Docker a Docker Hub para que su chart de Helm pueda utilizarla para implementar la aplicación en el clúster de Kubernetes.

      Paso 3: Introducir la imagen de Docker en Docker Hub

      El chart de Helm de LAMP que utilizará para implementar el código en Kubernetes requiere que el código esté disponible en un registro de contenedores. Si bien puede transferir la imagen a un registro privado o con alojamiento propio, a los efectos de este tutorial, utilizará un registro de Docker público y gratuito en Docker Hub.

      En el navegador web, acceda a su cuenta en Docker Hub y, luego, cree un nuevo repositorio llamado laravel-kubernetes.

      Crear un nuevo repositorio en Docker Hub

      A continuación, si no se conectó a Docker Hub desde el equipo local, deberá iniciar sesión en Docker Hub. Puede hacerlo con la siguiente línea de comandos:

      • docker login -u your_docker_hub_username

      Cuando se le solicite, ingrese las credenciales de inicio de sesión. Generalmente, solo debe realizar esta acción una vez en cada equipo, ya que Docker guardará las credenciales en ~/.docker/config.json en el directorio de inicio.

      Por último, transfiera la imagen a Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

      Dependiendo de la velocidad de conexión, puede tomar algunos minutos cargar la aplicación, pero una vez que Docker termine, verá un último resumen de la función hash y el tamaño de la imagen en el terminal. El aspecto será similar a este:

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Ahora que la aplicación de Laravel está en un contenedor y que introdujo una imagen en Docker Hub, puede utilizar la imagen en la implementación de un chart de Helm o de Kubernetes. En el siguiente paso, configurará valores personalizados en base al chart de Helm de LAMP y lo implementará en el clúster de Kubernetes de DigitalOcean.

      Paso 4: Configurar e implementar la aplicación con el chart de Helm de LAMP

      Helm proporciona varios Charts para ayudarlo a configurar aplicaciones de Kubernetes utilizando combinaciones de herramientas predeterminadas. Si bien podría escribir archivos de servicio de Kubernetes propios para lograr una implementación similar, en esta sección observará que al utilizar un Chart de Helm se requerirá un proceso de configuración mucho menor.

      Primero, necesitará un directorio para almacenar todos los archivos de configuración de Helm. En la raíz de su proyecto Laravel, cree un nuevo directorio llamado helm/:

      Dentro del directorio helm/ crearemos dos nuevos archivos: values.yml y secrets.yml. Primero, cree y abra values.yml:

      El archivo values.yml incluirá opciones de configuración no secretas que anularán los valores predeterminados en el gráfico de Helm de LAMP. Agregue las siguientes opciones de configuración, asegurándose de sustituir your_docker_hub_username por su nombre de usuario:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

      Guarde y cierre el archivo.

      Ahora cree un archivo secrets.yml:

      secrets.yml no se verificará en el control de versiones. Contendrá información de configuración confidencial, como la contraseña de la base de datos y la clave de la aplicación de Laravel. Agregue la siguiente configuración, y adáptela según corresponda para que coincida con sus credenciales:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

      Asegúrese de utilizar combinaciones de nombre de usuario y contraseña seguras para su base de datos de producción, y utilice la misma your_laravel_app_key que empleó anteriormente, o ejecute el siguiente comando para abrir una ventana de terminal nueva y generar una nueva clave. Luego, puede copiar el nuevo valor que establezca Laravel en el archivo .env:

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

      Guarde y cierre secrets.yml.

      A continuación, para evitar que el archivo secrets.yml se integre en la imagen de Docker o se guarde en el control de versiones, asegúrese de agregar la siguiente línea en los archivos .dockerignore y .gitignore. Abra cada archivo y anexe /helm/secrets.yml a cada uno, o bien ejecute el siguiente comando para agregarlo a ambos:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Ahora que ha creado los archivos de configuración de Helm para su aplicación y la imagen de Docker, puede instalar este chart de Helm como una nueva versión en el clúster de Kubernetes. Instale el chart desde el directorio raíz de la aplicación:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Verá un resultado similar a este:

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      La aplicación estará disponible en uno o dos minutos, pero puede ejecutar este comando para controlar el servicio de Kubernetes en el clúster:

      Busque el nombre de su aplicación:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      Cuando el nuevo servicio laravel-kubernetes-lamp muestre una dirección IP en EXTERNAL-IP, puede visitar your_external_ip para ver la aplicación ejecutándose en el clúster de Kubernetes. La aplicación se conectará a la base de datos, y verá el nombre de dicha base de datos debajo del logotipo de Laravel, como sucedió cuando ejecutó la aplicación de manera local en Docker Compose.

      La aplicación de Laravel ejecutándose en Kubernetes con el chart de Helm de LAMP

      Es aceptable ejecutar una aplicación web en una dirección IP no segura cuando se trata de una prueba de concepto, pero sin un certificado SSL y un nombre de dominio personalizado, el sitio web no está listo para producción. Antes de configurar esto en el siguiente paso, desinstale la versión mediante la línea de comandos:

      • helm delete laravel-kubernetes

      En el siguiente paso, ampliará la primera configuración de Helm para agregar un controlador Ingress, un certificado SSL y un dominio personalizado a la aplicación de Laravel.

      Paso 5: Agregar un controlador Ingress y SSL al clúster de Kubernetes

      En Kubernetes, un controlador Ingress es el responsable de exteriorizar los servicios de su aplicación a Internet. En el paso anterior, el chart de Helm de LAMP creó un equilibrador de carga de DigitalOcean y expuso la aplicación de manera directa a través de la dirección IP del equilibrador de carga.

      Podría terminar SSL y el nombre de dominio directamente en el equilibrador de carga, pero, debido a que está trabajando en Kubernetes, podría resultar más práctico administrar todo en el mismo lugar. Para obtener más información sobre los controladores Ingress y detalles sobre los siguientes pasos, consulte Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean utilizando Helm.

      El chart de Helm de LAMP incluye una opción de configuración para admitir Ingress. Abra el archivo helm/values.yml:

      Ahora agregue las siguientes líneas:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      Esto indica que durante la implementación no se instale un equilibrador de carga y que, en su lugar, se exponga la aplicación al puerto 80 del clúster de Kubernetes, donde el controlador Ingress lo exteriorizará a Internet. Guarde y cierre values.yml.

      Ahora ejecute el comando helm install que ejecutó anteriormente para que se volviera a ejecutar la aplicación de Laravel. Asegúrese de ejecutar el comando desde el directorio raíz de la aplicación:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      A continuación, instale el controlador nginx-ingress en el clúster de Kubernetes utilizando el controlador Ingress de Nginx que mantiene Kubernetes:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

      Una vez completada la instalación, verá un resultado similar a este:

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      También necesita un recurso de Ingress para exponer la implementación de la aplicación de Laravel. Cree un nuevo archivo denominado ingress.yml en el directorio raíz de la aplicación:

      Este archivo define el host de la aplicación, el administrador del certificado SSL, el servicio de backend y el nombre del puerto. Agregue las siguientes opciones de configuración, sustituyendo your_domain por el dominio de su elección:

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

      Guarde y cierre el archivo.

      A continuación, debería instalar Cert-Manager y crear un emisor que le permitirá crear certificados SSL de producción utilizando Let’s Encrypt. Cert-Manager requiere definiciones de recursos personalizados que puede aplicar desde el repositorio de Cert-Manager mediante la línea de comandos:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      Esto creará varios recursos de Kubernetes que se mostrarán en la línea de comandos:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager también requiere un espacio de nombres para aislarlo en el clúster de Kubernetes:

      • kubectl create namespace cert-manager

      Obtendrá el siguiente resultado:

      Output

      namespace/cert-manager created

      Debido a que el Cert-Manager de Jetstack no es uno de los charts que mantiene Kubernetes, también deberá agregar el repositorio de Helm para Jetstack. Ejecute el siguiente comando para habilitarlo en Helm:

      • helm repo add jetstack https://charts.jetstack.io

      Si se agrega de manera correcta, se mostrará el siguiente resultado:

      Output

      "jetstack" has been added to your repositories

      Ahora está listo para instalar Cert-Manager en el espacio de nombres de cert-manager del clúster de Kubernetes:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      Cuando finalice, verá un resumen del despliegue similar al siguiente:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      El archivo de configuración de Kubernetes production_issuer.yml es el último archivo que deberá agregar al directorio raíz de la aplicación de Laravel. Cree el archivo:

      • nano ./production_issuer.yml

      Ahora, agregue lo siguiente:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

      Guarde y cierre el archivo.

      Let’s Encrypt enviará a your_email_address cualquier aviso importante y advertencia de vencimiento, así que asegúrese de agregar una dirección que revisará de manera regular. Guarde este archivo y cree un nuevo recurso en el clúster de Kubernetes para el recurso de Ingress y para el emisor de producción:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      Por último, actualice los registros DNS de su nombre de dominio para que dirija un registro A a la dirección IP del equilibrador de carga. Para encontrar la dirección IP del controlador Ingress escriba:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Utilice la dirección your_external_ip como la dirección IP para su registro DNS tipo A. El proceso para actualizar los registros DNS varía en función de dónde gestiona los nombres de dominio y el hosting de DNS, pero si utiliza DigitalOcean, puede consultar nuestra guía sobre Cómo administrar registros DNS.

      Una vez que se actualice el registro DNS y se genere el certificado SSL, la aplicación estará disponible en your_domain y se habilitará SSL.

      La aplicación de Laravel con terminación de SSL y un nombre de dominio personalizado

      Si bien la aplicación de PHP y la base de datos ya están conectadas, aún deberá ejecutar migraciones de base de datos. En el último paso, aprenderá a ejecutar los comandos Artisan en el pod de Kubernetes para realizar migraciones de base de datos y otras tareas comunes de mantenimiento.

      Paso 6: Ejecutar comandos remotos

      Mientras se ejecuta la aplicación de Laravel y se mantiene conectada a la base de datos de MySQL en Kubernetes, existen varias operaciones comunes que debería ejecutar en una nueva instalación de Laravel. Una tarea común que debería realizar son las migraciones de base de datos.

      Antes de poder ejecutar un comando Artisan en la aplicación de Laravel, debe conocer el nombre del pod que está ejecutando el container de dicha aplicación. Puede ver todos los pods de su clúster de Kubernetes mediante la siguiente línea de comandos:

      Verá un resultado similar a este:

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Seleccione el pod para la implementación de laravel-kubernetes-lamp-.... Asegúrese de utilizar el nombre del resultado y no el que aparece arriba. Ahora puede ejecutar kubectl exec en él. Por ejemplo, ejecute una migración de base de datos utilizando el comando artisan migrate. Agregará el indicador --force porque está ejecutando el pod en producción:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      Este comando arrojará un resultado como el siguiente:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      De esta manera, implementó de manera exitosa Laravel 7 y MySQL en Kubernetes y realizó una tarea de mantenimiento de la base de datos indispensable.

      Conclusión

      En este tutorial, aprendió a disponer una aplicación PHP de Laravel en un container, conectarla con una base de datos de MySQL, introducir una imagen de Docker que contiene su código en Docker Hub y, luego, utilizar un chart de Helm para implementar esa imagen en un clúster de Kubernetes de DigitalOcean. Por último, agregó SSL y un nombre de dominio personalizado, y aprendió a ejecutar herramientas de línea de comandos en los pods en ejecución.

      En comparación del hosting tradicional de la pila LAMP, Kubernetes y Helm ofrecen varias ventajas: escalabilidad, la capacidad de cambiar servicios sin tener que iniciar sesión en el servidor de manera directa, herramientas para realizar actualizaciones progresivas y control sobre el entorno de hosting. Dicho esto, la complejidad de utilizar contenedores y configurar la aplicación al principio eleva la barrera a la hora de comenzar a utilizarlos. Con esta guía como punto de partida, la implementación de Laravel en Kubernetes se vuelve factible. A partir de aquí, quizás quiera aprender más sobre la capacidad de Laravel o agregar herramientas de monitoreo a Kubernetes como Linkerd, que puede instalar de manera manual siguiendo nuestra guía o con un solo clic de DigitalOcean.



      Source link

      Cómo instalar y configurar Laravel con Docker Compose en Ubuntu 20.04


      Introducción

      Cuando se habla de disponer en contenedores una aplicación, se hace referencia al proceso de adaptación de una aplicación y sus componentes para poder ejecutarla en entornos ligeros conocidos como contenedores. Estos entornos están aislados, son desechables y se pueden utilizar para desarrollar, probar e implementar aplicaciones en la producción.

      En esta guía, usaremos Docker Compose con el propósito de disponer en contenedores una aplicación de Laravel para el desarrollo. Al finalizar, dispondrá de una aplicación Laravel de demostración funcional en tres contenedores de servicios separados:

      • un servicio app con PHP7.4-FPM;
      • un servicio db con MySQL 5.7;
      • un servicio nginx en el que se utilice el servicio app para analizar el código PHP antes de proporcionar la aplicación Laravel al usuario final.

      Para permitir un proceso de desarrollo simplificado y facilitar la depuración de aplicaciones, mantendremos sincronizados los archivos de la aplicación usando volúmenes compartidos. También veremos cómo usar comandos docker-compose exec para la ejecución de Composer y Artisan en el contenedor app.

      Requisitos previos

      Paso 1: Obtener la aplicación de demostración

      Para comenzar, obtendremos la aplicación Laravel de demostración de su repositorio de Github. Nos interesa la ramificación tutorial-01, que contiene la aplicación básica de Laravel que creamos en la primera guía de esta serie.

      Para obtener el código de la aplicación que es compatible con este tutorial, descargue la versión tutorial-1.0.1 en su directorio de inicio con lo siguiente:

      • cd ~
      • curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip

      Necesitaremos el comando unzip para desempaquetar el código de la aplicación. En caso de que no haya instalado el paquete antes, hágalo ahora con lo siguiente:

      • sudo apt update
      • sudo apt install unzip

      Luego, descomprima el contenido de la aplicación y cambie el nombre del directorio desempaquetado para facilitar el acceso:

      • unzip travellist.zip
      • mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

      Diríjase al directorio travellist-demo:

      En el siguiente paso, crearemos un archivo de configuración .env para configurar la aplicación.

      Paso 2: Configurar el archivo .env de la aplicación

      Los archivos de configuración de Laravel se encuentran en un directorio llamado config, dentro del directorio root de la aplicación. Además, un archivo .env se utiliza para establecer una configuración dependiente del entorno, como las credenciales y cualquier información que pueda variar entre las implementaciones. Este archivo no está incluido en el control de revisiones.

      Advertencia: En el archivo de configuración del entorno se encuentra información confidencial sobre su servidor, incluidas las credenciales de bases de datos y las claves de seguridad. Por ese motivo, nunca debe compartir públicamente este archivo.

      Los valores incluidos en el archivo .env tendrán prioridad sobre los valores establecidos en los archivos de configuración normales que se encuentran en el directorio config. Para cada instalación en un nuevo entorno se requiere un archivo de entorno personalizado a fin de definir elementos como las configuraciones de conexión de bases de datos, las opciones de depuración y las URL de aplicación, entre otros elementos que pueden variar dependiendo del entorno en el que se ejecute la aplicación.

      Ahora, crearemos un nuevo archivo .env para personalizar las opciones de configuración para el entorno de desarrollo que configuraremos. En Laravel se incluye un archivo .env de ejemplo que podemos copiar para crear el nuestro:

      Abra este archivo utilzando nano o el editor de texto que prefiera:

      En el archivo .env actual de la aplicación de demostración travellist se incluyen las configuraciones para usar una base de datos local de MySQL, con 127.0.0.1 como host de base de datos. Necesitamos actualizar la variable DB_HOST para que esta apunte al servicio de base de datos que crearemos en nuestro entorno de Docker. En esta guía, usaremos el nombre db para el servicio de nuestra base de datos. Sustituya el valor de la lista de DB_HOST por el nombre del servicio de la base de datos:

      .env

      APP_NAME=Travellist
      APP_ENV=dev
      APP_KEY=
      APP_DEBUG=true
      APP_URL=http://localhost:8000
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=db
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password
      ...
      

      Si lo desea, puede cambiar también el nombre, el nombre de usuario y la contraseña de la base de datos. Estas variables aprovecharán en un paso posterior en el que prepararemos el archivo docker-compose.yml para configurar nuestros servicios.

      Guarde el archivo cuando finalice la edición. Si utiliza nano, puede hacerlo presionando Ctrl+x, luego Y y Enter para confirmar.

      Paso 3: Configurar el Dockerfile de la aplicación

      Aunque ambos servicios de MySQL y Nginx se basarán en imágenes predeterminadas obtenidas de Docker Hub, debemos de todas formas crear una imagen personalizada para el contenedor de la aplicación. Crearemos un nuevo Dockerfile para ello.

      Nuestra imagen de travellist se basará en la imagen oficial de PHP php:7.4-fpm de Docker Hub. Además de ese entorno básico de PHP-FPM, instalaremos algunos módulos de PHP adicionales y la herramienta de administración de dependencias Composer.

      También crearemos un nuevo usuario de sistema; esto es necesario para ejecutar los comandos artisan y composer mientras se desarrolla la aplicación. En la configuración uid se garantiza que el usuario dentro del contenedor tenga el mismo uid que el usuario de su sistema en su equipo host, donde Docker está en ejecución. De esta manera, todos los archivos creados por estos comandos se replican en el host con los permisos correctos. Esto también significa que podrá usar su editor de código preferido en la máquina host para desarrollar la aplicación que está en ejecución dentro de los contenedores.

      Cree un nuevo Dockerfile con lo siguiente:

      Copie el siguiente contenido en su Dockerfile:

      Dockerfile

      FROM php:7.4-fpm
      
      # Arguments defined in docker-compose.yml
      ARG user
      ARG uid
      
      # Install system dependencies
      RUN apt-get update && apt-get install -y 
          git 
          curl 
          libpng-dev 
          libonig-dev 
          libxml2-dev 
          zip 
          unzip
      
      # Clear cache
      RUN apt-get clean && rm -rf /var/lib/apt/lists/*
      
      # Install PHP extensions
      RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
      
      # Get latest Composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      
      # Create system user to run Composer and Artisan Commands
      RUN useradd -G www-data,root -u $uid -d /home/$user $user
      RUN mkdir -p /home/$user/.composer && 
          chown -R $user:$user /home/$user
      
      # Set working directory
      WORKDIR /var/www
      
      USER $user
      
      

      No olvide guardar el archivo cuando termine.

      Nuestro Dockerfile comienza definiendo la imagen base que usaremos: php:7.4-fpm.

      Después de instalar los paquetes del sistema y las extensiones de PHP, instalamos Composer copiando el ejecutable composer de su imagen oficial más reciente en la propia imagen de nuestra aplicación.

      A continuación, se crea un nuevo usuario de sistema y se configura usando los argumentos user y uid que se declararon al inicio del Dockerfile. Docker Compose insertará estos valores en el tiempo de compilación.

      Por último, fijaremos el directorio de trabajo predeterminado como /var/www y cambiaremos al usuario recién creado. Esto garantizará que se conecte como un usuario normal y que se encuentre en el directorio correcto, al ejecutar comandos de composer y artisan en el contenedor de la aplicación.

      Paso 4: Preparar archivos de configuración de Nginx y de volcado de bases de datos

      Cuando se crean entornos de desarrollo con Docker Compose, a menudo es necesario compartir archivos de configuración o de inicialización con contenedores de servicios para que se puedan configurar o aplicar estos servicios. Esta práctica facilita la aplicación de cambios en los archivos de configuración para ajustar el entorno mientras desarrolla la aplicación.

      Ahora crearemos una carpeta con archivos que se utilizarán para configurar e inicializar nuestros contenedores de servicios.

      Para configurar Nginx, compartiremos un archivo travellist.conf en el que se configurará la forma en que se proporciona la aplicación. Cree la carpeta docker-compose/nginx con lo siguiente:

      • mkdir -p docker-compose/nginx

      Abra un nuevo archivo llamado travellist.conf dentro de ese directorio:

      • nano docker-compose/nginx/travellist.conf

      Copie la siguiente configuración de Nginx en ese archivo:

      docker-compose/nginx/travellist.conf

      
      server {
          listen 80;
          index index.php index.html;
          error_log  /var/log/nginx/error.log;
          access_log /var/log/nginx/access.log;
          root /var/www/public;
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass app:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
          location / {
              try_files $uri $uri/ /index.php?$query_string;
              gzip_static on;
          }
      }
      

      En este archivo se configurará Nginx para que escuche en el puerto 80 y utilice index.php como la página de índice predeterminada. Establecerá el documento root en /var/www/public y luego configurará Nginx para que en este se utilice el servicio app en el puerto 9000 a fin de procesar archivos *.php.

      Guarde y cierre el archivo cuando finalice la edición.

      Para configurar la base de datos de MySQL, compartiremos un volcado de base de datos que se importará cuando se inicialice el contenedor. Esta es una característica que se proporciona a través de la imagen de MySQL 5.7 y que usaremos en ese contenedor.

      Cree una nueva carpeta para sus archivos de inicialización de MySQL dentro de la carpeta docker-compose:

      • mkdir docker-compose/mysql

      Abra un nuevo archivo .sql:

      • nano docker-compose/mysql/init_db.sql

      El siguiente volcado de MySQL deriva de la base de datos que configuramos en nuestra guía sobre Laravel en LEMP. Se creará una nueva tabla llamada places. Luego, se completará la tabla con un conjunto de lugares de ejemplo.

      Añada el siguiente código al archivo:

      docker-compose/mysql/db_init.sql

      DROP TABLE IF EXISTS `places`;
      
      CREATE TABLE `places` (
        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
        `visited` tinyint(1) NOT NULL DEFAULT '0',
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
      
      INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);
      

      En la tabla places se incluyen tres campos: id, name y visited. El campo visited es un indicador utilizado para identificar los lugares que aún quedan por recorrer. Puede cambiar los lugares de ejemplo o incluir casos nuevos si lo desea. Guarde y cierre el archivo cuando termine.

      Terminamos de preparar el Dockerfile de la aplicación y los archivos de configuración del servicio. A continuación, configuraremos Docker Compose para que se utilicen estos archivos al crear nuestros servicios.

      Paso 5: Crear un entorno en varios contenedores con Docker Compose

      Docker Compose le permite crear entornos en varios contenedores para aplicaciones que se ejecuten en Docker. Se utilizan definiciones de servicio para crear entornos totalmente personalizables con varios contenedores que pueden compartir redes y volúmenes de datos. Esto permite una integración sin problemas entre los componentes de la aplicación.

      Para establecer nuestras definiciones de servicios, crearemos un nuevo archivo llamado docker-compose.yml. Normalmente, este archivo se encuentra en la carpeta root de la aplicación y define su entorno en contenedor, incluidas las imágenes de base que usará para crear sus contenedores y la forma en que interactuarán sus servicios.

      Definiremos tres servicios diferentes en nuestro archivo docker-compose.yml: app, db y nginx.

      En el servicio app se creará una imagen llamada travellist, basada en el Dockerfile que creamos previamente. En el contenedor definido por este servicio se ejecutará un servidor php-fpm para analizar el código PHP y enviar los resultados de vuelta al servicio nginx, que estará en ejecución en un contenedor separado. A través del servicio mysql, se define un contenedor en un servidor MySQL 5.7. En nuestros servicios se compartirá una red de puente llamada travellist.

      Los archivos de la aplicación se sincronizarán en los servicios app y nginx mediante montajes “bind”. Los montajes “bind” son útiles en los entornos de desarrollo porque en estos se permite una sincronización bidireccional estable entre el equipo host y los contenedores.

      Cree un nuevo archivo docker-compose.yml en la carpeta root de la aplicación:

      Un archivo típico de docker-compose.yml comienza con una definición de versión, a la que le sigue un nodo services, donde se definen todos los servicios. Las redes compartidas suelen definirse al final de ese archivo.

      Para comenzar, copie el siguiente código estándar a su archivo docker-compose.yml:

      docker-compose.yml

      version: "3.7"
      services:
      
      
      networks:
        travellist:
          driver: bridge
      

      Ahora, editaremos el nodo services para incluir los servicios app, db y nginx.

      El servicio app

      A través del servicio app se configurará un contenedor llamado travellist-app. Crea una nueva imagen de Docker basada en un Dockerfile ubicado en la misma ruta que el archivo docker-compose.yml. La nueva imagen se guardará a nivel local con el nombre travellist.

      Aunque el root de documentos que se proporciona como la aplicación se encuentra en el contenedor nginx, también necesitamos los archivos de la aplicación en algún lugar dentro del contenedor app para poder ejecutar tareas de línea de comandos con la herramienta Laravel Artisan.

      Copie la siguiente definición de servicio en su nodo services, dentro del archivo docker-compose.yml:

      docker-compose.yml

        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      

      Estas configuraciones tienen los siguientes atributos:

      • build: en esta configuración indica a Docker Compose que cree una imagen local para el servicio app, y usa la ruta especificada (context) y Dockerfile para las instrucciones. Los argumentos user y uid se insertan en Dockerfile para personalizar los comandos de creación del usuario en el tiempo de compilación.
      • image: nombre que se usará para la imagen que se creará.
      • container_name: configura el nombre del contenedor para este servicio.
      • restart: siempre ejecuta un reinicio, a menos que se detenga el servicio.
      • working_dir: establece el directorio predeterminado para este servicio como /var/www.
      • volumes: crea un volumen compartido en el que se sincronizarán los contenidos del directorio actual con /var/www dentro del contenedor. Tenga en cuenta que esto no es su root de documentos, ya que este residirá en el contenedor nginx.
      • networks: configura este servicio para que se utilice una red llamada travellist.

      El servicio db

      En el servicio db se utiliza una imagen previamente creada de MySQL 5.7 de Docker Hub. Debido a que en Docker Compose se cargan automáticamente los archivos de variable .env ubicados en el mismo directorio que el archivo docker-compose.yml, podemos obtener la configuración de nuestra base de datos del archivo Laravel .env que creamos en un paso anterior.

      Incluya la siguiente definición de servicio en el nodo services, justo después del servicio app:

      docker-compose.yml

        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      

      Estas configuraciones hacen lo siguiente:

      • image: define la imagen de Docker que debe utilizarse para este contenedor. En este caso, usamos una imagen MySQL 5.7 de Docker Hub.
      • container_name: establece el nombre del contenedor para el servicio travellist-db.
      • restart: reinicie siempre este servicio, a menos que se detenga de forma explicita.
      • environment: define las variables de entorno en el nuevo contenedor. Usaremos valores obtenidos del archivo Laravel .env para establecer nuestro servicio de MySQL, que creará automáticamente una nueva base de datos y usuario basadas en las variables de entorno proporcionadas.
      • volumes: crea un volumen para compartir un volcado de base de datos .sql que se usará para inicializar la base de datos de la aplicación. En la imagen de MySQL se importarán automáticamente archivos .sql ubicados en el directorio /docker-entrypoint-initdb.d dentro del contenedor.
      • networks: configura este servicio para que se utilice una red llamada travellist.

      El servicio nginx

      En el servicio nginx se utiliza una imagen previamente creada de Nginx en la parte superior de Alpine, una distribución ligera de Linux. Se crea un contenedor llamado travellist-nginx y se utiliza la definición ports para crear un redireccionamiento del puerto 8000 en el sistema host al puerto 80 dentro del contenedor.

      Incluya la siguiente definición de servicio en su nodo services, justo después del servicio db:

      docker-compose.yml

        nginx:
          image: nginx:1.17-alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d
          networks:
            - travellist
      

      Esta configuración hace lo siguiente:

      • image: define la imagen de Docker que debe utilizarse para este contenedor. En este caso, usaremos la imagen Alpine Nginx 1.17.
      • container_name: establece el nombre del contenedor para el servicio travellist-nginx.
      • restart: reinicie siempre este servicio, a menos que se detenga de forma explicita.
      • ports: establece un redireccionamiento de puerto que permitirá el acceso externo a través del puerto 8000 al servidor web que se ejecuta en el puerto 80 dentro del contenedor.
      • volumes: crea dos volúmenes compartidos. El primero sincronizará los contenidos del directorio actual con /var/www dentro del contenedor. De esta manera, cuando realice cambios locales en los archivos de la aplicación, se reflejarán rápidamente en la aplicación proporcionada por Nginx dentro del contenedor. En el segundo volumen, se asegurará que nuestro archivo de configuración de Nginx, ubicado en docker-compose/nginx/travellist.conf, se copie a la carpeta de configuración de Nginx del contenedor.
      • networks: configura este servicio para que se utilice una red llamada travellist.

      Archivo docker-compose.yml terminado

      Este es el aspecto de nuestro archivo docker-compose.yml terminado:

      docker-compose.yml

      version: "3.7"
      services:
        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      
        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      
        nginx:
          image: nginx:alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d/
          networks:
            - travellist
      
      networks:
        travellist:
          driver: bridge
      

      Asegúrese de guardar el archivo cuando termine.

      Paso 6: Ejecutar la aplicación con Docker Compose

      Ahora, usaremos comandos docker-compose para crear la imagen de la aplicación y ejecutar los servicios que especificamos en nuestra configuración.

      Cree la imagen app con el siguiente comando:

      La aplicación de este comando puede tardar unos minutos en completarse. Verá un resultado similar a este:

      Output

      Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in f71eb33b7459 Removing intermediate container f71eb33b7459 ---> 533c30216f34 Step 3/11 : ARG uid ---> Running in 60d2d2a84cda Removing intermediate container 60d2d2a84cda ---> 497fbf904605 Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev ... Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ---> e499f74896e3 Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user ---> Running in 232ef9c7dbd1 Removing intermediate container 232ef9c7dbd1 ---> 870fa3220ffa Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user ---> Running in 7ca8c0cb7f09 Removing intermediate container 7ca8c0cb7f09 ---> 3d2ef9519a8e Step 10/11 : WORKDIR /var/www ---> Running in 4a964f91edfa Removing intermediate container 4a964f91edfa ---> 00ada639da21 Step 11/11 : USER $user ---> Running in 9f8e874fede9 Removing intermediate container 9f8e874fede9 ---> fe176ff4702b Successfully built fe176ff4702b Successfully tagged travellist:latest

      Cuando se complete la compilación, podrá ejecutar el entorno en el modo de segundo plano con lo siguiente:

      Output

      Creating travellist-db ... done Creating travellist-app ... done Creating travellist-nginx ... done

      Con esto, se ejecutarán sus contenedores en segundo plano. Para mostrar información sobre el estado de sus servicios activos, ejecute lo siguiente:

      Verá resultados como este:

      Output

      Name Command State Ports -------------------------------------------------------------------------------- travellist-app docker-php-entrypoint php-fpm Up 9000/tcp travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp travellist-nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp

      Su entorno ahora estárá configurado y en funcionamiento, pero aún debemos ejecutar algunos comandos para finalizar la configuración de la aplicación. Puede usar el comando docker-compose exec para ejecutar comandos en los contenedores de servicios, como ls -l. Este muestra información detallada sobre los archivos en el directorio de la aplicación:

      • docker-compose exec app ls -l

      Output

      total 260 -rw-rw-r-- 1 sammy sammy 737 Jun 9 11:19 Dockerfile -rw-rw-r-- 1 sammy sammy 101 Jan 7 08:05 README.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 app -rwxr-xr-x 1 sammy sammy 1686 Jan 7 08:05 artisan drwxrwxr-x 3 sammy sammy 4096 Jan 7 08:05 bootstrap -rw-rw-r-- 1 sammy sammy 1501 Jan 7 08:05 composer.json -rw-rw-r-- 1 sammy sammy 179071 Jan 7 08:05 composer.lock drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 config drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 database drwxrwxr-x 4 sammy sammy 4096 Jun 9 11:19 docker-compose -rw-rw-r-- 1 sammy sammy 965 Jun 9 11:27 docker-compose.yml -rw-rw-r-- 1 sammy sammy 1013 Jan 7 08:05 package.json -rw-rw-r-- 1 sammy sammy 1405 Jan 7 08:05 phpunit.xml drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 public -rw-rw-r-- 1 sammy sammy 273 Jan 7 08:05 readme.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 resources drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 routes -rw-rw-r-- 1 sammy sammy 563 Jan 7 08:05 server.php drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 storage drwxrwxr-x 4 sammy sammy 4096 Jan 7 08:05 tests drwxrwxr-x 41 sammy sammy 4096 Jun 9 11:32 vendor -rw-rw-r-- 1 sammy sammy 538 Jan 7 08:05 webpack.mix.js

      Ahora, ejecutaremos composer install para instalar las dependencias de la aplicación:

      • docker-compose exec app composer install

      Verá resultados como este:

      Output

      Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) - Installing erusev/parsedown (1.7.4): Downloading (100%) - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%) - Installing phpoption/phpoption (1.7.2): Downloading (100%) - Installing vlucas/phpdotenv (v3.6.0): Downloading (100%) - Installing symfony/css-selector (v5.0.2): Downloading (100%) … Generating optimized autoload files > IlluminateFoundationComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.

      Lo último que debemos hacer antes de probar la aplicación es generar una clave de aplicación única con la herramienta de línea de comandos de Laravel artisan. Esta clave se utiliza para cifrar las sesiones de los usuarios y otros datos confidenciales:

      • docker-compose exec app php artisan key:generate

      Output

      Application key set successfully.

      Ahora diríjase a su navegador y acceda al nombre de dominio o dirección IP de su servidor en el puerto 8000:

      http://server_domain_or_IP:8000
      

      Nota: En el caso de que esté ejecutando esta demo en su equipo local, utilice https://localhost:8000 para acceder a la aplicación desde su navegador.

      Verá una página como la siguiente:

      Aplicación de demostración de Laravel

      Puede usar el comando logs para verificar los registros generados por sus servicios:

      • docker-compose logs nginx
      Attaching to travellist-nginx
      …
      travellist-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
      travellist-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:34 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:35 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      

      Si desea pausar su entorno de Docker Compose mientras mantiene el estado de todos sus servicios, ejecute lo siguiente:

      Output

      Pausing travellist-db ... done Pausing travellist-nginx ... done Pausing travellist-app ... done

      Luego podrá reanudar sus servicios con lo siguiente:

      Output

      Unpausing travellist-app ... done Unpausing travellist-nginx ... done Unpausing travellist-db ... done

      Para cerrar su entorno de Docker Compose y eliminar por completo sus contenedores, redes y volúmenes, ejecute lo siguiente:

      Output

      Stopping travellist-nginx ... done Stopping travellist-db ... done Stopping travellist-app ... done Removing travellist-nginx ... done Removing travellist-db ... done Removing travellist-app ... done Removing network travellist-laravel-demo_travellist

      Para acceder a una visión general de todos los comandos de Docker Compose, consulte la referencia de línea de comandos de Docker Compose.

      Conclusión

      A lo largo de esta guía, configuramos un entorno de Docker con tres contenedores usando Docker Compose para definir nuestra infraestructura en un archivo YAML.

      A partir de este punto, puede trabajar en su aplicación de Laravel sin necesidad de instalar y configurar un servidor web local para el desarrollo y las pruebas. Además, trabajará con un entorno disponible que se puede replicar y distribuir de forma sencilla, lo cual puede resultarle útil al desarrollar su aplicación y realizar la transición a un entorno de producción.



      Source link