sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo agrupar Odoo 12 con replicación de transmisión de PostgreSQL para alta disponibilidad

Odoo (anteriormente conocido como OpenERP) es un conjunto de aplicaciones empresariales de código abierto. Viene en dos versiones:comunidad y empresa. Algunas de las aplicaciones más populares (¡y gratuitas!) integradas en esta plataforma son Discuss, CRM, Inventory, Website, Employee, Leaves, Recruitment, Expenses, Accounting, Invoicing, Point of Sale y muchas más.

En esta publicación de blog, veremos cómo agrupar Odoo para lograr una alta disponibilidad y escalabilidad. Esta publicación es similar a nuestras publicaciones anteriores sobre cómo escalar Drupal, WordPress, Magento. Los softwares utilizados son Odoo 12, HAProxy 1.8.8, Keepalived 1.3.9, PostgreSQL 11 y OCFS2 (Oracle Cluster File System).

Nuestra configuración consta de 6 servidores:

  • lb1 (HAProxy) + keepalived + ClusterControl - 192.168.55.101
  • lb2 (HAProxy) + keepalived + almacenamiento compartido - 192.168.55.102
  • odoo1 - 192.168.55.111
  • odoo2 - 192.168.55.112
  • postgresql1 (maestro) - 192.168.55.121
  • postgresql2 (esclavo) - 192.168.55.122

Todos los nodos se ejecutan en Ubuntu 18.04.2 LTS (Bionic). Usaremos ClusterControl para implementar y administrar PostgreSQL, Keepalived y HAProxy, ya que nos ahorrará mucho trabajo. ClusterControl se ubicará junto con HAProxy en lb1, mientras que agregaremos un disco adicional a lb2 para usarlo como proveedor de almacenamiento compartido. Este disco se montará mediante un sistema de archivos en clúster denominado OCFS2 como directorio compartido. Una dirección IP virtual, 192.168.55.100, actúa como punto final único para nuestro servicio de base de datos.

El siguiente diagrama ilustra la arquitectura general de nuestro sistema:

El siguiente es el contenido de /etc/hosts en todos los nodos:

192.168.55.101  lb1.local lb1 cc.local cc
192.168.55.102  lb2.local lb2 storage.local storage
192.168.55.111  odoo1.local odoo1
192.168.55.112  odoo2.local odoo2
192.168.55.121  postgresql1.local postgresql1
192.168.55.122  postgresql2.local postgresql2

Implementación de la replicación de secuencias de PostgreSQL

Comenzaremos instalando ClusterControl en lb1:

$ wget severalnines.com/downloads/cmon/install-cc
$ chmod 755 ./install-cc
$ sudo ./install-cc

Siga el asistente de instalación, deberá responder algunas preguntas durante el proceso.

Configure SSH sin contraseña desde el nodo ClusterControl (lb1) a todos los nodos que serán administrados por ClusterControl, que es lb1 (en sí), lb2, postresql1 y postgresql2. Pero primero, genera una clave SSH:

$ whoami
ubuntu
$ ssh-keygen -t rsa # press Enter on all prompts

Luego copie la clave a todos los nodos de destino usando la herramienta ssh-copy-id:

$ whoami
ubuntu
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]

Abra la interfaz de usuario de ClusterControl en http://192.168.55.101/clustercontrol y cree un usuario superadministrador con contraseña. Se le redirigirá al panel de control de la interfaz de usuario de ClusterControl. Luego, implemente un nuevo clúster de PostgreSQL haciendo clic en el botón "Implementar" en el menú superior. Se le presentará el siguiente cuadro de diálogo de implementación:

Esto es lo que escribimos en el siguiente cuadro de diálogo, "Definir servidores PostgreSQL":

  • Puerto del servidor:5432
  • Usuario:postgres
  • Contraseña:s3cr3t
  • Versión:11
  • Dirección de datos:
  • Repositorio:Usar repositorios de proveedores

En la sección "Definir topología", especifique la dirección IP de postgresql1 y postgresql2 según corresponda:

En la última sección, "Resumen de implementación", tiene una opción para habilitar la replicación síncrona. Dado que usaremos el esclavo solo para fines de conmutación por error (el esclavo no realizará ninguna operación de lectura), simplemente dejamos el valor predeterminado como está. Luego, presione "Implementar" para iniciar la implementación del clúster de la base de datos. Puede monitorear el progreso de la implementación consultando Actividad> Trabajos> Crear clúster :

Mientras tanto, tome un café y la implementación del clúster debería completarse en 10 a 15 minutos.

Implementación de balanceadores de carga e IP virtual para servidores PostgreSQL

