项目作者: octaviotron

项目描述 :
Zimbra Community Suite Cluster with Fencing in Proxmox KVM hosts
高级语言:
项目地址: git://github.com/octaviotron/zimbra.git
创建时间: 2020-01-18T21:01:37Z
项目社区:https://github.com/octaviotron/zimbra

开源协议:

下载


Cluster de Zimbra Community Suite en hosts KVM (Proxmox)

(english version in https://github.com/octaviotron/zimbra/blob/master/README.en.md)

Esta documentación es una guía completa de cómo instalar Zimbra (versión LTS 8.8.15) en un cluster corosync/pacemaker de máquinas virtuales en Proxmox. Incluye los pasos necesarios para permitir auto-provisión de cuentas usando un árbol LDAP externo e instrucciones para configurar Fencing (STONITH).

Prefacio

La versión comunitaria de Zimbra (ZCS) no provee funciones para trabajar en cluster. No existe documentación oficial para que los mensajes almacenados (zimlet mailboxd) tenga replicación y alta disponibilidad. La documentación solo trae instrucciones para hacer una configuración multi-maestro del servicio LDAP lo cual es insuficiente para un ambiente seguro de producción.

La solución propuesta en esta documentación consiste en configurar un cluster de 3 nodos donde el servicio Zimbra sea un recurso de pacemaker. Por suerte todos los archivos necesarios para que funcione Zimbra están en /opt/zimbra de manera que creando en esa ruta un punto de montaje a un recurso de almacenamiento compartido entre los nodos y asegurando que sólo uno de estos pueda leer y escribir (evitando una situación de split-brain) se hace el truco de clusterizar Zimbra.

Diseño de Arquitectura

El panorama completo de la solución propuesta en este documento se puede obaservar en la siguiente ilustración:

diagrama

Las siguientes son las direcciones IP y nombres de hosts que usaremos como ejemplo:

  1. mbox01.domain.tld 192.168.0.1
  2. mbox02.domain.tld 192.168.0.2
  3. mbox03.domain.tld 192.168.0.3
  4. mbox.domain.tld 192.168.0.4 <--- IP virtual del Cluster de mailboxd
  5. proxy01.domin.tld 192.168.0.5
  6. proxy02.domin.tld 192.168.0.6
  7. proxy03.domin.tld 192.168.0.7
  8. mail.domian.tld 192.168.0.8 <--- IP virtual en roud-robin para los proxies
  9. proxmox.domain.tld 192.168.0.10 <--- Hypervisor Proxmox

Preparación del Sistema Operativo donde corre Proxmox

Es necesaria una unidad de almacenamiento SAN o NAS añadida como un dispositivo en cada máquiona virtual del cluster. Si se usa otro recurso (disco RAID compartido, montaje NFS, etc) es posible que la interfaz web de Proxmox no permita añadirlo a mas de una máquina virtual. en ese caso para hacerlo manualmente se pueden ejecutar las siguientes instrucciones:

  1. cd /etc/pve/qemu-server/
  2. qm set 101 -ide1 /dev/sdX

Notese que hay que cambiar “101“ por el ID de la máquina virtual que aplique en su caso y /dev/sdX por el dispositivo de almacenamiento que se ve desde el sistema operativo donde corre Proxmox.

NOTA: es necesario que esté habilitado este recurso de almacenamiento ANTES de proceder a hacer la instalación del cluster. Se debe asegurar ANTES que las máquinas virtuales al levantar vean el dispositivo para poder proseguir con los siguientes pasos.

Preparación del Sistema Operativo de los nodos del cluster

El proceso siguiente debe realizarse simultáneamente en todos los nodos del cluster. Es muy importante que el número de nodos sea exactamente 3 para que las instrucciones de esta documentación garanticen (completamente) que en su entorno resultante no habrá una situación de split-brain. Muchas recetas en internet (la mayoría de ellas) muestran como montar un cluster con sólo 2 nodos (inhabilitando el quorum) y eso tarde o temprano se traducirá en la corrupción de la data.

Se usará en este ejemplo CentOS 7 recién instalado en cada nodo, sólo con los paquetes básicos y escenciales.

En cada uno de los nodos se deben ejecutar los siguientes comandos, para añadir repositorios adicionales y actualizar el listado de paqquetes disponibles para ser instalados:

  1. rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
  2. rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
  3. yum -y update
  4. yum -y upgrade

En cada uno de los nodos, se instalan todos los paquetes necesarios:

  1. yum -y install ipa-client unzip net-tools sysstat openssh-clients \
  2. perl-core libaio nmap-ncat libstdc++.so.6 wget vim \
  3. pacemaker pcs corosync resource-agents pacemaker-cli fence-agents-all \
  4. git gcc make automake autoconf libtool pexpect python-requests

Es muy importante que cada nodo tenga asignado un FQDN. En el nodo “mbox01”:

  1. hostnamectl set-hostname "mbox01.domain.tld" && exec bash

(por supuesto, debe sustituir “domain.tld” por el nombre de su dominio)

En “mbox02”:

  1. hostnamectl set-hostname "mbox02.domain.tld" && exec bash

En “mbox03”:

  1. hostnamectl set-hostname "mbox03.domain.tld" && exec bash

Seguidamente, se deben colocar las direcciones de los demás componentes del sistema de correo, de manera que ante un fallo del DNS continúen funcionando los servicios y el cluster. Esto debe estar en /etc/hosts en cada uno de los nodos:

  1. 192.168.0.1 mbox01.domain.tld mbox01
  2. 192.168.0.2 mbox02.domain.tld mbox02
  3. 192.168.0.3 mbox03.domain.tld mbox03
  4. 192.168.0.4 mbox.domain.tld mbox
  5. 192.168.0.5 proxy01.domin.tld proxy01
  6. 192.168.0.6 proxy02.domin.tld proxy02
  7. 192.168.0.7 proxy03.domin.tld proxy03
  8. 192.168.0.8 mail.domian.tld mail
  9. 192.168.0.10 proxmox.domain.tld proxmox

Es necesario, en cada uno de los nodos, deshabilitar las políticas SELinux que trae CentOS por defecto:

  1. setenforce 0

Para que SELinux quede en ese estado en los próximos inicios del sistema operativo, es necesario cambiar la siguiente línea del archivo /etc/selinux/config en cada uno de los nodos:

  1. SELINUX=permissive

En cada uno de los nodos, el cortafuegos necesita tener habilitados los puertos necesarios:

  1. firewall-cmd --permanent --add-port={25,80,110,143,389,443,465,587,993,995,5222,5223,9071,7071}/tcp
  2. firewall-cmd --reload

Dependiendo de cada caso, es posible que sea necesario habilitar otros puertos adicionales o el proceso puede fallar, se puede por tanto inahbilitar temporalmente el cortafuegos de la siguiente manera en cada nodo:

  1. systemctl stop firewalld
  2. systemctl disable firewalld

Al terminar todos los pasos de esta documentación, es importante asegurar cuáles puertos nos realmente necesarios tener abiertos y volver a levantar el servicio:

  1. systemctl start firewalld
  2. systemctl enable firewalld

Es necesario que no haya ningún otro servicio activo que use el puerto 25/tcp (SNMP) y CentOS por defecto provee un servicio postfix para el manejo de la mensajería interna del sistema operativo, así que es necesario detenerlo e inhabilitarlo en cada uno de los nodos:

  1. systemctl stop postfix
  2. systemctl disable postfix

Todos los clientes deben encontrar la dirección IP de los servicios, por lo tanto debe haber un registro en el DNS de cada uno de los nodos del cluster. Esto debe hacerse manualmente para cada caso.

Si se usa FreeIPA para lograr esta resolución de nombres, en cada nodo debe realizarse el enroll mediante el siguiente comando:

  1. ipa-client-install --enable-dns-updates

Para incorporar cada nodo como miembro del cluster se debe colocar en cada uno la misma contraseña para el usuario “hacluster”:

  1. echo "hacluster:tu_password"|chpasswd

Se debe cambiar “tu_password” por alguna contraseña arbitraria la cual debe ser la misma en todos los nodos.

Seguidamente en cada nodo se levanta el cluster:

  1. systemctl start pcsd
  2. systemctl status pcsd

El sistema de cluster en CentOS presenta un mal funcionamiento en algunos casos, sobre todo cuando corre en hardware con procesadores muy veloces, por lo cual es necesario retrasar levemente su inicio de manera de asegurar que a otros servicios les de tiempo de levantar antes de ser consiltados por corosync. Esto se logra modificando el archivo /usr/lib/systemd/system/corosync.service, añadiendo la directiva “ExecStartPre=/usr/bin/sleep 3“ en la sección “[service]“ del script en systemd. Esta sección del archivo debe quedar así entonces en todos los nodos:

  1. [Service]
  2. ExecStartPre=/usr/bin/sleep 3
  3. ExecStart=/usr/share/corosync/corosync start
  4. ExecStop=/usr/share/corosync/corosync stop
  5. Type=forking

Para que el cambio surja efecto, luego de haber hecho la modificación debe renovarse la configuración que reside en memoria en cada uno de los nodos:

  1. systemctl daemon-reload

Creación de los recursos del cluster

En uno solo de los nodos, se autorizan los hosts que componen el cluster:

  1. pcs cluster auth mbox01.domain.tld mbox02.domain.tld mbox03.domain.tld

La instrucción anterior pedirá un usuario, donde se debe colocar “hacluster“ y seguidamente se solicitará una contraseña, donde debe colocarse la suministrada en los pasos anteriores (donde se sustituyo “tu_password”).

Se debe suministrar un nomnre al cluster (“cluster_zimbra” en este ejemplo), esto se hace en uno solo de los nodos:

  1. pcs cluster setup --name cluster_zimbra mbox01.domain.tld mbox02.domain.tld mbox03.domain.tld

De la misma manera en uno de los nodos se levanta el cluster:

  1. pcs cluster start --all

Con las siguientes instrucciones se puede verificar el estado de los componentes que hasta ahora se han configurado en cluster, estos comandos deben dar la misma salida al ejecutarse en cualquiera de los nodos:

  1. pcs status cluster
  2. pcs status corosync

En el diseño actual no se considera necesario configurar el fencing de los nodos, por lo cual se desactiva STONITH. En una sección posterior de este documento se explica detalladamente cómo habilitarlo en caso que se considere realmente bnecesario:

  1. pcs property set stonith-enabled=false

Definición de la IP virtual del cluster

Para crear el recurso de IP virtual, se ejecuta el siguiente comando en uno de los nodos del cluster:

  1. pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.0.4 cidr_netmask=32 nic=eth0:0 op monitor interval=30s

En este caso se indica “eth0” como la interfaz para crear el alias “et0:0” que tendrá asociada la IP Virtual. Se debe verificar que es “eth0” el nombre del dispositivo de red que usa el Sistema Operativo del nodo.

Se verifica que se ha creado satisfactoriamente este recusro ejecutando el siguiente comando:

  1. pcs status resources

En la salida obtenida se verá una línea similar a esta, indicando que el recurso ha sido asingado al host mbox01:

  1. virtual_ip (ocf::heartbeat:IPaddr2): Started mbox01.domain.tls

Creación del recurso en el cluster para el servicio ZIMBRA

Se crea un archivo /usr/lib/ocf/resource.d/heartbeat/zimbractl con el siguiente contenido:

  1. #!/bin/sh
  2. #
  3. # Resource script for Zimbra
  4. # Description: Manages Zimbra as an OCF resource in
  5. # an high-availability setup.
  6. # Author: RRMP <tigerlinux@gmail.com>
  7. # License: GNU General Public License (GPL)
  8. #
  9. # usage: $0 {start|stop|reload|monitor|validate-all|meta-data}
  10. # The "start" arg starts a Zimbra instance
  11. # The "stop" arg stops it.
  12. #
  13. # OCF parameters:
  14. # OCF_RESKEY_binary
  15. # OCF_RESKEY_config_dir
  16. # OCF_RESKEY_parameters
  17. #
  18. ##########################################################################
  19. # Initialization:
  20. : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
  21. . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
  22. : ${OCF_RESKEY_binary="zmcontrol"}
  23. : ${OCF_RESKEY_zimbra_dir="/opt/zimbra"}
  24. : ${OCF_RESKEY_zimbra_user="zimbra"}
  25. : ${OCF_RESKEY_zimbra_group="zimbra"}
  26. USAGE="Usage: $0 {start|stop|reload|status|monitor|validate-all|meta-data}";
  27. ##########################################################################
  28. usage() {
  29. echo $USAGE >&2
  30. }
  31. meta_data() {
  32. cat <<END
  33. <?xml version="1.0"?>
  34. <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
  35. <resource-agent name="postfix">
  36. <version>0.1</version>
  37. <longdesc lang="en">
  38. This script manages Zimbra as an OCF resource in a high-availability setup.
  39. </longdesc>
  40. <shortdesc lang="en">Manages a highly available Zimbra mail server instance</shortdesc>
  41. <parameters>
  42. <parameter name="binary" unique="0" required="0">
  43. <longdesc lang="en">
  44. Short name to the Zimbra control script.
  45. For example, "zmcontrol" of "/etc/init.d/zimbra".
  46. </longdesc>
  47. <shortdesc lang="en">
  48. Short name to the Zimbra control script</shortdesc>
  49. <content type="string" default="zmcontrol" ></content>
  50. </parameter>
  51. <parameter name="zimbra_dir" unique="1" required="0">
  52. <longdesc lang="en">
  53. Full path to Zimbra directory.
  54. For example, "/opt/zimbra".
  55. </longdesc>
  56. <shortdesc lang="en">
  57. Full path to Zimbra directory</shortdesc>
  58. <content type="string" default="/opt/zimbra" ></content>
  59. </parameter>
  60. <parameter name="zimbra_user" unique="1" required="0">
  61. <longdesc lang="en">
  62. Zimbra username.
  63. For example, "zimbra".
  64. </longdesc>
  65. <shortdesc lang="en">Zimbra username</shortdesc>
  66. <content type="string" default="zimbra" ></content>
  67. </parameter>
  68. <parameter name="zimbra_group"
  69. unique="1" required="0">
  70. <longdesc lang="en">
  71. Zimbra group.
  72. For example, "zimbra".
  73. </longdesc>
  74. <shortdesc lang="en">Zimbra group</shortdesc>
  75. <content type="string" default="zimbra" ></content>
  76. </parameter>
  77. </parameters>
  78. <actions>
  79. <action name="start" timeout="360s" ></action>
  80. <action name="stop" timeout="360s" ></action>
  81. <action name="reload" timeout="360s" ></action>
  82. <action name="monitor" depth="0" timeout="40s"
  83. interval="60s" ></action>
  84. <action name="validate-all" timeout="360s" ></action>
  85. <action name="meta-data" timeout="5s" ></action>
  86. </actions>
  87. </resource-agent>
  88. END
  89. }
  90. case $1 in
  91. meta-data)
  92. meta_data
  93. exit $OCF_SUCCESS
  94. ;;
  95. usage|help)
  96. usage
  97. exit $OCF_SUCCESS
  98. ;;
  99. start)
  100. echo "Starting Zimbra Services"
  101. echo "0" > /var/log/db-svc-started.log
  102. rm -f /var/log/zimbra-svc-stopped.log
  103. if [ -f /etc/init.d/zimbra ]
  104. then
  105. /etc/init.d/zimbra start
  106. fi
  107. ocf_log info "Zimbra started."
  108. exit $OCF_SUCCESS
  109. ;;
  110. stop)
  111. echo "Stopping Zimbra Services"
  112. rm -f /var/log/db-svc-started.log
  113. echo "0" > /var/log/zimbra-svc-stopped.log
  114. if [ -f /etc/init.d/zimbra ]
  115. then
  116. /etc/init.d/zimbra stop
  117. /bin/killall -9 -u zimbra
  118. fi
  119. ocf_log info "Zimbra stopped."
  120. exit $OCF_SUCCESS
  121. ;;
  122. status|monitor)
  123. echo "Zimbra Services Status"
  124. if [ -f /var/log/zimbra-svc-started.log ]
  125. then
  126. exit $OCF_SUCCESS
  127. else
  128. exit $OCF_NOT_RUNNING
  129. fi
  130. ;;
  131. restart|reload)
  132. echo "Zimbra Services Restart"
  133. ocf_log info "Reloading Zimbra."
  134. if [ -f /etc/init.d/zimbra ]
  135. then
  136. /etc/init.d/zimbra stop
  137. /bin/killall -9 -u zimbra
  138. /etc/init.d/zimbra start
  139. fi
  140. exit $OCF_SUCCESS
  141. ;;
  142. validate-all)
  143. echo "Validating Zimbra"
  144. exit $OCF_SUCCESS
  145. ;;
  146. *)
  147. usage
  148. exit $OCF_ERR_UNIMPLEMENTED
  149. ;;
  150. esac

