Table des matières

Keepalived

Keepalived est un programme disponible sous Debian qui permet de faire du failover au niveau IP. En fait il va faire que deux serveurs se partagent une même IP et que si l'un tombe, l'autre prend le relais ( propre ! ) et le tout de manière automatique ;).

Attention, il ne s'agit pas d'une solution de load-balancing… Le but est juste de fournir un serveur de remplacement si jamais le master “fail”.

Pour info, le protocole utilisé derrière est VRRP, Virtual Router Redundancy Protocol, qui permet de faire la même chose avec des routeurs.

Nos deux instances de keepalived vont donc s'échanger des infos pour savoir qui répond. Chacune va checker la “santé” de son processus et passe la main à la suivante si ça va pas. Les instances sont ordonnées par priorité.

Note : Il pourrait s'agir d'une solution pour redonder certains services de MiNET… Un peu moche mais ça marche…

A bon entendeur…

Description de l'instalation

Nous allons déployer un serveur web tout ce qu'il y a de plus basique. Mais en redondé : un serveur web en master et un autre de fail over. OK ça pête pas des masses d'intérêt mais c'est par exemple le même principe pour redonder un load balanceur.

Quoi de mieux qu'un petit dessin?

Préparation des clients

J'ai réalisé ceci sous OpenVZ. Mes deux openvz possèdent une interface publique et une interface d'administration. On utilise les vmbr.

Voici la conf réseau du master : /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 192.168.103.166
        netmask 255.255.255.0

iface eth3 inet manual

Voici la conf réseau du slave : /etc/networking/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 192.168.103.167
        netmask 255.255.255.0

iface eth3 inet manual

Bon …

Maintenant sur chaque serveur web, on autorise le routing sur les deux serveurs webs : /etc/sysctl.conf

net.ipv4.ip_forward = 1

Puis on reboot un petit coup.

OpenVZ seulement

( Vous pouvez passer à la suite si vous avez pas une Openvz )

Éteignez vos deux conteneurs.

Pour chacun d'entre eux :

  vzctl set $VEID --capability "NET_ADMIN:on" --save 

Bon maintenant on installe ipvsadm sur proxmox :

  apt-get install ipvsadm

Enfin on ajoute tout un tas de module noyaux. Ils ne sont sûrement pas tous nécessaires…

modprobe ip_vs
modprobe ip_vs_dh
modprobe ip_vs_ftp
modprobe ip_vs_lblc
modprobe ip_vs_lblcr
modprobe ip_vs_lc
modprobe ip_vs_nq
modprobe ip_vs_rr
modprobe ip_vs_sed
modprobe ip_vs_sh
modprobe ip_vs_wlc
modprobe ip_vs_wrr

Et pour finir la préparation de proxmox, on installe de quoi faire du bridge, si ce n'est pas déjà fait.

  apt-get install bridge-utils

On redémarre maintenant les deux conteneurs, et on peut passer à la suite.

Installation de Keepalived

Installons maintenant keepalived :

  apt-get install keepalived

Ensuite, on allume bien ses interfaces réseau, sur les deux OpenVZ :

   ifconfig eth3 up

Sinon ça risque pas de marcher !

Voici le fichier de conf du master : /etc/keepalived/keepalived.conf

vrrp_script chk_apache {      
        script "killall -0 apache2"    
        interval 2                    
        weight 2
        fall 2
        rise 2                      
}
 
vrrp_instance VI_1 {
        interface eth3
        state MASTER
        virtual_router_id 51
        priority 101                 
        virtual_ipaddress {
            157.159.40.175/26 dev eth3                
        }
        track_script {
            chk_apache
        }
}

Pour expliquer, on crée une instance VRRP master, sur eth3. Il s'agit d'un routeur virtuel d'id 51. Il a une priorité de 101. On donne ensuite l'adresse ip ainsi que le netmask.

Enfin on mentionne comment vérifier que apache tourne bien. On vérifie toutes les deux secondes que le proceesus est bien présent. Et on attend deux check pour crier au loup.

Voili voilou, rien de plus ;-)

Concernant le client : /etc/keepalived/keepalived.conf

vrrp_script chk_apache {
        script "killall -0 apache2"    
        interval 2                  
        weight 2
        fall 2
        rise 2                      
}
 
vrrp_instance VI_1 {
        interface eth3
        state BACKUP
        virtual_router_id 51
        priority 100           
        virtual_ipaddress {
            157.159.40.175/26 dev eth3             
        }
        track_script {
            chk_apache
        }
}