En este punto, ya tenemos un clúster de replicación de PostgreSQL de dos nodos ejecutándose en una configuración maestro-esclavo:

El siguiente paso es implementar el nivel del balanceador de carga para nuestra base de datos, lo que nos permite vincularlo con una dirección IP virtual y proporcionar un punto final único para la aplicación. Configuraremos las opciones de implementación de HAProxy de la siguiente manera:

La aplicación no admite la división de lectura y escritura de forma nativa, por lo que utilizaremos el método activo-pasivo para lograr una alta disponibilidad. El mejor algoritmo de equilibrio de carga es la política de "fuente", ya que solo usamos un nodo de PostgreSQL a la vez.

Repita el mismo paso para el otro balanceador de carga, lb2. Cambie la "Dirección del servidor" a 192.168.55.102 en su lugar. Así es como se ve después de que se completa la implementación si va a la página Nodos:

Se espera la línea roja en el primer oyente donde HAProxy muestra que postgresql2 (192.168.55.122) está inactivo porque el script de verificación de estado devuelve que el nodo está activo pero no es un maestro. El segundo oyente con línea azul (haproxy_5434_ro) muestra que el nodo está ACTIVADO pero en estado de "respaldo". Sin embargo, este oyente se puede ignorar ya que la aplicación no admite la división de lectura y escritura.

A continuación, implementamos instancias de Keepalived sobre estos balanceadores de carga para vincularlos con una sola dirección IP virtual. Vaya a Administrar -> Equilibrador de carga -> Keepalived -> Implementar Keepalived y especifique la primera y la segunda instancia de HAProxy, luego la dirección IP virtual y la interfaz de red para escuchar:

Haga clic en "Implementar Keepalived" para iniciar la implementación. El servicio de conexión de PostgreSQL ahora tiene una carga equilibrada para cualquiera de los nodos de la base de datos y es accesible a través del puerto 192.168.55.100 5433.

Configurar iSCSI

El servidor de almacenamiento (lb2) necesita exportar un disco a través de iSCSI para que pueda montarse en ambos servidores de aplicaciones de Odoo (odoo1 y odoo2). iSCSI básicamente le dice a su kernel que tiene un disco SCSI y transporta ese acceso a través de IP. El "servidor" se denomina "objetivo" y el "cliente" que utiliza ese dispositivo iSCSI es el "iniciador".

En primer lugar, instale el objetivo iSCSI en lb2:

$ sudo apt install -y tgt

Habilitar tgt en el arranque:

$ systemctl enable tgt

Se prefiere tener un disco separado para la agrupación en clústeres del sistema de archivos. Así, vamos a utilizar otro disco montado en lb2 (/dev/sdb) para ser compartido entre servidores de aplicaciones (odoo1 y odoo2). En primer lugar, cree un objetivo iSCSI utilizando la herramienta tgtadm:

$ sudo tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2019-02.lb2:odcfs2

Luego, asigne el dispositivo de bloque /dev/sdb al número de unidad lógica (LUN) 1 junto con el ID de destino 1:

$ sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/sdb

Luego, permita que los nodos iniciadores en la misma red accedan a este objetivo:

$ sudo tgtadm --lld iscsi --op bind --mode target --tid 1 --initiator-address 192.168.55.0/24

Use la herramienta tgt-admin para volcar las líneas de configuración de iSCSI y guárdela como un archivo de configuración para que sea persistente durante el reinicio:

$ sudo tgt-admin --dump > /etc/tgt/conf.d/shareddisk.conf

Finalmente, reinicie el servicio de destino iSCSI:

$ sudo systemctl restart tgt

** Los siguientes pasos deben realizarse en odoo1 y odoo2.

Instale el iniciador iSCSI en los hosts respectivos:

$ sudo apt-get install -y open-iscsi

Configure el iniciador iSCSI para que se inicie automáticamente:

$ sudo systemctl enable open-iscsi

Descubra objetivos iSCSI que hemos configurado anteriormente:

$ sudo iscsiadm -m discovery -t sendtargets -p lb2
192.168.55.102:3260,1 iqn.2019-02.lb2:odcfs2

Si ve un resultado similar al anterior, significa que podemos ver y conectarnos al objetivo iSCSI. Utilice el siguiente comando para conectarse al destino iSCSI en lb2:

$ sudo iscsiadm -m node --targetname iqn.2019-02.lb2:odcfs2 -p lb2 -l
Logging in to [iface: default, target: iqn.2019-02.lb2:odcfs2, portal: 192.168.55.102,3260] (multiple)
Login to [iface: default, target: iqn.2019-02.lb2:odcfs2, portal: 192.168.55.102,3260] successful.