Creado este archivo se le otorgan permisos de ejecución:

  1. chmod 755 /usr/lib/ocf/resource.d/heartbeat/zimbractl

Seguidamente se copia el archivo en los otros nodos:

  1. scp /usr/lib/ocf/resource.d/heartbeat/zimbractl root@mbox02.domain.tld:/usr/lib/ocf/resource.d/heartbeat/zimbractl
  2. scp /usr/lib/ocf/resource.d/heartbeat/zimbractl root@mbox03.domain.tld:/usr/lib/ocf/resource.d/heartbeat/zimbractl

Luego en cada nodo se le deben otorgar permisos de ejecución:

  1. chmod 755 /usr/lib/ocf/resource.d/heartbeat/zimbractl

Para añadir el recurso (llamdo “zimbractl” en este ejemplo) se ejecutan las siguientes instrucciones:

  1. pcs resource create svczimbra ocf:heartbeat:zimbractl op monitor interval=30s
  2. pcs resource op remove svczimbra monitor
  3. pcs constraint colocation add svczimbra virtual_ip INFINITY
  4. pcs constraint order virtual_ip then svczimbra

Se puede comprobar que se ha cargado el recurso mediente el siguiente comando:

  1. pcs status

Definición de la ruta con los archivos comunes

La ruta donde residen todos los archivos que necesitan los servicios relacionados con Zimbra se encuentran en /opt/zimbra. Se crea este directorio:

  1. mkdir -p /opt/zimbra

