K3rnelpanic

non serviam
Miembro del Equipo
MOD
Se incorporó
1 Octubre 2007
Mensajes
6.065
Bueno, lo prometido es deuda dicen :zippy, y aprovechando que estoy esperando datos de otra área :zippyte

Bueno, el tema del Clusterizado de servicios es muy útil en ambientes en donde se requiere alta disponibilidad, o balanceo de carga para estos. En esta guía se tratará algo básico como mantener un servidor activo y otro pasivo para mantener un servicio básico arriba. [strike] como una base de datos[/strike]

Partamos.

Requisitos
- Centos 7 (pueden obtener desde Aqui ).
- Máquinas Virtuales conectadas con 2 tarjetas cada una.
- Paciencia :zippy

Tutoriales de instalación hay varios, así que nos saltaremos esa parte.

La idea de tener 2 tarjetas de red es para mantener 1 de ellas en conexión directa con el segundo nodo del clúster (es lo mínimo que se recomienda para que mantengan comunicación los nodos de un clúster - de hecho se recomienda un bonding para hacerlo más tolerante a fallos, pero acá lo haremos simple :zippyu)

La otra tarjeta de red irá conectada al switch que intercomunica la red con el resto de las cosas :zippy.

Objetivos:
- Tener un servicio Apache operando en las 2 máquinas
- Una IP virtualizada, que el servicio de clúster se encargue mantener activa en uno de los nodos, para que en caso de falla de este, redirija el servicio transparentemente al segundo nodo.
- Un lindo laboratorio para hacer pruebas y descubrir las bondades de pcs.

Asumamos entonces lo siguiente:
Server1
Código:
hostname lab1.local
ip interna 10.0.0.10 255.255.255.0
ip externa 192.168.0.101 255.255.255.0
Server2
Código:
hostname lab2.local
ip interna 10.0.0.20 255.255.255.0
ip externa 192.168.0.102 255.255.255.0

