Nginx en tant que LoadBalancer

Nginx LoadBalancer

Voila depuis peu le blog est servi par le serveur http sorti de russie . Nginx peut être utilisé en tant que LoadBalancer

L’architecture est plutôt des plus classique :

  • LB Nginx
  • 2 serveurs web Apache

Si vous utilisez xen pour vos tests . Création des VMs

xen-create-image --hostname=http1.madinina.lan --size=10Gb --ip=10.10.10.30 --memory=128Mb --dist=squeeze --arch=i386
xen-create-image --hostname=http2.madinina.lan --size=10Gb --ip=10.10.10.31 --memory=128Mb --dist=squeeze --arch=i386

Modification de votre sources.list

deb http://nginx.org/packages/debian/ squeeze nginx
deb-src http://nginx.org/packages/debian/ squeeze nginx

Installation

apt-get update
apt-get install nginx

Sur les 2 serveurs Apache une installation de apache2 et finit .

Configuration de Nginx (nginx.conf)

    include /etc/nginx/sites-enable/*;

Configuration des upstreams

cd /etc/nginx/sites-available

upstream www.madinina.lan  {
  server 10.10.10.30:80 ;
  server 10.10.10.31:80 ; 
}

server {
  location / {
        proxy_pass  http://www.madinina.lan;
  }
}

La configuration est relativement simple on définit

  • Les upstream => IP ou noms de vos serveurs apache : Port de destination
  • Proxy_pass => URL qui sera appelée

N’oubliez pas le lien symbolique dans sites-enable . Puis un restart de Nginx . Pas trop fatigué ?

Votre loadbalancing est en place rien d’extraordinaire jusque la . Mais regardons un peu les logs .

10.10.10.22 - - [09/Aug/2012:03:21:58 +0200] "GET / HTTP/1.0" 200 455 "-" "Lynx/2.8.8dev.5 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/2.8.6"
10.10.10.22 - - [09/Aug/2012:03:25:04 +0200] "GET / HTTP/1.0" 200 459 "-" "Wget/1.12 (linux-gnu)"
10.10.10.22 - - [09/Aug/2012:03:26:25 +0200] "GET / HTTP/1.0" 200 455 "-" "Lynx/2.8.8dev.5 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/2.8.6"
10.10.10.22 - - [09/Aug/2012:03:27:17 +0200] "GET / HTTP/1.0" 200 455 "-" "Lynx/2.8.8dev.5 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/2.8.6"
10.10.10.22 - - [09/Aug/2012:03:29:34 +0200] "GET / HTTP/1.0" 200 455 "-" "Lynx/2.8.8dev.5 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/2.8.6"

On se retrouve avec l’ip de notre reverse (nginx) . Vous comprendrez bien que si vous voulez faire des stats ou un peu de debug ca va être compliqué .
Alors pour corriger cela il faut dans un premier temps rediriger certaines entetes vers les serveurs en backend (apache) .

La nouvelle configuration

server {
  location / {
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_pass  http://www.madinina.lan;
  }
}
  • Proxy_set_header => Permets de modifier les entêtes voir la doc

Il faut maintenant ajouter le modules RPAF (Reverse Proxy Add Forward)  sur les apache . C’est toujours aussi compliqué .

apt-get install libapache2-mod-rpaf

Il faut modifier le fichier de conf rpaf.

/etc/apache2/mods-enabled# cat rpaf.conf 
<IfModule mod_rpaf.c>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 10.10.10.22 xx.xx.xx.xx yy.yy.yy.yy
</IfModule>

Il faut mettre l’ip du reverse. Dans les logs vous aurez maintenant l’ip du client et non plus celle du reverse. Avec un peu de persistance cela ne serait-il pas mieux ? L’algorithme de LoadBalancing qui le permets est ip_hash

upstream www.madinina.lan  {
  ip_hash;
  server 10.10.10.30:80 ;
  server 10.10.10.31:80 ; 
}

Par contre je ne sais pas si il est possible de paramétrer un timeout (comme sur Keepalived) .

D’autres options sont disponible comme la mise en place d’un poids par exemple . Je vous laisse étudier les autres possibilités.

CONCLUSION

Nginx permets de mettre en place un LoadBalancer HTTP/HTTPS très rapidement et de façon très simple.

Vous pouvez également utiliser la suite Keepalived pour ce type d’architecture . L’avantage que présente NGINX par rapport à Keepalived est la mise en cache (même si nous n’avons pas vu ce point).

Bien-sur si vous voulez mettre en place un LB sur des ports autre que HTTP/HTTPS vous ne pourrez pas utiliser NGINX mais Keepalived est la bonne alternative .

Dans le cas ou vous voulez mettre NGINX pour du LoadBalancing SMTP lisez ceci 🙂

J’espère pouvoir faire enfin l’article sur keepalived depuis le temps que je le dis .

Related posts

12 Thoughts to “Nginx en tant que LoadBalancer”

  1. Merci pour cet article.
    Sur quoi se base nginx pour load balancer ??
    Charge du serveur ? 1 requette sur 2 ?

    Quid de la bdd ? ton tuto est bon pour des pages statiques mais qu’en est t’il des site avec bdd ? il faut faire du drbd du ocfs2 ou mysql en cluster ?

    1. Avec l’algorithme ip_hash le client est redirigé vers le même serveur . Si aucun algorithme n’est définit il fait du round-robin. Comme dans le premier exemple .

      Pour la base de donnée cela ne pose pas de problème car ses sont les back-end qui se connectent à la BDD. Dans le cas ou il est nécessaire d’avoir des accès concourrants , il faut effectivement un FS distribué de type ocfs2 ou gfs .

      En ce qui concerne drdb je n’ai pas trop joué avec .

      Tout dépends après de l’architecture que vous souhaitez mettre en place .

  2. Salut.

    En tant que mainteneur des paquets nginx dans debian, j’ai une petite question à te poser.

    Pourquoi n’as-tu pas utilisé les paquets officiels debian ?

    Est-ce qu’ils ont des défauts selon toi ?

    N’hésite pas à donner ton avis, on est preneurs de toutes les opinions et idées pour améliorer les paquets :).

    ++

    1. Salut ,

      Je n’ai pas testé le paquet nginx de debian . Car nginx propose un dépot avec une version plus récente .

      Il faudrait que je test le paquet debian (mais pas avec que du statique comme dans mon article ) 🙂 .

      A noté que dans la version 1.2.2 :
      *) Feature: it is now possible to specify a weight for servers while
      using the « ip_hash » directive.

  3. Wolfy

    pour mettre un timeout sur tes serveurs, tu peu utiliser cet exemple :

    upstream http://www.madinina.lan {
    ip_hash;
    server 10.10.10.30:80 max_fails=3 fail_timeout=30s;
    server 10.10.10.31:80 ;
    }

    cf : http://wiki.nginx.org/HttpUpstreamModule#server

  4. Salut,

    Ngnix pour c’est pas trop prévu pour load-balancer quand même 🙂
    C’est le boulot d’HAProxy, et il le fait beaucoup mieux…
    Quand à l’affinité par IP source, c’est assez moyen, car il arrive qu’on change d’IP de temps en temps (téléphonie mobile) ou alors beaucoup d’utilisateurs pevent se cacher derrière la même IP (téléphonie mobile, FW ou proxy d’entreprise, etc…)

    Y’a pas un module dans nginx qui permet de faire de la persistance par Cookie?

    Bel article, ceci dit 🙂

    a+

    1. Je te rejoins sur le fait que Nginx ce n’est pas ca fonction première de faire du LB . 🙂
      Chez nous , nous utilisons plutôt des F5 même si j’ai une préférence pour la suite Keepalived .
      Pour la partie cookie j’ai trouvé ceci
      http://code.google.com/p/nginx-sticky-module/

      1. T’es riche pour utiliser du F5, en fonction de ce que tu as besoin en LB, tu peux trouver beaucoup moins cher et tout aussi, voire plus, robuste:
        http://ninjanix.com/alternative-to-f5/

        a+

  5. seb

    Merci pour cet article!
    J’essaierai de mettre cela en place!

    Je lis les commentaires concernant le fait qu’Nginx « c’est pas trop prévu pour ça ». Certains argumentent avec des solutions matériels et propriétaires.

    Mais qu’en est-il du LB avec du logiciel libre? En dehors de nginx.

  6. Salut ,

    Dans les solutions libre comme le disait Baptiste tu as HAproxy ou encore keepalived.
    http://www.keepalived.org/index.html
    http://haproxy.1wt.eu/

  7. j’avais lu l’article de david mytton sur le lb et nginx, mais ici c’est plus compréhensible en français :)), j’ai gagné quelques heures de travail donc merci, car on a viré notre solution de load balancing qui marchait fort pour nginx, et à première vue je ne trouve pas ça vraiment très très pratique …

Leave a Comment