Ese directorio debe crearse como un recurso del cluster, de manera que sólo el nodo activo lo tendrá montado. Esto debe hacerse sólo en el nodo activo:

  1. cd /
  2. pcs cluster cib add_fs
  3. pcs -f add_fs resource create zimbra_fs Filesystem device="/dev/sdX" directory="/opt/zimbra" fstype="ext4"
  4. pcs -f add_fs constraint colocation add svczimbra zimbra_fs INFINITY
  5. pcs -f add_fs constraint order zimbra_fs then svczimbra
  6. pcs cluster cib-push add_fs

NOTA: es necesario cambiar “/dev/sdX“ para ajustarlo al nombre correcto del dispositivo de almacenamiento.

Finalmente, se concluye la configuración del cluster habilitando los servicios permanentemente:

  1. systemctl enable pcsd
  2. systemctl enable corosync
  3. systemctl enable pacemaker

Instalación de Zimbra

Se realizará la instalación de los pauetes de Zimbra Community Suite v8.8.15. Para eso, es necesario crear una entrada temporal en /etc/hosts que apunte a “mail.domain.tld“:

  1. 127.0.0.1 mail.domain.tld mail

Es importante que en /opt/zimbra se encuentre montado (dispositivo de almacenamiento que se compartirá entre los nodos).

