WikiMiNET

La documentation technique et administrative

Outils pour utilisateurs

Outils du site


wiki:divers:ha:varnish

Varnish

Varnish est un reverse proxy extrêmement performant et très utilisé. Il travail donc au niveau 7.

  1. Il permet entre autre de faire du load balancing,
  2. De séparer les contenus statiques d'un site des contenus dynamiques.
  3. D'appliquer une politique de caching.

Tout ceci est configurable par l'intermédiaire d'un pseudo langage de programmation, le VCL.

Autant dire que l'on ne peut pas être exhaustif sur le sujet. J'avais juste envie de présenter un autre reverse proxy que NGinx, car ce serait bête de ne connaître qu'une seule solution à un problème ;-).

Qui plus est, Varnish est utilisée notamment par Facebook, Twitter et Slashdot… Rien que ça …

De plus, dans l'esprit de la série d'articles que je suis en train d'écrire, je ne pouvais passer à coté d'un programme si puissant, même si avec je ne pourrais aller bien loin…

Installation

Voici l'architectures que nous allons réaliser ici :

Nous allons donc avoir ici 4 machines :

  1. web-d-1 qui servira des contenus dynamiques
  2. web-d-2 qui servira les mêmes contenus dynamiques
  3. web-s-1 qui servira une image qui sera intégrée dans la page servie par web-d-1 et web-d-2
  4. Et enfin varnish qui abritera le reverse proxy avec lequel on fera joujou !

Enfin, on fera pointer le nom de domaine benwa-varnish.minet.net en direction du revproxy.

Les serveurs webs dynamiques

La procédure qui suit sera appliquée pour chaque serveur web.

Installation d'apache2 et de php :

  apt-get install php5 libapache2-mod-php5

Virtual host d'apache :

<VirtualHost *:80>
        ServerName      benwa-varnish.minet.net
        DocumentRoot    /var/www/benwa-varnish.minet.net/
        ErrorLog /var/log/apache2/benwa-varnish.minet.net-error.log
        CustomLog /var/log/apache2/benwa-varnish.minet.net-access.log combined
        <Directory /var/www/benwa-varnish.minet.net.minet.net/>
                Order Deny,Allow
                Allow from all
        </Directory>
</VirtualHost>

Code de la page index.php :

<html>
    <body>
        <?php
             echo "Un peu de code bidon : <br/>";
             $i = 0;
             $n = 5;
             $cpt = 0;
             for($i = 0; $i < 5; $i++)
             {
                 $cpt += $i;
             }
             echo $i."<br/>"
        ?>
        <img src="http://benwa-varnish.minet.net/img/plop.jpg"/>
    </body>
</html>

Serveur statique

On installe nginx :

  apt-get install nginx

Voici son virtual host :

server {
        listen          80;
        server_name     benwa-varnish.minet.net;

        access_log      /var/log/nginx/benwa-varnish.access.log;
        error_log       /var/log/nginx/benwa-varnish.error.log;

        location / {
                root /var/www/benwa-varnish/;
        }
}

Et on fait attention à bien créer / placer les images.

Reverse proxy

L'installation de varnish est relativement simple :

  1. echo “deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0” » /etc/apt/sources.list
  2. apt-get update
  3. apt-get install varnish

Configuration

Bon après avoir passé beaucoup de temps à expliquer ce qu'on allait faire, et installé / mis en place les différents composants, et après s'être assuré de leur bon fonctionnement, il est enfin venu l'heure de jouer avec Varnish.

Configuration basique

Le but de cette section est ici de mettre en place une simple redirection avec cache en direction d'un des serveurs webs dynamiques.

La configuration de Varnish passe soit par la ligne de commande soit par un fichier dans le langage de programmation VCL. Nous commencerons par faire un reverse proxy vers un seul site, avec un seul serveur web, histoire d'illustrer rapidement le fonctionnement sous Debian, et ensuite on fera mumuse avec le fichier VCL pour utiliser les options cool de varnish.

Le fichier important ici est /etc/default/varnish

Nous allons garder l'utilisation du fichier VCL. Nous allons donc remplacer le bloc DEAMON_OPTS par celui ci :

DAEMON_OPTS=“-a :80 \

  1. T localhost:6082 \
  2. f /etc/varnish/default.vcl \
  3. S /etc/varnish/secret \
  4. s malloc,256m”

On remarque qu'on écoute sur le port 80 …

On a par ailleur un cache en RAM de 256 MB ;-) Évidement, on peut jouer avec la taille de ce cache.

Afin de faire pointer vers un de nos serveurs webs, il nous faut modifier /etc/varnish/default.vcl :

backend default {
    .host = "192.168.103.166";
    .port = "80";
}

Avec ça, j'ai accès à benwa-varnish.minet.net ;-)