Asegúrese de que puede ver el nuevo disco duro (/dev/sdb) en el directorio /dev:

$ sudo ls -1 /dev/sd*
/dev/sda
/dev/sda1
/dev/sda2
/dev/sda3
/dev/sdb

Nuestro disco compartido ahora está montado en ambos servidores de aplicaciones (odoo1 y odoo2).

Configuración de OCFS2 para Odoo

** Los siguientes pasos deben realizarse en odoo1 a menos que se especifique lo contrario.

OCFS2 permite que el sistema de archivos se monte en más de un lugar. Instale las herramientas OCFS2 en los servidores odoo1 y odoo2:

$ sudo apt install -y ocfs2-tools

Crear una tabla de particiones de disco para la unidad de disco duro /dev/sdb:

$ sudo cfdisk /dev/sdb

Cree una partición utilizando las siguientes secuencias en el asistente de cfdisk:Nuevo> Primario> aceptar tamaño> Escribir> sí> Salir .

Cree un sistema de archivos OCFS2 en /dev/sdb1:

$ sudo mkfs.ocfs2 -b 4K -C 128K -L "Odoo_Cluster" /dev/sdb1
mkfs.ocfs2 1.8.5
Cluster stack: classic o2cb
Label: Odoo_Cluster
Features: sparse extended-slotmap backup-super unwritten inline-data strict-journal-super xattr indexed-dirs refcount discontig-bg append-dio
Block size: 4096 (12 bits)
Cluster size: 131072 (17 bits)
Volume size: 21473656832 (163831 clusters) (5242592 blocks)
Cluster groups: 6 (tail covers 2551 clusters, rest cover 32256 clusters)
Extent allocator size: 4194304 (1 groups)
Journal size: 134217728
Node slots: 8
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 3 block(s)
Formatting Journals: done
Growing extent allocator: done
Formatting slot map: done
Formatting quota files: done
Writing lost+found: done
mkfs.ocfs2 successful

Cree un archivo de configuración de clúster en /etc/ocfs2/cluster.conf y defina las directivas de nodo y clúster de la siguiente manera:

# /etc/ocfs2/cluster.conf
cluster:
        node_count = 2
        name = ocfs2
node:
        ip_port = 7777
        ip_address = 192.168.55.111
        number = 1
        name = odoo1
        cluster = ocfs2
node:
        ip_port = 7777
        ip_address = 192.168.55.112
        number = 2
        name = odoo2
        cluster = ocfs2

Tenga en cuenta que los atributos debajo de la cláusula de nodo o clúster deben estar después de una tabulación.

** Los siguientes pasos deben realizarse en odoo1 y odoo2 a menos que se especifique lo contrario.

Cree el mismo archivo de configuración (/etc/ocfs2/cluster.conf) en odoo2. Este archivo debe ser el mismo en todos los nodos del clúster y los cambios realizados en este archivo deben propagarse a los demás nodos del clúster.

Reinicie el servicio o2cb para aplicar los cambios que hicimos en /etc/ocfs2/cluster.conf:

$ sudo systemctl restart o2cb

Cree el directorio de archivos de Odoo en /var/lib/odoo:

$ sudo mkdir -p /var/lib/odoo

Obtenga el ID de bloque para el dispositivo /dev/sdb1. Se recomienda UUID en fstab si usa un dispositivo iSCSI:

$ sudo blkid /dev/sdb1 | awk {'print $3'}
UUID="93a2b6c4-d800-4532-9a9b-2d2f2f1a726b"

Utilice el valor UUID cuando agregue la siguiente línea en /etc/fstab:

UUID=93a2b6c4-d800-4532-9a9b-2d2f2f1a726b       /var/lib/odoo     ocfs2   defaults,_netdev        0 0

Registre el clúster ocfs2 y monte el sistema de archivos desde fstab:

$ sudo o2cb register-cluster ocfs2
$ sudo mount -a

Verificar con:
 

$ mount | grep odoo
/dev/sdb1 on /var/lib/odoo type ocfs2 (rw,relatime,_netdev,heartbeat=local,nointr,data=ordered,errors=remount-ro,atime_quantum=60,coherency=full,user_xattr,acl,_netdev)

Si puede ver la línea anterior en todos los servidores de aplicaciones, somos buenos para instalar Odoo.

Instalación y configuración de Odoo 12

** Los siguientes pasos deben realizarse en odoo1 y odoo2 a menos que se especifique lo contrario.

Instale Odoo 12 a través del repositorio de paquetes:

$ wget -O - https://nightly.odoo.com/odoo.key | sudo apt-key add -
$ echo "deb http://nightly.odoo.com/12.0/nightly/deb/ ./" | sudo tee -a /etc/apt/sources.list.d/odoo.list
$ sudo apt update && sudo apt install odoo

De forma predeterminada, el comando anterior instalará automáticamente el servidor PostgreSQL en el mismo host como parte de las dependencias de Odoo. Probablemente queramos detenerlo porque de todos modos no vamos a usar el servidor local:

$ sudo systemctl stop postgresql
$ sudo systemctl disable postgresql

En postgresql1, cree un usuario de base de datos llamado "odoo":

$ sudo -i
$ su - postgres
$ createuser --createrole --createdb --pwprompt odoo

Especifique una contraseña en el aviso. Luego, tanto en postgresql1 como en postgresql2, agregue la siguiente línea dentro de pg_hba.conf para permitir que la aplicación y los nodos del balanceador de carga se conecten. Como en nuestro caso, se encuentra en /etc/postgresql/11/main/pg_hba.conf:

host  all  all       192.168.55.0/24    md5

Luego vuelva a cargar el servidor PostgreSQL para cargar los cambios:

$ su - postgres
$ /usr/lib/postgresql/11/bin/pg_ctl reload -D /var/lib/postgresql/11/main/

Edite el archivo de configuración de Odoo en /etc/odoo/odoo.conf y configure los parámetros admin_passwd, db_host y db_password según corresponda:

[options]
; This is the password that allows database operations:
admin_passwd = admins3cr3t
db_host = 192.168.55.100
db_port = 5433
db_user = odoo
db_password = odoopassword
;addons_path = /usr/lib/python3/dist-packages/odoo/addons

Reinicie Odoo en ambos servidores para cargar los nuevos cambios:

$ sudo systemctl restart odoo

Luego, abra Odoo en uno de los servidores de aplicaciones a través del navegador web. En este ejemplo, nos conectamos a odoo1, por lo que la URL es http://192.168.55.111:8069/ y debería ver la siguiente página inicial:

Especifique la "Contraseña maestra" idéntica al valor admin_passwd definido en el archivo de configuración de Odoo. Luego complete toda la información requerida para la nueva empresa que utilizará esta plataforma.

Una vez hecho esto, espere un momento hasta que finalice la inicialización. Será redirigido al panel de administración de Odoo:

En este punto, la instalación de Odoo está completa y puede comenzar a configurar las aplicaciones comerciales para esta empresa. Todos los cambios de archivos realizados por este servidor de aplicaciones se almacenarán dentro del sistema de archivos en clúster ubicado en "/var/lib/odoo/.local" (que también se montó en otro servidor de aplicaciones, odoo2), mientras que los cambios en la base de datos se realizarán. en el nodo maestro de PostgreSQL.

A pesar de ejecutarse en dos hosts diferentes, tenga en cuenta que la aplicación Odoo en sí misma no tiene equilibrio de carga en este escrito. Puede usar las instancias de HAProxy implementadas para el clúster de la base de datos para lograr una mejor disponibilidad al igual que el servicio de la base de datos. Además, el sistema de archivos de disco compartido (OCFS2) utilizado por ambos servidores de aplicaciones todavía está expuesto a un punto único de falla, ya que todos usan el mismo dispositivo iSCSI en lb2 (imagínese si no se puede acceder a lb2).

Operación de conmutación por error de la base de datos

Quizás se pregunte qué sucedería si el maestro de PostgreSQL deja de funcionar. Si sucede, ClusterControl promoverá automáticamente el esclavo en ejecución para que se convierta en maestro, como se muestra en la siguiente captura de pantalla:

No es necesario que el usuario final haga nada, ya que la conmutación por error se realiza automáticamente (después de un período de gracia de 30 segundos). Una vez completada la conmutación por error, ClusterControl informará la nueva topología como:

Si el antiguo maestro vuelve a funcionar, el servicio de PostgreSQL se cerrará automáticamente y lo siguiente que debe hacer el usuario es volver a sincronizar el antiguo maestro desde el nuevo maestro yendo a Acciones de nodo> Reconstruir esclavo de replicación :

El antiguo maestro se convertirá en esclavo del nuevo maestro después de que se complete la operación de sincronización:

ClusterControl seguramente mejora la disponibilidad de la base de datos con su función de recuperación automática y resincronizar un nodo de base de datos defectuoso está a solo dos clics de distancia. ¿Qué tan simple es eso después de un evento de falla catastrófica?

Eso es todo amigos. ¡Feliz agrupamiento!