En el primer nodo (el que se encuentra activo) se descarga e instala el Software:

  1. mkdir /root/zimbra && cd /root/zimbra
  2. wget https://files.zimbra.com/downloads/8.8.15_GA/zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  3. tar zxpf zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  4. cd zcs-8.8.15_GA_3869.RHEL7_64.20190918004220
  5. ./install.sh -s

Nóese la opción “-s“, la cual realizará la instalación sin configurar el sistema, lo cual se realizará posteriormente. El instalador realizará unas preguntas, que deben responderse como se especifican a continuación:

  1. Do you agree with the terms of the software license agreement? [N] y
  2. Use Zimbra's package repository [Y]
  3. Install zimbra-ldap [Y]
  4. Install zimbra-logger [Y]
  5. Install zimbra-mta [Y]
  6. Install zimbra-dnscache [Y]
  7. Install zimbra-snmp [Y]
  8. Install zimbra-store [Y]
  9. Install zimbra-apache [Y]
  10. Install zimbra-spell [Y]
  11. Install zimbra-memcached [Y]
  12. Install zimbra-proxy [Y]
  13. Install zimbra-drive [Y]
  14. Install zimbra-imapd (BETA - for evaluation only) [N] <--- ENTER
  15. Install zimbra-chat [Y]
  16. The system will be modified. Continue? [N] Y