Discussion générale de la conf'

La configuration est d'abord compilée à chaque démarrage de Varnish (Oui Mr !!!).

Sinon, sur l'organisation du fichier VCL 1) :

  • Il comporte une première partie dans laquelle on définit nos serveurs distants, et d'éventuels load-balancing.
  • Ensuite, il se décompose en un ensemble de directives, dans lesquelles on peut écrire des conditions et où on a accès à des instructions de traitement, de mise en cache, etc… Les deux principales directives sont :
    1. vcl_recv qui s'applique à la réception de requêtes
    2. vcl_fetch qui s'applique quand on reçoit la réponse d'un serveur.

Voilà qui devrait être suffisant pour attaquer la suite ;-)

Load balancing

Nous allons ici voir comment faire du load balancing entre nos deux nodes web dynamique.

Tout d'abord nous allons renseigner nos deux hôtes ( en dehors de tout bloc ) :

backend site1 {
  .host = "192.168.103.166";
  .port = "80";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
}
 
backend site2 {
  .host = "192.168.103.167";
  .port = "80";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
}

Vous noterez l'ajout du module probe qui permet de vérifier la “santé” des nœuds.

Il ne reste plus qu'à load-balancer tout ça. Pour cela, je vais créer un director que je vais appeler redounded. Je choisis ensuite la politique que je souhaite lui appliquer. Il y a trois politiques :

  1. le très connu roud robin
  2. le fameux source
  3. et le random, dont l'utilité est discutable.

Voici ce que ça donne :

director redounded round-robin {
        { .backend = site1; }
        { .backend = site2; }
}

Il ne reste plus qu'à utiliser notre back-end. Pour cela, je vais le mapper avec les requêtes des clients.

Voici donc à quoi ressemble mon début de bloc vlc_recv :

sub vcl_recv {
     set req.backend = redounded;
...

En modifiant index.php de manière à ce qu'il soit différent sur chaque client, et en respectant les temps de cache, je constate bien que le tout est correctement-load balancé. En éteignant une serveur apache à l'arrache, j'ai de nouveau accès au service.

Séparer les contenus dynamiques de ceux statiques

Bon alors pour commencer, on va ajouter un backend, celui qui correspond à notre noeud sous NGinx :

backend imgs {
  .host = "192.168.103.56";
  .port = "80";
}

Puis on fait en sorte de mapper les appels au dossier img qui contient les images vers le serveur statique. Pour celà nous allons annalyser l'URL appelées, grâce à req.url :

 sub vcl_recv {
     ######
     ## If the requested object is an image
     ## ( ending in .jpg )
     ## then we may ask the NGinx server
     ## set backend to imgs in this case
     ######
     if( req.url~ "^/img/" ) {
       set req.backend = imgs;
     } else {
       set req.backend = redounded;
     }
     ...
     ...
     ...

Et voilà, chez moi ça marche du tonnerre ;-)

Édition de la politique de caching

Bon histoire de finir, on peut regrouper dans certains dossiers les éléments dynamiques sur lesquels on peut faire du cache avec une “même politique”. Ça se fait très bien avec un if similaire à celui du dessus.

Pour lire le cache et ensuite si il n'y a pas de hits intéroger un serveur web, utilisez :

  return(lookup);

Pour consulter un serveur web sans tenir compte du cache :

  return(pass);

ACLs pour les clients

Exemple avec la classique ACL maisel :

acl maisel {
  "157.159.40.0"/24;
  "157.159.41.0"/24;
  "157.159.42.0"/24;
  "157.159.43.0"/24;
  "157.159.44.0"/24;
  "157.159.45.0"/24;
  "157.159.46.0"/24;
  "157.159.47.0"/24;
  ! "157.159.40.254";  // Non au routeur de la DISI
}

Dans une des sous routines, il suffit ensuite de :

if (client.ip ~ maisel) {
    ...

Mes conclusions

Les deux capacités qu'apporte à mon sens Varnish par rapport à NGinx c'est :

  1. Une meilleure gestion du cache, avec des possibilités de configuration littéralement monstrueuses.
  2. Une gestion au final assez sympa du load balancing.

En revanche, là ou à mon sens le bas blesse, c'est que :

  1. Il a une syntaxe carrément beaucoup plus verbeuse que ce brave NGinx.
  2. Il est ( là aussi à mon sens ) plus destiné à un gros site qu'à plein de petits sites comme nous avons à MiNET.

Liens utiles

1)
Je suis tout sauf un expert…
2)
Je ne me suis rendu compte qu'après qu'il y avait plusieures pages… Ça m'aurait évité de chercher comme un damné ce qui y était écrit dans tout l'internet :-(
wiki/divers/ha/varnish.txt · Dernière modification: 2020/06/27 18:16 (modification externe)