Bah c'est exactement la même chose, mais un chouïa moins prioritaire…

Voilà, il ne reste plus qu'à observer le résultat !

On démarre donc keepalived sur les deux machines :

  /etc/init.d/keepalived start

Chez moi ça marche, je peux killer apache où je veux, je continue à avoir le service, tant que je coupe pas les deux en même temps.

Là ou nous en sommes, nous n'avons pas encore de gateway. Elle peut être ajouté via :

  route add default gateway 157.159.40.129

Personnelement, j'ailégerement modifié mes scripts d'init afin de :

  1. allumer l'interface eth3
  2. lancer keepalived
  3. ajoute une route qui me sert de gateway.

Une solution plus propre serais d'utiliser des routes virtuelles comme documentées pour keepalived, mais je n'ai pas réussit à les faire marcher sur les OpenVZ. Je suppose que ça doit marcher dans une KVM ( pas testé … ).

Voilà voilà ;-)

Un peu plus de sécurité

Si quelqu'un de mal intentionné a accès à votre subnet, il peut tenter de récupérer l'adresse IP virtuelle et faire ensuite ce qu'il veut avec… Vraiment pas cool.

Pour celà, il a juste besoin de connaitre :

  1. L'ip en question
  2. Le virtual_router_ip ( en général 51 dans les confs …)

Il ne lui reste ensuite plus qu'à installer keepalived sur une de ses machines pour ensuite s'inscrire au groupe avec une priorité maximale et récupérer l'ip virtuelle…

Un moyen de se défendre contre ceci serait de mettre un mot de passe :

    authentication {
        auth_type PASS
        auth_pass 1111
    }

Je ne peux pas garantir que ça ne passe pas en clair…

Conclusion, utiliser keepalived dans des VLANs ou il n'y a que des gens de confiance…

Load balancing de niveau 4

Keepalived permet aussi de faire du load balancing de niveau 4.

Je me suis basé la dessus : http://www.alienxarea.fr/2010/08/04/sysadmin-loadbalancing-avec-lvs-et-keepalived/

Voici mon fichier de configuration :

vrrp_instance VI_1 {
        state MASTER
        interface eth3
        virtual_router_id 10
        priority 200
        virtual_ipaddress {
                157.159.40.136/24
        }
        virtual_server 157.159.40.136 81 {
                delay_loop 15
                lb_algo rr
                lb_kind DR
                persistence_timeout 50
                protocol TCP

        real_server 192.168.103.166 80 {
                TCP_CHECK {
                        connect_timeout 3
                }
        }
        real_server 192.168.103.167 80 {
                TCP_CHECK {
                        connect_timeout 3
                }
        }
}

En fait dans mon cas ça marche à moitié ( lié aux openVZ? ):

benwa@benwa-serveur:/$ nmap -F 157.159.40.136
 
Starting Nmap 5.00 ( http://nmap.org ) at 2014-01-25 18:33 CET
Interesting ports on 157.159.40.136:
Not shown: 97 closed ports
PORT    STATE    SERVICE
22/tcp  open     ssh
81/tcp  filtered hosts2-ns
111/tcp open     rpcbind

En revanche, le check fonctionne, cf mes logs de keepalived :

Jan 25 17:29:22 benwaHAproxy Keepalived_healthcheckers: Activating healtchecker for service [192.168.103.166]:80
Jan 25 17:29:22 benwaHAproxy Keepalived_healthcheckers: Activating healtchecker for service [192.168.103.167]:80
Jan 25 17:29:23 benwaHAproxy Keepalived_vrrp: VRRP_Instance(VI_1) Transition to MASTER STATE
Jan 25 17:29:24 benwaHAproxy Keepalived_vrrp: VRRP_Instance(VI_1) Entering MASTER STATE
Jan 25 17:30:08 benwaHAproxy Keepalived_healthcheckers: TCP connection to [192.168.103.166]:80 failed !!!
Jan 25 17:30:08 benwaHAproxy Keepalived_healthcheckers: Removing service [192.168.103.166]:80 from VS [157.159.40.136]:81

En bref, la fonctionnalité existe, mais c'est je pense pas pour rien que les gens utilisent des trucs comme HAproxy

Liens utiles

Voici les liens sur lesquels je me suis appuyé :

Articles connexes :

Benoit Tellier 2014/01/24 03:25