Despùés de seleccionar la última de esas opciones, se descargarán y actualizarán los paquetes necesarios. En este punto puede ir por un café, porque Zimbra usa Java y todo lo que usa Java tarda mucho tiempo y consume mucho procesador y memoria, hasta para ejecutar los procesos mas simples.

Antes de configurar Zimbra, es necesario corregir la ruta en la cual se encuentran la unidad certificadora (CA):

  1. mkdir -p /opt/zimbra/java/jre/lib/security/
  2. ln -s /opt/zimbra/common/etc/java/cacerts /opt/zimbra/java/jre/lib/security/cacerts
  3. chown -R zimbra.zimbra /opt/zimbra/java

Ahora si, se puede correr el programa que configura Zimbra:

  1. /opt/zimbra/libexec/zmsetup.pl

Puede que aparezca un error como este:

  1. DNS ERROR resolving MX for mbox01.domain.tld
  2. It is suggested that the domain name have an MX record configured in DNS
  3. Change domain name? [Yes]

Esto quiere decir que no hay un registro MX para el hostname desde el cual se ejecuta el instalador que por defecto lo toma como el dominio de correo.

  1. Change domain name? [Yes] <---- ENTER
  2. Create domain: [mbox01.domain.tld] domain.tld <----- Se coloca acá el dominio (sin nombre de host)

Cuando termnia este proceso, se muestra un menú en el cual es necesario como primer paso definir una contraseña de administrador de Zimbra. Para hacer eso, se escogen las sigientes opciones cuando en en diálogo aparezca el mensaje “Address unconfigured (++) items (? - help)”

  • Seleccionar la opción 7: zimbra-store en el menú principal
  • Seleccionar la opción 4: Admin Password

Allí se coloca una contraseña o se toma nota de la que Zimbra aleatoriamente propone como opción. Para regresar al menú principal se presiona ENTER en el diálogo “Select, or ‘r’ for previous menu [r]” prompt message to go to main menu

Es necesario verificar que el dominio que se creará en el árbl LDAP coincide con el que se definió anteriormente. Si se omite este paso, es posible que los nombres difieran y los buzones de correo sean “usuario@mbox01.domain.tld“ y no “usuario@domain.tld“:

  • Seleccionar la opción 2: “zimbra-ldap” en el menú principal
  • Seleccionar la opción 3: “Domain to create” y verificar que coincida con el dominio raíz o cambiarlo en caso que nea necesario.

Se regresa al menú principal se presiona ENTER en el diálogo “Select, or ‘r’ for previous menu [r]” prompt message to go to main menu“ y desde allí se inicia la instalación sleccionado la opción “a”:

  1. Select from menu, or press 'a' to apply config (? - help) a

A continuación se guarda el archivo de configuración. Es importante acá tomar nota del nombre, el cual contiene una extensión aleatoriamente asignada por el instalador

  1. Save configuration data to a file? [Yes]
  2. Save config in file: [/opt/zimbra/config.21593]

Para proceder con la instalación en el Sistema Operativo de Zimbra, se responde “Yes”:

  1. The system will be modified - continue? [No] Yes

Zimbra se comenzará a a instalar… da tiempo para tomarse otro café, Java lo invita. Al terminar (después de haber tenido tiempo de hablar sobre religión o sobre el movimiento perpetuo en la física), saldrá el siguiente mensaje:

  1. Notify Zimbra of your installation? [Yes]
  2. Configuration complete - press return to exit

Ahora se copia el archivo de configuración a los demás nodos:

  1. scp /opt/zimbra/config.21593 mbox02.domain.tld:/root/zmconfig.log
  2. scp /opt/zimbra/config.21593 mbox03.domain.tld:/root/zmconfig.log

En este momento se debe borrar la línea temporal asignada a “mail.domain.tld“ en el archivo /etc/hosts

Instalación de Zimbra en los nodos mbox02 y mbox03

CUIDADO: Este procedimiento debe hacerse cuando el nodo esté en modo OFFLINE en el cluster, para evitar que la ruta /opt/zimbra esté siendo usada. Para detener el cluster en el nodo se ejecuta:

  1. pcs cluster stop mbox02.domain.tld
  2. pcs cluster stop mbox03.domain.tld

Para comenzar a instalar, al ejecutar el comando

  1. pcs status

Se obtendrá como respuesta

  1. Error: cluster is not currently running on this node

Con el nodo en offline hará falta de nuevo colocar “mail.domain.tld“ en /etc/hosts apuntando a 127.0.0.1.

Se procede a instalar Zimbra:

  1. mkdir /opt/zimbra
  2. mkdir /root/zimbra && cd /root/zimbra
  3. wget https://files.zimbra.com/downloads/8.8.15_GA/zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  4. tar zxpf zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  5. cd zcs-8.8.15_GA_3869.RHEL7_64.20190918004220
  6. ./install.sh -s

