¿Cómo realizar tareas de conmutación por error cron?

8

Utilizando dos servidores Debian, necesito configurar un entorno de conmutación por error sólido para trabajos cron que solo se puede invocar en un servidor a la vez.

Mover un archivo en /etc/cron.d debería ser el truco, pero ¿existe una solución HA simple para operar tal acción? Y si es posible no con latidos;)

Falken
fuente
Para el registro, finalmente utilicé los latidos del corazón para hacer el trabajo. Sin embargo, existe una solución más fácil, si sus máquinas están en la misma subred y pueden hacer multidifusión, recomendaría usar ucarp. Mucho más simple que el latido del corazón -> ucarp.org
Falken
1
rcron? Gnubatch? ¿Marioneta?
symcbean
Yo segundo rcron. Actualmente lo estoy usando y tengo casi la misma configuración (2 servidores ubuntu detrás de un equilibrador de carga).
Ali

Respuestas:

5

Creo que el ritmo cardíaco / marcapasos sería la mejor solución, ya que pueden cuidar muchas condiciones de carrera, esgrima, etc. para garantizar que el trabajo solo se ejecute en un host a la vez. Es posible diseñar algo usted mismo, pero es probable que no tenga en cuenta todos los escenarios que hacen esos paquetes, y eventualmente terminará reemplazando la mayor parte de la rueda, si no toda.

Si realmente no te importan esas cosas y quieres una configuración más simple. Sugiero escalonar los trabajos cron en los servidores por unos minutos. Luego, cuando el trabajo comienza en el primario, de alguna manera puede dejar un marcador en cualquier recurso compartido en el que operen los trabajos (no especificas esto, así que estoy siendo intencionalmente vago). Si se trata de una base de datos, pueden actualizar un campo en una tabla o si está en un sistema de archivos compartido bloquear un archivo.

Cuando el trabajo se ejecuta en el segundo servidor, puede verificar la presencia del marcador y abortar si está allí.

Kamil Kisiel
fuente
1

Utilizamos dos enfoques según los requisitos. Ambos implican tener los crons presentes y en ejecución desde todas las máquinas, pero con un poco de comprobación de la cordura involucrados:

  1. Si las máquinas están en una relación primaria y secundaria (puede haber más de una secundaria), los scripts se modifican para verificar si la máquina en la que se están ejecutando es un estado primario. Si no, simplemente salen en silencio. No tengo una configuración de HB a mano en este momento, pero creo que puede consultar HB para obtener esta información.

  2. Si todas las máquinas son primarias elegibles (como en un clúster), se utiliza algún bloqueo. Mediante una base de datos compartida o un archivo PID. Solo una máquina obtiene el estado de bloqueo y las que no salen silenciosamente.

Dan Carley
fuente
1

Para abreviar la historia, debe convertir sus scripts cron en algún tipo de aplicaciones compatibles con clústeres. Al ser la implementación tan liviana o tan pesada como sea necesario, aún necesitan una cosa: poder reanudar / reiniciar correctamente la acción (o recuperar su estado) después de la conmutación por error del nodo primario. El caso trivial es que son programas sin estado (o programas "lo suficientemente sin estado"), que simplemente se pueden reiniciar en cualquier momento y funcionarán bien. Probablemente este no sea tu caso. Tenga en cuenta que para los programas sin estado no necesita conmutación por error porque simplemente podría ejecutarlos en paralelo en todos los nodos.

En un caso normalmente complicado, sus scripts deben estar en el almacenamiento compartido del clúster, deben almacenar su estado en archivos allí, deben cambiar el estado almacenado en el disco solo atómicamente y deben poder continuar su acción desde cualquier estado transitorio que detectarán en el inicio.

kubanczyk
fuente
1

En realidad, no hay una solución que sea satisfactoria en esta área. Los hemos probado todos. soluciones de secuencias de comandos, cron con latido / marcapasos y más. La única solución, hasta hace poco, era una solución de red. naturalmente, esto no es lo que queremos ver, ya que una solución de red es un poco más que exagerada para el escenario.

Es por eso que comencé el proyecto CronBalancer. funciona exactamente como un servidor cron normal, excepto que está distribuido, con equilibrio de carga y HA (cuando finaliza). Actualmente, los primeros 2 puntos están terminados (beta) y funciona con un archivo crontab estándar.

El marco HA está en su lugar. todo lo que queda es la señalización necesaria para determinar las acciones de recuperación y recuperación.

http://sourceforge.net/projects/cronbalancer/

arrojar

Charles Williams
fuente
1

Había estado usando el controlador de eventos Nagios como una solución simple.

En el servidor NRPE:

