Nextcloud es una aplicación de sincronización y uso compartido de archivos de código abierto que ofrece almacenamiento de archivos en la nube gratuito, seguro y de fácil acceso, así como una serie de herramientas que amplían su conjunto de características. Es muy similar a los populares Dropbox, iCloud y Google Drive, pero a diferencia de Dropbox, Nextcloud no ofrece alojamiento de almacenamiento de archivos fuera de las instalaciones.
En esta publicación de blog, implementaremos una configuración de alta disponibilidad para nuestra infraestructura privada "Dropbox" utilizando Nextcloud, GlusterFS, Percona XtraDB Cluster (MySQL Galera Cluster), ProxySQL con ClusterControl como herramienta de automatización para administrar y monitorear la base de datos y los niveles del balanceador de carga.
Nota:También puede usar MariaDB Cluster, que usa la misma biblioteca de replicación subyacente que Percona XtraDB Cluster. Desde la perspectiva del balanceador de carga, ProxySQL se comporta de manera similar a MaxScale en el sentido de que puede comprender el tráfico de SQL y tiene un control detallado sobre cómo se enruta el tráfico.
Arquitectura de base de datos para Nexcloud
En esta publicación de blog, usamos un total de 6 nodos.
- 2 servidores proxy
- 3 x base de datos + servidores de aplicaciones
- 1 servidor de controlador (ClusterControl)
El siguiente diagrama ilustra nuestra configuración final:
Para Percona XtraDB Cluster, se requiere un mínimo de 3 nodos para un sólido replicación multimaestro. Las aplicaciones de Nextcloud se ubican dentro de los servidores de la base de datos, por lo que GlusterFS también debe configurarse en esos hosts.
El nivel del equilibrador de carga consta de 2 nodos por motivos de redundancia. Usaremos ClusterControl para implementar el nivel de la base de datos y los niveles del balanceador de carga. Todos los servidores se ejecutan en CentOS 7 con la siguiente definición de /etc/hosts en cada nodo:
192.168.0.21 nextcloud1 db1
192.168.0.22 nextcloud2 db2
192.168.0.23 nextcloud3 db3
192.168.0.10 vip db
192.168.0.11 proxy1 lb1 proxysql1
192.168.0.12 proxy2 lb2 proxysql2
Tenga en cuenta que GlusterFS y MySQL son procesos muy intensivos. Si está siguiendo esta configuración (GlusterFS y MySQL residen en un solo servidor), asegúrese de tener especificaciones de hardware decentes para los servidores.
Despliegue de base de datos de Nextcloud
Comenzaremos con la implementación de la base de datos para nuestro clúster Percona XtraDB de tres nodos mediante ClusterControl. Instale ClusterControl y luego configure SSH sin contraseña en todos los nodos que va a administrar ClusterControl (3 PXC + 2 proxies). En el nodo ClusterControl, haga:
$ whoami
root
$ ssh-copy-id 192.168.0.11
$ ssh-copy-id 192.168.0.12
$ ssh-copy-id 192.168.0.21
$ ssh-copy-id 192.168.0.22
$ ssh-copy-id 192.168.0.23
**Ingrese la contraseña raíz para el host respectivo cuando se le solicite.
Abra un navegador web y vaya a https://{ClusterControl-IP-address}/clustercontrol y cree un superusuario. Luego vaya a Implementar -> MySQL Galera. Siga el asistente de implementación en consecuencia. En la segunda etapa, 'Definir servidores MySQL', elija Percona XtraDB 5.7 y especifique la dirección IP para cada nodo de la base de datos. Asegúrese de obtener una marca verde después de ingresar los detalles del nodo de la base de datos, como se muestra a continuación:
Haga clic en "Implementar" para iniciar la implementación. El clúster de la base de datos estará listo en 15 a 20 minutos. Puede seguir el progreso de la implementación en Actividad -> Trabajos -> Crear clúster -> Detalles completos del trabajo. El clúster aparecerá en el panel de control del clúster de base de datos una vez implementado.
Ahora podemos continuar con la implementación del equilibrador de carga de la base de datos.
Implementación del equilibrador de carga de base de datos de Nextcloud
Se recomienda que Nextcloud se ejecute en una configuración de un solo escritor, donde las escrituras serán procesadas por un maestro a la vez, y las lecturas se pueden distribuir a otros nodos. Podemos usar ProxySQL 2.0 para lograr esta configuración, ya que puede enrutar las consultas de escritura a un solo maestro.
Para implementar un ProxySQL, haga clic en Acciones de clúster> Agregar equilibrador de carga> ProxySQL> Implementar ProxySQL. Ingrese la información requerida como se destaca con las flechas rojas:
Rellene todos los detalles necesarios como se destaca por las flechas de arriba. La dirección del servidor es el servidor lb1, 192.168.0.11. Más abajo, especificamos la contraseña de los usuarios de administración y supervisión de ProxySQL. Luego incluya todos los servidores MySQL en el conjunto de equilibrio de carga y luego elija "No" en la sección Transacciones implícitas. Haga clic en "Implementar ProxySQL" para iniciar la implementación.
Repita los mismos pasos anteriores para el balanceador de carga secundario, lb2 (pero cambie la "Dirección del servidor" a la dirección IP de lb2). De lo contrario, no tendríamos redundancia en esta capa.
Nuestros nodos ProxySQL ahora están instalados y configurados con dos grupos de host para Galera Cluster. Uno para el grupo de un solo maestro (grupo de host 10), donde todas las conexiones se reenviarán a un nodo de Galera (esto es útil para evitar interbloqueos de varios maestros) y el grupo de varios maestros (grupo de host 20) para todas las cargas de trabajo de solo lectura que se equilibrará con todos los servidores back-end MySQL.
A continuación, debemos implementar una dirección IP virtual para proporcionar un punto final único para nuestros nodos ProxySQL, de modo que su aplicación no necesite definir dos hosts ProxySQL diferentes. Esto también proporcionará capacidades automáticas de conmutación por error porque el nodo ProxySQL de respaldo tomará el control de la dirección IP virtual en caso de que algo salga mal en el nodo ProxySQL principal.
Vaya a ClusterControl -> Administrar -> Load Balancers -> Keepalived -> Implementar Keepalived. Elija "ProxySQL" como tipo de balanceador de carga y elija dos servidores ProxySQL distintos del menú desplegable. Luego especifique la dirección IP virtual así como la interfaz de red que escuchará, como se muestra en el siguiente ejemplo:
Una vez que se complete la implementación, debería ver los siguientes detalles en la barra de resumen del clúster:
Finalmente, cree una nueva base de datos para nuestra aplicación yendo a ClusterControl -> Administrar -> Esquemas y usuarios -> Crear base de datos y especifique "nextcloud". ClusterControl creará esta base de datos en cada nodo de Galera. Nuestro nivel de balanceador de carga ahora está completo.
Implementación de GlusterFS para Nextcloud
Los siguientes pasos deben realizarse en nextcloud1, nextcloud2, nextcloud3 a menos que se especifique lo contrario.
Paso uno
Se recomienda tener esto separado para el almacenamiento de GlusterFS, por lo que agregaremos un disco adicional en /dev/sdb y crearemos una nueva partición:
$ fdisk /dev/sdb
Siga el asistente de creación de particiones fdisk presionando la siguiente tecla:
n > p > Enter > Enter > Enter > w
Paso dos
Verifique si se ha creado /dev/sdb1:
$ fdisk -l /dev/sdb1
Disk /dev/sdb1: 8588 MB, 8588886016 bytes, 16775168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Paso tres
Formatear la partición con XFS:
$ mkfs.xfs /dev/sdb1
Cuarto Paso
Montar la partición como /storage/brick:
$ mkdir /glusterfs
$ mount /dev/sdb1 /glusterfs
Verifique que todos los nodos tengan el siguiente diseño:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 40G 0 disk
└─sda1 8:1 0 40G 0 part /
sdb 8:16 0 8G 0 disk
└─sdb1 8:17 0 8G 0 part /glusterfs
Paso cinco
Cree un subdirectorio llamado brick en /glusterfs:
$ mkdir /glusterfs/brick
Paso Seis
Para la redundancia de aplicaciones, podemos usar GlusterFS para la replicación de archivos entre los hosts. En primer lugar, instale el repositorio GlusterFS para CentOS:
$ yum install centos-release-gluster -y
$ yum install epel-release -y
Paso Siete
Instalar servidor GlusterFS
$ yum install glusterfs-server -y
Paso Ocho
Habilitar e iniciar el demonio gluster:
$ systemctl enable glusterd
$ systemctl start glusterd
Paso Nueve
En nextcloud1, pruebe los otros nodos:
(nextcloud1)$ gluster peer probe 192.168.0.22
(nextcloud1)$ gluster peer probe 192.168.0.23
Puede verificar el estado del par con el siguiente comando:
(nextcloud1)$ gluster peer status
Number of Peers: 2
Hostname: 192.168.0.22
Uuid: f9d2928a-6b64-455a-9e0e-654a1ebbc320
State: Peer in Cluster (Connected)
Hostname: 192.168.0.23
Uuid: 100b7778-459d-4c48-9ea8-bb8fe33d9493
State: Peer in Cluster (Connected)
Paso Diez
En nextcloud1, cree un volumen replicado en los nodos probados:
(nextcloud1)$ gluster volume create rep-volume replica 3 192.168.0.21:/glusterfs/brick 192.168.0.22:/glusterfs/brick 192.168.0.23:/glusterfs/brick
volume create: rep-volume: success: please start the volume to access data
Paso Once
Inicie el volumen replicado en nextcloud1:
(nextcloud1)$ gluster volume start rep-volume
volume start: rep-volume: success
Verifique que el volumen replicado y los procesos estén en línea:
$ gluster volume status
Status of volume: rep-volume
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick 192.168.0.21:/glusterfs/brick 49152 0 Y 32570
Brick 192.168.0.22:/glusterfs/brick 49152 0 Y 27175
Brick 192.168.0.23:/glusterfs/brick 49152 0 Y 25799
Self-heal Daemon on localhost N/A N/A Y 32591
Self-heal Daemon on 192.168.0.22 N/A N/A Y 27196
Self-heal Daemon on 192.168.0.23 N/A N/A Y 25820
Task Status of Volume rep-volume
------------------------------------------------------------------------------
There are no active volume tasks
Paso Doce
Monte el volumen replicado en /var/www/html. Crea el directorio:
$ mkdir -p /var/www/html
Paso trece
13) Agregue la siguiente línea en /etc/fstab para permitir el montaje automático:
/dev/sdb1 /glusterfs xfs defaults,defaults 0 0
localhost:/rep-volume /var/www/html glusterfs defaults,_netdev 0 0
Paso Catorce
Monte el GlusterFS en /var/www/html:
$ mount -a
Y verifica con:
$ mount | grep gluster
/dev/sdb1 on /glusterfs type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
localhost:/rep-volume on /var/www/html type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
El volumen replicado ahora está listo y montado en cada nodo. Ahora podemos proceder a implementar la aplicación.
Implementación de la aplicación Nextcloud
Los siguientes pasos deben realizarse en nextcloud1, nextcloud2 y nextcloud3 a menos que se especifique lo contrario.
Nextcloud requiere PHP 7.2 y versiones posteriores, y para la distribución de CentOS, debemos habilitar varios repositorios como EPEL y Remi para simplificar el proceso de instalación.
Paso uno
Si SELinux está habilitado, desactívelo primero:
$ setenforce 0
$ sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
También puede ejecutar Nextcloud con SELinux habilitado siguiendo esta guía.
Paso dos
Instala los requisitos de Nextcloud y habilita el repositorio de Remi para PHP 7.2:
$ yum install -y epel-release yum-utils unzip curl wget bash-completion policycoreutils-python mlocate bzip2
$ yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ yum-config-manager --enable remi-php72
Paso tres
Instalar las dependencias de Nextcloud, principalmente paquetes relacionados con Apache y PHP 7.2:
$ yum install -y httpd php72-php php72-php-gd php72-php-intl php72-php-mbstring php72-php-mysqlnd php72-php-opcache php72-php-pecl-redis php72-php-pecl-apcu php72-php-pecl-imagick php72-php-xml php72-php-pecl-zip
Cuarto Paso
Habilite Apache y ejecútelo:
$ systemctl enable httpd.service
$ systemctl start httpd.service
Paso cinco
Haga un enlace simbólico para que PHP use PHP 7.2 binario:
$ ln -sf /bin/php72 /bin/php
Paso Seis
En nextcloud1, descargue Nextcloud Server desde aquí y extráigalo:
$ wget https://download.nextcloud.com/server/releases/nextcloud-17.0.0.zip
$ unzip nextcloud*
Séptimo Paso
En nextcloud1, copie el directorio en /var/www/html y asigne la propiedad correcta:
$ cp -Rf nextcloud /var/www/html
$ chown -Rf apache:apache /var/www/html
**Tenga en cuenta que el proceso de copia en /var/www/html llevará algún tiempo debido a la replicación del volumen de GlusterFS.
Paso Ocho
Antes de proceder a abrir el asistente de instalación, debemos deshabilitar la variable pxc_strict_mode a otra que no sea "ENFORCING" (el valor predeterminado). Esto se debe al hecho de que la importación de la base de datos de Nextcloud tendrá una cantidad de tablas sin una clave principal definida que no se recomienda ejecutar en Galera Cluster. Esto se explica con más detalles en la sección Tuning más abajo.
Para cambiar la configuración con ClusterControl, simplemente vaya a Administrar -> Configuraciones -> Cambiar/Establecer parámetros:
Elija todas las instancias de base de datos de la lista e ingrese:
- Grupo:MYSQLD
- Parámetro:pxc_strict_mode
- Nuevo valor:PERMISIVO
ClusterControl realizará los cambios necesarios en cada nodo de la base de datos automáticamente. Si el valor se puede cambiar durante el tiempo de ejecución, será efectivo inmediatamente. ClusterControl también configura el valor dentro del archivo de configuración de MySQL para la persistencia. Deberías ver el siguiente resultado:
Paso Nueve
Ahora estamos listos para configurar nuestra instalación de Nextcloud. Abra el navegador y vaya al servidor HTTP de nextcloud1 en http://192.168.0.21/nextcloud/ y se le presentará el siguiente asistente de configuración:
Configure la sección "Almacenamiento y base de datos" con el siguiente valor:
- Carpeta de datos:/var/www/html/nextcloud/data
- Configurar la base de datos:MySQL/MariaDB
- Nombre de usuario:nextcloud
- Contraseña:(la contraseña para el usuario nextcloud)
- Base de datos:nextcloud
- Host:192.168.0.10:6603 (La dirección IP virtual con puerto ProxySQL)
Haga clic en "Finalizar configuración" para iniciar el proceso de configuración. Espere hasta que termine y será redirigido al panel de control de Nextcloud para el usuario "admin". La instalación está completa. La siguiente sección proporciona algunos consejos de ajuste para funcionar de manera eficiente con Galera Cluster.
Ajuste de la base de datos de Nextcloud
Clave principal
Tener una clave principal en cada tabla es vital para la replicación del conjunto de escritura de Galera Cluster. Para una tabla relativamente grande sin clave principal, una gran transacción de actualización o eliminación bloquearía completamente su clúster durante mucho tiempo. Para evitar peculiaridades y casos extremos, simplemente asegúrese de que todas las tablas utilicen el motor de almacenamiento InnoDB con una clave primaria explícita (la clave única no cuenta).
La instalación predeterminada de Nextcloud creará un montón de tablas en la base de datos especificada y algunas de ellas no cumplen con esta regla. Para comprobar si las tablas son compatibles con Galera, podemos ejecutar la siguiente sentencia:
mysql> SELECT DISTINCT CONCAT(t.table_schema,'.',t.table_name) as tbl, t.engine, IF(ISNULL(c.constraint_name),'NOPK','') AS nopk, IF(s.index_type = 'FULLTEXT','FULLTEXT','') as ftidx, IF(s.index_type = 'SPATIAL','SPATIAL','') as gisidx FROM information_schema.tables AS t LEFT JOIN information_schema.key_column_usage AS c ON (t.table_schema = c.constraint_schema AND t.table_name = c.table_name AND c.constraint_name = 'PRIMARY') LEFT JOIN information_schema.statistics AS s ON (t.table_schema = s.table_schema AND t.table_name = s.table_name AND s.index_type IN ('FULLTEXT','SPATIAL')) WHERE t.table_schema NOT IN ('information_schema','performance_schema','mysql') AND t.table_type = 'BASE TABLE' AND (t.engine <> 'InnoDB' OR c.constraint_name IS NULL OR s.index_type IN ('FULLTEXT','SPATIAL')) ORDER BY t.table_schema,t.table_name;
+---------------------------------------+--------+------+-------+--------+
| tbl | engine | nopk | ftidx | gisidx |
+---------------------------------------+--------+------+-------+--------+
| nextcloud.oc_collres_accesscache | InnoDB | NOPK | | |
| nextcloud.oc_collres_resources | InnoDB | NOPK | | |
| nextcloud.oc_comments_read_markers | InnoDB | NOPK | | |
| nextcloud.oc_federated_reshares | InnoDB | NOPK | | |
| nextcloud.oc_filecache_extended | InnoDB | NOPK | | |
| nextcloud.oc_notifications_pushtokens | InnoDB | NOPK | | |
| nextcloud.oc_systemtag_object_mapping | InnoDB | NOPK | | |
+---------------------------------------+--------+------+-------+--------+
El resultado anterior muestra que hay 7 tablas que no tienen una clave principal definida. Para solucionar lo anterior, simplemente agregue una clave principal con una columna de incremento automático. Ejecute los siguientes comandos en uno de los servidores de la base de datos, por ejemplo, nexcloud1:
(nextcloud1)$ mysql -uroot -p
mysql> ALTER TABLE nextcloud.oc_collres_accesscache ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_collres_resources ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_comments_read_markers ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_federated_reshares ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_filecache_extended ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_notifications_pushtokens ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_systemtag_object_mapping ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
Una vez que se hayan aplicado las modificaciones anteriores, podemos volver a configurar pxc_strict_mode al valor recomendado, "ENFORCING". Repita el paso 8 en la sección "Implementación de la aplicación" con el valor correspondiente.
Nivel de aislamiento de LECTURA COMPROMETIDA
El nivel de aislamiento de transacciones recomendado por Nextcloud es usar LECTURA COMPROMETIDA, mientras que Galera Cluster tiene por defecto un nivel de aislamiento de LECTURA REPETIBLE más estricto. El uso de READ-COMMITTED puede evitar la pérdida de datos en escenarios de alta carga (por ejemplo, al usar el cliente de sincronización con muchos clientes/usuarios y muchas operaciones paralelas).
Para modificar el nivel de transacción, vaya a ClusterControl -> Administrar -> Configuraciones -> Cambiar/Establecer parámetro y especifique lo siguiente:
Haga clic en "Continuar" y ClusterControl aplicará los cambios de configuración inmediatamente. No es necesario reiniciar la base de datos.
Nextcloud de múltiples instancias
Desde que realizamos la instalación en nextcloud1 al acceder a la URL, esta dirección IP se agrega automáticamente a la variable 'trusted_domains' dentro de Nextcloud. Cuando intentó acceder a otros servidores, por ejemplo, el servidor secundario, http://192.168.0.22/nextcloud, vería un error que indica que este host no está autorizado y debe agregarse a la variable trust_domain.
Por lo tanto, agregue todas las direcciones IP de los hosts en la matriz "trusted_domain" dentro de /var/www/html/nextcloud/config/config.php, como se muestra a continuación:
'trusted_domains' =>
array (
0 => '192.168.0.21',
1 => '192.168.0.22',
2 => '192.168.0.23'
),
La configuración anterior permite a los usuarios acceder a los tres servidores de aplicaciones a través de las siguientes URL:
- http://192.168.0.21/nextcloud (nextcloud1)
- http://192.168.0.22/nextcloud (nextcloud2)
- http://192.168.0.23/nextcloud (nextcloud3)
Nota:Puede agregar un nivel de equilibrador de carga sobre estas tres instancias de Nextcloud para lograr una alta disponibilidad para el nivel de la aplicación mediante el uso de proxies inversos HTTP disponibles en el mercado como HAProxy o nginx. Eso está fuera del alcance de esta publicación de blog.
Uso de Redis para el bloqueo de archivos
El mecanismo de bloqueo de archivos transaccionales de Nextcloud bloquea los archivos para evitar que se dañen durante el funcionamiento normal. Se recomienda instalar Redis para encargarse del bloqueo de archivos transaccionales (esto está habilitado de forma predeterminada), lo que evitará que el clúster de la base de datos maneje este trabajo pesado.
Para instalar Redis, simplemente:
$ yum install -y redis
$ systemctl enable redis.service
$ systemctl start redis.service
Agregue las siguientes líneas dentro de /var/www/html/nextcloud/config/config.php:
'filelocking.enabled' => true,
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => '192.168.0.21',
'port' => 6379,
'timeout' => 0.0,
),
Para obtener más detalles, consulte esta documentación, Bloqueo de archivos transaccionales.
Conclusión
Nextcloud puede configurarse para ser un servicio de alojamiento de archivos escalable y de alta disponibilidad para satisfacer sus demandas de uso compartido de archivos privados. En este blog, mostramos cómo puede brindar redundancia en Nextcloud, el sistema de archivos y las capas de la base de datos.