Hay que asegurar que las respuestas siguientes se respondan exactamente igual que en la instalación del primer nodo:

  1. Do you agree with the terms of the software license agreement? [N] y
  2. Use Zimbra's package repository [Y]
  3. Install zimbra-ldap [Y]
  4. Install zimbra-logger [Y]
  5. Install zimbra-mta [Y]
  6. Install zimbra-dnscache [Y]
  7. Install zimbra-snmp [Y]
  8. Install zimbra-store [Y]
  9. Install zimbra-apache [Y]
  10. Install zimbra-spell [Y]
  11. Install zimbra-memcached [Y]
  12. Install zimbra-proxy [Y]
  13. Install zimbra-drive [Y]
  14. Install zimbra-imapd (BETA - for evaluation only) [N] <--- press ENTER
  15. Install zimbra-chat [Y]
  16. The system will be modified. Continue? [N] Y

Tiempo para otro café (bueno… quizás no sea muy bueno para la salud… puede funcionar té o limonada en su lugar).

Cuando finalice la instalación:

  1. mkdir -p /opt/zimbra/java/jre/lib/security/
  2. ln -s /opt/zimbra/common/etc/java/cacerts /opt/zimbra/java/jre/lib/security/cacerts
  3. chown -R zimbra.zimbra /opt/zimbra/java

En este punto, se realiza la configuración usando el archivo copiado (via SCP) desde el primer nodo:

  1. /opt/zimbra/libexec/zmsetup.pl -c /root/zmconfig.log

Al finalizar, se detiene Zimbra y se eliminan los archivos de /opt pues se usarán sólo los almacenados en el dispositivo común:

  1. /etc/init.d/zimbra stop
  2. killall -9 -u zimbra
  3. mv /opt/zimbra /root/old-zimbra
  4. mkdir /opt/zimbra

Se elimina la línea temporal en /etc/hosts que apunta a “mail.domain.tld“.

Ahora, se levanta el cluster en este nodo:

  1. pcs cluster start mbox02.domain.tld
  2. pcs cluster start mbox03.domain.tld

Llegado a este punto, Zimbra trabajará en cluster activo-pasivo. Se puede hacer la prueba accediendo desde un navegador a https://mail.domain.tld, deteniendo (o apagando) el nodo que esté activo hará que el cluster pase todos los servicios a otro nodo. Se puede observar el proceso (que demora unos 2 minutos) de la siguiente forma:

  1. watch pcs status

(CONTOL + C para salir)

Auto-Provisión de cuentas vía LDAP (Opcional)

Si se desea usar un Arbol LDAP externo para la autenticación de cuentas de usuario, se deben seguir los siguientes pasos. En este ejemplo se usa la estructura de un servidor FreeIPA, pero para cualquier otro caso es necesario tener los mismos datos:

  • La URL del servicio LDAP, en este ejemplo ldap://freeipa.domain.tld:389
  • La base de búsqueda (LDAP Search Base) donde pueden ser encontradas las cuentas, por ejemplo cn=accounts,dc=domain,dc=tld
  • El filtro LDAP con el cual se obtiene una cuenta. Es importante que este filtro arroje siempre un solo resultado: (uid=%u)

Para configurar la auto-provisión se abre la interfaz de administración de Zimbra https://mail.domain.tld:7071 y se siguen los siguientes pasos:

  • Ir a Admin > Configuration > Domain y seleccionar el dominio, en nuestro caso domain.tld
  • Ir a Authentication en el menú de la izquierda y luego presionar el ícono en forma de engranaje en la esquina superior derecha de la ventana y allí seleccionar Autentication
  • En la ventana emergente que se abrirá se seleeciona la opción Use external LDAP y se da click en siguiente
  • Colocar el nombre de hos o la IP del servicio LDAP: freeipa.domain.tld
  • Colocar (uid=%u) en el campo donde pide el filtro LDAP
  • Colocar cn=users,cn=accounts,dc=domain,dc=tld en el campo “Base DN” y seleccionar siguiente
  • Probar los valores suministrados usando el botón de pruebas, donde habrá que suministrar un usuario y contraeeñas válidos en el LDAP
  • Presionar Finnish en el diálogo de configuración

Ahora desde una consola como root en el nodo activo del cluster se ejecuta la siguiente serie de comandos:

  1. su - zimbra
  2. zmprov md prue.ba +zimbraAutoProvAttrMap description=description
  3. zmprov md prue.ba +zimbraAutoProvAttrMap displayName=displayName
  4. zmprov md prue.ba +zimbraAutoProvAttrMap givenName=givenName
  5. zmprov md prue.ba +zimbraAutoProvAttrMap cn=cn
  6. zmprov md prue.ba +zimbraAutoProvAttrMap sn=sn
  7. zmprov md prue.ba zimbraAutoProvAuthMech LDAP
  8. zmprov md prue.ba zimbraAutoProvLdapSearchBase "cn=accounts,dc=domain,dc=tld"
  9. zmprov md prue.ba zimbraAutoProvLdapSearchFilter "(uid=%u)"
  10. zmprov md prue.ba zimbraAutoProvLdapURL "ldap://freeipa.domain.tld:389"
  11. zmprov md prue.ba zimbraAutoProvMode LAZY
  12. zmprov md prue.ba zimbraAutoProvNotificationBody "Your account has been auto provisioned. Your email address is ${ACCOUNT_ADDRESS}."
  13. zmprov md prue.ba zimbraAutoProvNotificationFromAddress prov-admin@prue.ba
  14. zmprov md prue.ba zimbraAutoProvNotificationSubject "New account auto provisioned"