command[check_crond]=/usr/lib64/nagios/plugins/check_procs -c 1: -C crond
command[autostart_crond]=sudo /etc/init.d/crond start
command[stop_crond]=sudo /etc/init.d/crond stop

No olvides agregar al nagiosusuario al grupo de sudoers:

nagios  ALL=(ALL)   NOPASSWD:/usr/lib64/nagios/plugins/, /etc/init.d/crond

y deshabilitar requiretty:

Defaults:nagios !requiretty

En el servidor de Nagios:

services.cfg

define service{
    use                     generic-service
    host_name               cpc_3.145
    service_description     crond
    check_command           check_nrpe!check_crond
    event_handler           autostart_crond!cpc_2.93
    process_perf_data       0
    contact_groups          admin,admin-sms
}

command.cfg

define command{
    command_name    autostart_crond
    command_line    $USER1$/eventhandlers/autostart_crond.sh $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$ $ARG1$
}

autostart_crond.sh

#!/bin/bash

case "$1" in
    OK)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c stop_crond
        ;;
    WARNING)
        ;;
    UNKNOWN)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
    CRITICAL)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
esac

exit 0

pero he cambiado para usar Pacemaker y Corosync ya que es la mejor solución para asegurar que el recurso solo se ejecute en un nodo a la vez.

Estos son los pasos que he hecho:

Verifique que el script de inicio crond sea ​​compatible con LSB . En mi CentOS, tengo que cambiar el estado de salida de 1 a 0 (si iniciar una carrera o detener una parada) para que coincida con los requisitos:

start() {
    echo -n $"Starting $prog: " 
    if [ -e /var/lock/subsys/crond ]; then
        if [ -e /var/run/crond.pid ] && [ -e /proc/`cat /var/run/crond.pid` ]; then
            echo -n $"cannot start crond: crond is already running.";
            failure $"cannot start crond: crond already running.";
            echo
            #return 1
            return 0
        fi
    fi

stop() {
    echo -n $"Stopping $prog: "
    if [ ! -e /var/lock/subsys/crond ]; then
        echo -n $"cannot stop crond: crond is not running."
        failure $"cannot stop crond: crond is not running."
        echo
        #return 1;
        return 0;
    fi

entonces se puede agregar al Marcapasos usando:

# crm configure primitive Crond lsb:crond \
        op monitor interval="60s"

crm configure show

node SVR022-293.localdomain
node SVR233NTC-3145.localdomain
primitive Crond lsb:crond \
        op monitor interval="60s"
property $id="cib-bootstrap-options" \
        dc-version="1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        stonith-enabled="false" \
        no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
        resource-stickiness="100"

estado de crm

============
Last updated: Fri Jun  7 13:44:03 2013
Stack: openais
Current DC: SVR233NTC-3145.localdomain - partition with quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain SVR233NTC-3145.localdomain ]

 Crond  (lsb:crond):    Started SVR233NTC-3145.localdomain

Prueba de conmutación por error deteniendo Pacemaker y Corosync en 3.145:

[root@3145 corosync]# service pacemaker stop
Signaling Pacemaker Cluster Manager to terminate:          [  OK  ]
Waiting for cluster services to unload:......              [  OK  ]

[root@3145 corosync]# service corosync stop
Signaling Corosync Cluster Engine (corosync) to terminate: [  OK  ]
Waiting for corosync services to unload:.                  [  OK  ]

luego verifique el estado del clúster en el 2.93:

============
Last updated: Fri Jun  7 13:47:31 2013
Stack: openais
Current DC: SVR022-293.localdomain - partition WITHOUT quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain ]
OFFLINE: [ SVR233NTC-3145.localdomain ]

Crond   (lsb:crond):    Started SVR022-293.localdomain
quanta
fuente
0

Hacerlo ejecutar / no ejecutar en una máquina en particular es trivial. Haga que un script coloque un trabajo cron en /etc/cron.d, como sugiere, o haga que el script permanezca en /etc/cron.d, pero haga que el script haga la verificación de conmutación por error y decida si ejecutarlo.

La parte común (que falta) en ambos es cómo el script verifica si el script en la otra máquina se está ejecutando.

Sin más información sobre lo que está tratando de hacer, esto es difícil de responder.

Schof
fuente
0

Prefiero Rcron para este problema en particular. Tiene un archivo de estado, que simplemente dice "activo" o "pasivo", y si está activo, su cron se ejecutará en una determinada máquina. Si el archivo de estado está configurado como pasivo, no se ejecutará. Simple como eso.

Ahora, puede usar RedHat Cluster Suite o cualquier otro middleware de agrupación para administrar archivos de estado en su clúster, o puede configurarlo manualmente en un determinado nodo y listo.

Jakov Sosic
fuente