Me ha tocado montar un par de servidores en alta disponibilidad en dos data centers distintos. La idea es la de usar uno como servidor principal y sólo en el caso de que este falle se ponga a funcionar el otro.
La primera idea que tuvimos fue la de usar los DNS del dominio para hacer esta HA. Suponiendo que el dominio fuese biremaz.es, la idea era:
- Declarar ns1.biremaz.es apuntando al servidor principal y ns2.biremaz.es.
- Poner como NS primario al dominio ns1.biremaz.es y ns2.biremaz.es
- En cada servidor DNS, el dominio estaría configuradas con las ips del propio servidor.
Con esto se pretendía que siempre respondiese el DNS en ns1.biremaz.es con las ips de ese servidor, y si cae, que respondiese ns2.biremaz.es con las ips nuevas.
Esta aproximación fue un fracaso, porque aun estando declarado ns1.biremaz.es como primario, respondía también ns2.biremaz.es.
Tras investigar un poco, descubrí que las peticiones DNS las responde indistintamente cualquiera de los servidores NS que tengas declarado en el dominio, que no hay ninguna prioridad que permita forzar el uso de un servidor NS concreto.
Al fallar esto, se ha tenido que ver otra forma de hacerlo porque no se quiere que respondan los dos servidores al mismo tiempo*. Haciendo pruebas, al final lo que se ha hecho es mantener la idea de tener dos servidores DNS con distintas IPs, uno como primario y otro como secundario, pero manteniendo el servicio DNS del secundario parado. Cuando suceda algo, lo que hay que hacer es parar el servicio DNS del primario y arrancar el secundario, que teniendo un TTL de 60s hará que se refresquen las IPs del DNS rápidamente y en caso de fallo responda el servidor secundario.
Habiendo resuelto este punto, que es el más importante, quedaba ver cómo poder replicar los datos de la web y de la bbdd. Para los datos es algo sencillo, un cron con un rsync permite hacerlo, y como los datos web en sí no se modifican a cada momento, no hay mucho problema de desfase de datos.
El otro problema nos vino con la bbdd. Hice la prueba de poner el servidor mysql en master-slave, lo que permitía que cada vez que se hiciese un cambio en el servidor principal se replicase al de prueba, pero en el caso de que cayese el principal y se empezase a usar el secundario, habría un desfase de datos, por lo que se decidió usar el mysql en modo master-master, que ambos servidores se replicasen.
Esto nos trajo otro problema, ya que durante las pruebas que hicimos ambos servidores estaban respondiendo a la web y se han creado entradas distintas con los mimos PKs, así que eso falla más que una escopeta de feria**. Como la web está en funcionamiento, no tenemos la posibilidad de hacer muchas pruebas, por lo que lo que voy a hacer es borrar las bbdd de las webs, forzar en la configuración del mysql que tengan distintos PKs las bbdd, y restaurar un dump con la esperanza de que se regenere todo bien y ya no de problemas el master-master.
Si esto funciona bien, lo único que quedaría por hacer sería encontrar la forma de que se haga automáticamente el cambio de servidores DNS, que por ahora creo que lo haré con el programa Monit que permite un chequeo TCP a puertos de servidores externos. En caso de que no funcione el master-master, la solución es ponerlo en master-slave pero implica más trabajo manual y pierde la gracia.
En otros posts voy a desgranar un poco más la configuración de cada parte, más a modo de apuntes que otra cosa.
* Si se pudiesen usar ambos servidores a la vez no habría tanto problema en esto, y hubiésemos optado por dejarlo así o por usar un DNS RoundRobin, aunque los problemas del mysql hubiesen sido los mismos.
** El servicio de replicación de mysql se para si encuentra fallos de este tipo para evitar inconsistencias, pero se puede cambiar el comportamiento mediante la configuración del mysql.