Como es lógico, hay que adaptar los campos “cn=accounts,dc=domain,dc=tld”, (uid=%u)” y “ldap://freeipa.domain.tld:389” siministrados acá como ejemplo para adaptarlo a las variantes del LDAP externo que se esté usando.

Con eso se ha configurado la auto-provisión externa. Ahora se puede abrir el buzón de cualquier usuario válido registrado en el Arbol LDAP externo.

Configuración de Fencing (opcional)

EL “fencing” es usado para aislar un nodo que el cluster determina que no está en condiciones de poder ser integrado y es posible, opcionalmente, configurar un método llamado STONITH para este fin.

Sólo realice esta configuración si considera que es necesario desahacerse de la presencia del sistema operativo de un nodo, en caso que no cumpla con el quorum requerido:

En este ejemplo, el Sistema Operativo donde corren las máquinas virtuales es el GNU/Linux de Proxmox, Se instalan en ese equipo los agentes del fencing:

  1. apt install fence-agents

CentOS no incluye este agente, por lo cual es necesario descargar sus fuentes y compilarlas (en cada uno de los nodos del cluster):

  1. cd
  2. git clone https://github.com/ClusterLabs/fence-agents.git
  3. cd fence-agents/
  4. ./autogen.sh
  5. ./configure --with-agents=pve
  6. make && make install
  7. fence_pve --version

Para probar el funcionamiento del agente, desde los nodos del cluster se ejecuta el siguiente comando:

  1. /usr/sbin/fence_pve --ip=<proxmox_ip> --username=root@pam --password=<proxmox_passwd> --plug=<vm_id> --action=status

En este ejemplo, hay que cambiar por la dirección IP del Hypervisor KVM, “root@pam” es necesario dejarlo sin modificaciones, en se coloca la contraseña de root de Hypervisor y en el número de identificación de la máquina virtual, por ejemplo:

  1. /usr/sbin/fence_pve --ip=192.168.0.10 --username=root@pam --password="EstaEsMiClave" --plug=101 --action=status

Se obtendrá un mensaje “STATUS: OK” si todo funciona correctamente.

Cuando un nodo falla (se cuelga, pierde conexión, etc) pacemaker procederá a aislarlo (fencing). En el siguiente ejemplo están las reglas para activar STONITH en ese caso. En cualquier nodo activo se ejecuta:

  1. pcs stonith create fence_mboxs01 fence_pve ipaddr=<proxmox_ip> inet4_only="true" vmtype="qemu" \
  2. login="root@pam" passwd=<proxmox_passwd> delay="15" port=<vm_id> pcmk_host_check=static-list \
  3. pcmk_host_list="mbox01.domain.tld" node_name="pve"
  4. pcs stonith create fence_mbox02 fence_pve ipaddr=<proxmox_ip> inet4_only="true" vmtype="qemu" \
  5. login="root@pam" passwd=<proxmox_passwd> delay="15" port=<vm_id> pcmk_host_check=static-list \
  6. pcmk_host_list="mbox02.domain.tld" node_name="pve"
  7. pcs stonith create fence_mbox03 fence_pve ipaddr=<proxmox_ip> inet4_only="true" vmtype="qemu" \
  8. login="root@pam" passwd=<proxmox_passwd> delay="15" port=<vm_id> pcmk_host_check=static-list \
  9. pcmk_host_list="mbox03.domain.tld" node_name="pve"

Para que un nodo permanezca en línea, debe ver al menos un nodo mas. Con el siguiente comando se activa esa directiva:

  1. pcs stonith update fence_mbox01 action="off" --force
  2. pcs stonith update fence_mbox02 action="off" --force
  3. pcs stonith update fence_mbox03 action="off" --force
  4. pcs property set stonith-enabled=true
  5. pcs property set no-quorum-policy=suicide

Finalmente, se reinicia los servicios de cluster para que la configuración tome efecto:

  1. systemctl enable pcsd
  2. systemctl enable corosync
  3. systemctl enable pacemaker

Ahora se puede probar el fencing, suspendiendo la configuración de red en una máquina virtual (lo cual desconectará el nodo y perderá el quorum):

  1. systemctl stop networking

Se puede verificar así:

  1. watch pcs status

(CONTROL-C para salir)

Instalación de Servidores Zimbra-Proxy (opcional)

Primero, hay que configurar el nombre de la máquina para que sea un FQDN:

  1. hostnamectl set-hostname "proxy01.domain.tld" && exec bash

Luego, verificar que exista el proxy en /etc/hosts al igual que los demás nodos:

  1. 192.168.0.1 mbox01.domain.tld mbox01
  2. 192.168.0.2 mbox02.domain.tld mbox02
  3. 192.168.0.3 mbox03.domain.tld mbox03
  4. 192.168.0.4 mbox.domain.tld mbox
  5. 192.168.0.5 proxy01.domin.tld proxy01
  6. 192.168.0.6 proxy02.domin.tld proxy02
  7. 192.168.0.7 proxy03.domin.tld proxy03
  8. 192.168.0.8 mail.domian.tld mail
  9. 192.168.0.10 proxmox.domain.tld proxmox