Asumamos que ya configuraron las interfaces de red y hacen ping a las 2 IPs :zippy
Una buena practica es siempre dejar un repositorio local utilizando el DVD de instalación como fuente (en caso de que los servidores no vayan a estar conectados a Internet.
Imaginemos que tienen montado su DVD en /mnt/repodata, con lo siguiente se copian las 2 carpetas necesarias para generar el repositorio local (Packages y repodata)
Código:
#mkdir /repolocal
#cp -Rv /mnt/repodata /repolocal/ && cp -Rv /mnt/Packages /repolocal/
#cat <<END>/etc/yum.repos.d/local.repo
[CentOS_local]
name=CentOS 7.2 Local
baseurl=file:///repolocal/
gpgcheck=0
enabled=1
END

Para no tener problemas adicionales, y dado que es a modo de laboratorio, pondremos a SELINUX en modo permisivo.
Código:
mv /etc/selinux/config /etc/selinux/config.bkp
cat <<END>/etc/selinux/config
SELINUX=permissive
SELINUXTYPE=targeted
END

En CentOS 7 tenemos a firewalld (que es bien amigable en su configuración, pero en este minuto no es necesario), así que procederemos a deshabilitarlo para dejar nuestro servidor de patas abiertas. Si confían en su firewall/solución de seguridad, go ahead.
Código:
systemctl stop firewalld
systemctl disable firewalld

Algo importante es que ambos servers deben conocer su propia IP y la IP de su contraparte, por lo que agregaremos eso al archivo hosts de cada máquina. Validen que esto haya quedado bien hecho haciendo ping al nombre de host de cada maquina.
Código:
echo "192.168.0.101 lab1.local lab1" >> /etc/hosts
echo "10.0.0.10 lab1-int.local lab1-int" >> /etc/hosts
echo "192.168.0.102 lab2.local lab2" >> /etc/hosts
echo "10.0.0.20 lab2-int.local lab2-int" >> /etc/hosts

PREPARACION DEL CLUSTER
Hasta aquí sólo hemos hecho configuraciones básicas y de conectividad para que nuestros 2 servidores independientes tengan conexión entre sí. Ahora procederemos a levantar servicios y configurar el servicio de cluster como tal.

En ambos nodos instalar agentes de cluster
Código:
yum install pacemaker pcs corosync resource-agents
Esto crea los servicios necesarios para el cluster y el usuario hacluster, que se encarga de generar las tareas de comunicacion entre nodos. A este usuario le tenemos que asignar un password.

En ambos nodos
Código:
echo demo | passwd --stdin hacluster
Changing password for user hacluster.
passwd: all authentication tokens updated successfully.
También debemos habilitar el servicio para que se inicie con el sistema y posteriormente iniciarlo. En en ambos nodos

Código:
[root@lab1 ~]# systemctl enable pcsd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/pcsd.service to /usr/lib/systemd/system/pcsd.service.
[root@lab1 ~]# systemctl start pcsd.service

Ahora tenemos el usuario hacluster ya tiene password, debemos indicarle a PCS la autenticación de los nodos
Ejecuta esto solo en nodo 1
Código:
[root@lab1 ~]# pcs cluster auth lab1-int lab2-int -u hacluster
Password: **** --- ingresas tu password super segura aqui
lab1-int: Authorized
lab2-int: Authorized
[root@lab1 ~]#

Una vez realizado esto, se inicializa el cluster
Código:
[root@lab1 ~]# pcs cluster setup --start --name DEMOCLUSTER lab1-int,lab1 lab2-int,lab2
Shutting down pacemaker/corosync services...
Redirecting to /bin/systemctl stop  pacemaker.service
Redirecting to /bin/systemctl stop  corosync.service
Killing any remaining services...
Removing all cluster configuration files...
lab1-int: Succeeded
lab2-int: Succeeded
Starting cluster on nodes: lab1-int, lab2-int...
lab2-int: Starting Cluster...
lab1-int: Starting Cluster...
Synchronizing pcsd certificates on nodes lab1-int, lab2-int...
lab1-int: Success
lab2-int: Success

Restaring pcsd on the nodes in order to reload the certificates...
lab1-int: Success
lab2-int: Success
[root@lab1 ~]#

Ahora se habilitan todos los nodos desde lab1
Código:
[root@lab1 ~]# pcs cluster enable --all
lab1-int: Cluster Enabled
lab2-int: Cluster Enabled
[root@lab1 ~]#

Con esto ya tenemos los nodos del cluster comunicandose entre sí y lo podemos averiguar utilizando
Código:
pcs cluster status
pcs status

Código:
[root@lab1 ~]# pcs cluster status
Cluster Status:
Last updated: Thu Aug  4 18:30:27 2016  Last change: Thu Aug  4 18:30:06 2016 by hacluster via crmd on lab1-int
Stack: corosync
Current DC: lab1-int (version 1.1.13-10.el7-44eb2dd) - partition with quorum
2 nodes and 0 resources configured
Online: [ lab1-int lab2-int ]

PCSD Status:
  lab1-int: Online
  lab2-int: Online
[root@lab1 ~]# pcs status
Cluster name: DEMOCLUSTER
WARNING: no stonith devices and stonith-enabled is not false
Last updated: Thu Aug  4 18:30:36 2016  Last change: Thu Aug  4 18:30:06 2016 by hacluster via crmd on lab1-int
Stack: corosync
Current DC: lab1-int (version 1.1.13-10.el7-44eb2dd) - partition with quorum
2 nodes and 0 resources configured

Online: [ lab1-int lab2-int ]

Full list of resources:


PCSD Status:
  lab1-int: Online
  lab2-int: Online

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled
[root@lab1 ~]#
Este WARNING gigante que aparece ahí tiene que ver con el Fencing. El Fencing es una característica de todo Cluster que tiene un storage en común, y es que en el supuesto caso de una pérdida de conectividad entre los nodos, ambos no figuren como activos, y por lo tanto, generando cambios independientes en el filesystem. Por lo tanto lo que se hace es fencing de un nodo, o inhabilitarlo de acceder al recurso compartido.

En un Clúster Linux esto se logra a través de STONITH (Shoot The Other Node In The Head - bien explícito :risas). Acá vemos que nos alerta que no tenemos dispositivos stonith ni el stonith-enabled=false activado. Como este laboratorio no va a contar (de momento) con un Filesystem compartido, vamos a deshabilitar el stonith.
Código:
pcs property set stonith-enabled=false

Ahora estamos en condiciones de agregar resources. Pero antes, una pequeña reseña:
Como hemos visto hasta ahora, el modo de manejar un clúster Linux ha cambiado bastante desde Red Hat 6. En RHEL/CentOS 7 PCS es la herramienta centralizada de configuración. Tiene muchos menús y opciones para habilitar, visualizar, deshabilitar, etc. Todas las aristas en la configuración de un Clúster.

Código:
[root@lab1 ~]# pcs help

Usage: pcs [-f file] [-h] [commands]...
Control and configure pacemaker and corosync.

Options:
  -h, --help  Display usage and exit
  -f file  Perform actions on file instead of active CIB
  --debug  Print all network traffic and external commands run
  --version  Print pcs version information

Commands:
  cluster  Configure cluster options and nodes
  resource  Manage cluster resources
  stonith  Configure fence devices
  constraint  Set resource constraints
  property  Set pacemaker properties
  acl  Set pacemaker access control lists
  status  View cluster status
  config  View and manage cluster configuration
  pcsd  Manage pcs daemon

Ahora vamos a habilitar un resource, para comenzar. Una IP Virtual.
Código:
pcs resource create VirtualIP ocf:heartbeat:IPaddr2 ip=192.168.0.50 cidr_netmask=24 op monitor interval=30s

Probamos haciendo ping
Código:
[vittokox@thinkpad ~]$ ping 192.168.0.50 -c 5
PING 192.168.0.50 (192.168.0.50) 56(84) bytes of data.
64 bytes from 192.168.0.50: icmp_seq=1 ttl=64 time=0.488 ms
64 bytes from 192.168.0.50: icmp_seq=2 ttl=64 time=0.386 ms
64 bytes from 192.168.0.50: icmp_seq=3 ttl=64 time=0.428 ms
64 bytes from 192.168.0.50: icmp_seq=4 ttl=64 time=0.366 ms
64 bytes from 192.168.0.50: icmp_seq=5 ttl=64 time=0.418 ms

--- 192.168.0.50 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.366/0.417/0.488/0.043 ms
Ejalé!

Ahora instalaremos el servicio de Apache, en ambos nodos pero SIN INICIAR EL SERVICIO. Esto es crítico, porque ahora los servicios se gestionan como resources.
Código:
yum install httpd -y
Copiamos un molde
Código:
cp /usr/share/doc/HTML/index.html /var/www/html/ -v


Código:
cat <<END>/etc/httpd/conf.d/status.conf
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
END

Y volvemos a crear un resource, esta vez para el Apache.
Código:
pcs resource create WWW ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://localhost/server-status" op monitor interval=1min

Ahora podemos ver el servicio Apache arriba, pero levantado en el otro nodo :naster, eso claramente no nos sirve si buscamos un esquema activo/pasivo
Código:
[root@lab1 conf.d]# pcs status
Cluster name: DEMOCLUSTER
Last updated: Thu Aug  4 19:20:38 2016  Last change: Thu Aug  4 19:20:33 2016 by root via cibadmin on lab1-int
Stack: corosync
Current DC: lab1-int (version 1.1.13-10.el7-44eb2dd) - partition with quorum
2 nodes and 2 resources configured

Online: [ lab1-int lab2-int ]

Full list of resources:

VirtualIP  (ocf::heartbeat:IPaddr2):  Started lab1-int
WWW  (ocf::heartbeat:apache): Started lab2-int

PCSD Status:
  lab1-int: Online
  lab2-int: Online

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

Esto se logra utilizando la opción constraint. Con ella le decimos al cluster que queremos que X servicio siempre se ejecute donde Y servicio esté corriendo.
Código:
[root@lab1 conf.d]# pcs constraint colocation add WWW with VirtualIP INFINITY
[root@lab1 conf.d]# pcs resource show
VirtualIP  (ocf::heartbeat:IPaddr2):  Started lab1-int
WWW  (ocf::heartbeat:apache):  [/b]Started lab1-int[/b]

Puede llegar el caso en donde tengamos que reiniciar el Cluster (posiblemente por requerimiento del hefe :risas), así que es necesario establecer QUE servicio inicia primero. No nos sirve levantar un Apache si aún no está arriba la IP Virtualizada.
Para esto, tambien se usa constraint pero con la opción order
Código:
[root@lab1 conf.d]# pcs constraint order VirtualIP then WWW
Adding VirtualIP WWW (kind: Mandatory) (Options: first-action=start then-action=start)
[root@lab1 conf.d]# pcs constraint
Location Constraints:
Ordering Constraints:
  start VirtualIP then start WWW (kind:Mandatory)
Colocation Constraints:
  WWW with VirtualIP (score:INFINITY)
[root@lab1 conf.d]#
Con esto ya está listo nuestro Cluster. Ahora pueden probar (si virtualizaron el entuerto) a desconectar de la red a uno de los nodos completamnete, mientras le hacen ping a la IP virtualizada, y acceden a la URL en la misma IP :zippyte
En un segundo capítulo, le agregaremos un GFS2 o una unidad replicada con DRBD para mantener los datos sincronizados. Aunque de momento, pueden mantener todo alineado con un cochino rsync que haga updates incrementales en ambos /var/www/html/ :lezippy

Lo más importante de este lab es que nos permite soltarle la mano a la configuración de un Cluster básico, y si se tiene tiempo, poder agregar resources y ver su forma de operar.

Quedo listo y dispuesto a recibir sus críticas, y por qué no, alguna sugerencia que gustoso aceptaré para implementar.
Yakko, no tires mucha caca :yao
 
Última modificación:

Soujiro

Fanático
Se incorporó
14 Enero 2008
Mensajes
1.433
Resucito el tema por que estube jugando con drbd y corosync. Resulta que por segunda vez me pasa que uno de los nodos "explota" súbitamente,

La primera vez fue el proceso crmd, el cual básicamente se cayo en el nodo master, provocando que el secundario se promoviera a master, pero en el intertanto el proceso crmd se relanzo en el primer nodo provocando que ambos servidores se pelearan por el rango master por 5 minutos aproximadamente. Finalmente el original master fue el que "gano" y quedo andando ok.

Ahora resulta que anoche paso algo similar, solo que esta vez no "exploto" crmd, sino que corosync decidio eso

en el nodo master
Código:
Dec  6 04:36:57 white corosync[38637]:  [MAIN  ] Corosync main process was not scheduled for 11491.4434 ms (threshold is 2400.0000 ms). Consider token timeout increase.
Dec  6 04:36:57 white corosync[38637]:  [TOTEM ] A processor failed, forming new configuration.
Dec  6 04:36:58 white corosync[38637]:  [TOTEM ] A new membership (192.168.7.2:72) was formed. Members joined: 2 left: 2
Dec  6 04:36:58 white crmd[10036]:  warning: match_down_event: No match for shutdown action on 2
Dec  6 04:36:58 white crmd[10036]:  notice: peer_update_callback: Stonith/shutdown of black not matched
Dec  6 04:36:58 white crmd[10036]:  notice: do_state_transition: State transition S_IDLE -> S_INTEGRATION [ input=I_NODE_JOIN cause=C_FSA_INTERNAL origin=peer_update_callback ]
Dec  6 04:36:58 white corosync[38637]:  [QUORUM] Members[2]: 2 1
Dec  6 04:36:58 white corosync[38637]:  [MAIN  ] Completed service synchronization, ready to provide service.
Dec  6 04:36:58 white cib[10032]:  warning: cib_server_process_diff: Not requesting full refresh in R/W mode
Dec  6 04:36:58 white crmd[10036]:  warning: crmd_ha_msg_filter: Another DC detected: black (op=noop)
en el secundario
Código:
Dec  6 04:35:14 black corosync[35420]:  [TOTEM ] A processor failed, forming new configuration.
Dec  6 04:35:18 black corosync[35420]:  [TOTEM ] A new membership (192.168.7.2:68) was formed. Members left: 1
Dec  6 04:35:18 black crmd[35466]:  notice: peer_update_callback: Our peer on the DC is dead
Dec  6 04:35:18 black crmd[35466]:  notice: do_state_transition: State transition S_NOT_DC -> S_ELECTION [ input=I_ELECTION cause=C_CRMD_STATUS_CALLBACK origin=peer_update_callback ]
Sin embargo el secundario decidio promoverse a master o_O por que nuevamente estuvieron peleando por el control como por 5 mins
Código:
Dec  6 04:35:19 black pengine[35465]:  notice: unpack_config: On loss of CCM Quorum: Ignore
Dec  6 04:35:19 black pengine[35465]:  notice: LogActions: Promote drbd_res_caleuche:0#011(Slave -> Master black)

Comprendo que este comportamiento (pelearse por el estado master) es producto de deshabilitar fencing, pero los recursos siguen arriba y el "bajarlos" para promover el otro nodo a master por que los procesos del cluster (crosync, crmd) se ponen idiotas genera un downtime no deseado. Alguien mas ha tenido experiencias similares y/o o como solucionar esto
 
Upvote 0

K3rnelpanic

non serviam
Miembro del Equipo
MOD
Se incorporó
1 Octubre 2007
Mensajes
6.065
Resucito el tema por que estube jugando con drbd y corosync. Resulta que por segunda vez me pasa que uno de los nodos "explota" súbitamente,

La primera vez fue el proceso crmd, el cual básicamente se cayo en el nodo master, provocando que el secundario se promoviera a master, pero en el intertanto el proceso crmd se relanzo en el primer nodo provocando que ambos servidores se pelearan por el rango master por 5 minutos aproximadamente. Finalmente el original master fue el que "gano" y quedo andando ok.

Ahora resulta que anoche paso algo similar, solo que esta vez no "exploto" crmd, sino que corosync decidio eso

en el nodo master
Código:
Dec  6 04:36:57 white corosync[38637]:  [MAIN  ] Corosync main process was not scheduled for 11491.4434 ms (threshold is 2400.0000 ms). Consider token timeout increase.
Dec  6 04:36:57 white corosync[38637]:  [TOTEM ] A processor failed, forming new configuration.
Dec  6 04:36:58 white corosync[38637]:  [TOTEM ] A new membership (192.168.7.2:72) was formed. Members joined: 2 left: 2
Dec  6 04:36:58 white crmd[10036]:  warning: match_down_event: No match for shutdown action on 2
Dec  6 04:36:58 white crmd[10036]:  notice: peer_update_callback: Stonith/shutdown of black not matched
Dec  6 04:36:58 white crmd[10036]:  notice: do_state_transition: State transition S_IDLE -> S_INTEGRATION [ input=I_NODE_JOIN cause=C_FSA_INTERNAL origin=peer_update_callback ]
Dec  6 04:36:58 white corosync[38637]:  [QUORUM] Members[2]: 2 1
Dec  6 04:36:58 white corosync[38637]:  [MAIN  ] Completed service synchronization, ready to provide service.
Dec  6 04:36:58 white cib[10032]:  warning: cib_server_process_diff: Not requesting full refresh in R/W mode
Dec  6 04:36:58 white crmd[10036]:  warning: crmd_ha_msg_filter: Another DC detected: black (op=noop)
en el secundario
Código:
Dec  6 04:35:14 black corosync[35420]:  [TOTEM ] A processor failed, forming new configuration.
Dec  6 04:35:18 black corosync[35420]:  [TOTEM ] A new membership (192.168.7.2:68) was formed. Members left: 1
Dec  6 04:35:18 black crmd[35466]:  notice: peer_update_callback: Our peer on the DC is dead
Dec  6 04:35:18 black crmd[35466]:  notice: do_state_transition: State transition S_NOT_DC -> S_ELECTION [ input=I_ELECTION cause=C_CRMD_STATUS_CALLBACK origin=peer_update_callback ]
Sin embargo el secundario decidio promoverse a master o_O por que nuevamente estuvieron peleando por el control como por 5 mins
Código:
Dec  6 04:35:19 black pengine[35465]:  notice: unpack_config: On loss of CCM Quorum: Ignore
Dec  6 04:35:19 black pengine[35465]:  notice: LogActions: Promote drbd_res_caleuche:0#011(Slave -> Master black)

Comprendo que este comportamiento (pelearse por el estado master) es producto de deshabilitar fencing, pero los recursos siguen arriba y el "bajarlos" para promover el otro nodo a master por que los procesos del cluster (crosync, crmd) se ponen idiotas genera un downtime no deseado. Alguien mas ha tenido experiencias similares y/o o como solucionar esto
Que distribución corres en ambos nodos? Quee raro. Como es tu topología?, cómo "conversan" los nodos? interfaz independiente?
 
Upvote 0

Soujiro

Fanático
Se incorporó
14 Enero 2008
Mensajes
1.433
Distro Ubuntu 14.04 lts (es lo que ocupan los malditos desarrolladores :(), los 2 nodos estan en master slave conectados directamente por cables cruzados usando 2 interfaces GB en bonding. Las maquinas tiene 4 interfaces gb y todo el stack cluster esta configurado para solo funcionar en la interfaz del bonding.
 
Upvote 0

K3rnelpanic

non serviam
Miembro del Equipo
MOD
Se incorporó
1 Octubre 2007
Mensajes
6.065
Distro Ubuntu 14.04 lts (es lo que ocupan los malditos desarrolladores :(), los 2 nodos estan en master slave conectados directamente por cables cruzados usando 2 interfaces GB en bonding. Las maquinas tiene 4 interfaces gb y todo el stack cluster esta configurado para solo funcionar en la interfaz del bonding.
ubuntu. :yao
Le seteaste la opción
pcs property set no-quorum-policy=ignore
?
Recordemos que en un clúster de 2 nodos no es necesario mantener un quórum, dado que sólo hay 2 nodos.
 
Upvote 0

Soujiro

Fanático
Se incorporó
14 Enero 2008
Mensajes
1.433
por supuesto de echo en los logs sale clarito
Dec 6 04:35:19 black pengine[35465]: notice: unpack_config: On loss of CCM Quorum: Ignore

Respecto a ubuntu, no hay mucho que hacer la verdad. He insistido con el cambio a centos desde el 2014 pero recién hay planes para el 2019 :(
 
Upvote 0

K3rnelpanic

non serviam
Miembro del Equipo
MOD
Se incorporó
1 Octubre 2007
Mensajes
6.065
por supuesto de echo en los logs sale clarito
Dec 6 04:35:19 black pengine[35465]: notice: unpack_config: On loss of CCM Quorum: Ignore

Respecto a ubuntu, no hay mucho que hacer la verdad. He insistido con el cambio a centos desde el 2014 pero recién hay planes para el 2019 :(
No hay caso. traté de replicar el problema botando la conexión entre los nodos de mi laboratorio, si bien no tengo fencing (por lo tanto ambos levantan los recursos por su lado :risas), al restablecer la conexión negocian un par de segundos y los recursos quedan en un solo nodo. Para moverlos al otro pongo en stand by el que los tiene actualmente
Código:
pcs cluster standby nombre_del_nodo

Quizá es bug de la implementación de *buntu.

Aquí aplica la lógica yakkoniana
UBUNTU :yakko
 
Última modificación:
Upvote 0
Subir