Seguidamente hay que añadir el proxy en el DNS. Si se está usando FreeIPA:

  1. ipa-client-install --enable-dns-updates

Desactivar la política SELinux:

  1. setenforce 0

Para que SELinux se desactive permanentemente, cambiar la siguiente línea en /etc/selinux/config:

  1. SELINUX=permissive

Luego, correr el instalador de Zimbra con la opción “-s

  1. mkdir /root/zimbra && cd /root/zimbra
  2. wget https://files.zimbra.com/downloads/8.8.15_GA/zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  3. tar zxpf zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  4. cd zcs-8.8.15_GA_3869.RHEL7_64.20190918004220
  5. ./install.sh -s
  6. Do you agree with the terms of the software license agreement? [N] Y
  7. Use Zimbra's package repository [Y]
  8. Install zimbra-ldap [Y] N
  9. Install zimbra-logger [Y] N
  10. Install zimbra-mta [Y] N
  11. Install zimbra-dnscache [N] N
  12. Install zimbra-snmp [Y] N
  13. Install zimbra-store [Y] N
  14. Install zimbra-apache [Y] N
  15. Install zimbra-spell [Y] N
  16. Install zimbra-memcached [Y] N
  17. Install zimbra-proxy [Y] Y <----------------- "y" sólo responder Y en esta opción
  18. The system will be modified. Continue? [N] Y

En muchas recetas en internet, “zimbra-memcached” es instalada junto a “zimbra-proxy”, pero la verdad es que sólo una instancia de “zimbra-memcached” es necesaria y en el servicio principal ya se ha instalado uno.

  1. mkdir -p /opt/zimbra/java/jre/lib/security/
  2. ln -s /opt/zimbra/common/etc/java/cacerts /opt/zimbra/java/jre/lib/security/cacerts
  3. chown -R zimbra.zimbra /opt/zimbra/java
  4. /opt/zimbra/libexec/zmsetup.pl

Es necesario conocer la clave de acceso para Nginx. Esta clave fue generada automáticamente en el proceso de instalación de los nodos, así que será necesario conocerla. Desde el nodo activo del cluster se ejecuta:

  1. su - zimbra
  2. zmlocalconfig -s ldap_nginx_password

Ahora, en el instalador del proxy, se accede a la opción 1 “Common Configuration“ y allí se va a la opción 2 “Ldap master host“. Allí se coloca el nombre de host asignado a la IP Virtual: “mail.domain.tld

Posteriormente, se accede a la opción 4 “Ldap Admin password“ y se proporciona la clave obtenida el el proceso anterior. Hecho esto el instalador se conectará y tomará del servicio LDAP principal todas las configuraciones necesarias:

  1. Setting defaults from ldap...done.

Para regresar al menú principal se presiona ENTER ante el mensaje “Select, or ‘r’ for previous menu [r]” y allí se selecciona la opción 2 “zimbra-proxy” en la cual se provee la contraseña de nginx a través de la opción 12 “Bind password for nginx ldap user”. Se coloca la misma obtenida en el paso anterior.

Una vez que se ha realizado este paso, se regresa al menú principal y se procede a realizar la instalación:

  1. *** CONFIGURATION COMPLETE - press 'a' to apply
  2. Select from menu, or press 'a' to apply config (? - help) a <------ press "a" and ENTER here
  3. Save configuration data to a file? [Yes]
  4. Save config in file: [/opt/zimbra/config.15941]
  5. Saving config in /opt/zimbra/config.15941...done.
  6. The system will be modified - continue? [No] Yes <---- "Yes" and ENTER
  7. ...
  8. Notify Zimbra of your installation? [Yes]
  9. ...
  10. Configuration complete - press return to exit

Para finalizar, es necesario actualizar las llaves SSH entre los servidores. En el nodo activo y en el nuevo proxy instalado se ejecutan los siguientes comandos:

  1. su - zimbra
  2. /opt/zimbra/bin/zmsshkeygen
  3. /opt/zimbra/bin/zmupdateauthkeys
  4. exit;

Configuración de RSYSLOG

Para obtener las estadísticas y estado de funcionamiento de los servicios, es necesario realizar la configuración de RSYSLOG.

En cada uno de los proxies se ejecuta:

  1. /opt/zimbra/libexec/zmsyslogsetup

Reparación de chat-zimlet:

El componente de Zimbra encargado del servicio de mensajería instantánea (chat) presenta fallas al terminar de ser instalado y no funciona correctamente. El error consiste en una librería Java mal empaquetada. El problema se resuelve sustituyando el paquete defectuoso de la siguiente manera:

  1. mv /opt/zimbra/lib/ext/openchat/zal.jar /tmp
  2. cp -rp /opt/zimbra/lib/ext/zimbradrive/zal.jar /opt/zimbra/lib/ext/openchat/zal.jar
  3. su - zimbra
  4. zmmailboxdctl restart

Documentación consultada para realizar el presente trabajo: