Varnish 3.0 en Ubuntu 12.04

Varnish es un cache HTTP para contenido dinámico para sitios de alto tráfico.  En contraste con otros caches, Varnish nació como cache enfocado en HTTP y no soporta otros protocolos.

El procedimiento describe la instalación y configuración de Varnish en Ubuntu delante de una graja de 4 servidores web.   También como alternativa se explica como configurar el Apache para que viva con el Varnish.

Procedimiento para instalar Varnish 3.0 en Ubuntu 12.04

El primer paso a realizar es dar de alta el repositorio de Varnish.

< wget -qO- http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -
< echo "deb http://repo.varnish-cache.org/ubuntu/ $(lsb_release -s -c) varnish-3.0" | sudo tee /etc/apt/sources.list.d/varnish.list

Se debe actualizar la información de los paquetes que están disponibles en el repositorio.

< sudo apt-get update

Y a continuación se procede a instalar el paquete.

< sudo apt-get install varnish

Configuración / Optimización Varnish 3.0 en Ubuntu 12.04

El primer paso a realizar es parar la ejecución del servicio.

< sudo /etc/init.d/varnish stop

A continuación se procede a modificar el puerto en el que escucha el servicio.

En este caso se modifica para que las peticiones que entren en el puerto 80 sean recibidas por el Varnish, estoy va a implicar cambiar el puerto en el que escucha el Apache.

< sudo vi /etc/default/varnish

Del archivo de configuración se deben modificar la configuración del parámetro DAEMON_OPTS.  Los valores en azul son los modificados.

DAEMON_OPTS="    -a :80 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,4096m"
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
#

#es un ACL sobre el que se va a consultar para habilitar la posibilidad de hacer purges. Solo se permite
#desde las IPs de esta lista.

acl purge {
"localhost";
"127.0.0.1";
}

#Define el backend y configuramos un probe para poder usar el grace-mode
backend svr1 {
   .host = "192.168.21.143";
   .port = "80";
   .probe = {
      .url = "http://svr.sismonda.com.ar/check.html";
      .interval = 5s;
      .timeout = 1s;
      .window = 5;
      .threshold = 3;
   }
}
backend svr2 {
   .host = "192.168.21.144";
   .port = "80";
   .probe = {
      .url = "http://svr.sismonda.com.ar/check.html";
      .interval = 5s;
      .timeout = 1s;
      .window = 5;
      .threshold = 3;
   }
}
backend svr3 {
   .host = "192.168.21.145";
   .port = "80";
   .probe = {
      .url = "http://svr.sismonda.com.ar/check.html";
      .interval = 5s;
      .timeout = 1s;
      .window = 5;
      .threshold = 3;
   }
}
backend svr4 {
.host = "192.168.21.146";
.port = "80";
.probe = {
   .url = "http://svr.sismonda.com.ar/check.html";
   .interval = 5s;
   .timeout = 1s;
   .window = 5;
   .threshold = 3;
   }
}

#Definimos un director. de haber multiples backend varnish balancea mediante round-robin.

director mmsx round-robin{
   {
      .backend = svr1;
   }
   {
      .backend = svr2;
   }
   {
      .backend = svr3;
   }
   {
      .backend = svr4;
   }
}

#Esta funcion es lo primero que corre cuando se hace un request. Aca es donde se decide si ir directo al backend o
#buscar el pedido en el cache y demas.

sub vcl_recv {
   #Purge -> chequeo ACL y dejo pasar o rechazo.
   if (req.request == "PURGE") {
      if (!client.ip ~ purge) {
         error 405 "Not allowed.";
      }
      ban("req.url == " + req.url + " && req.http.host == " + req.http.host);
      error 200 "Purged.";
   }

   #configuro el backend
   set req.backend = svr;
   remove req.http.X-Forwarded-For;
   set req.http.X-Forwarded-For = client.ip;

   #Esto actua como un para avalanchas. la definicion de lo que si   gnifica es:

   #Allow expired objects to be served for XX time. If the backend takes a long time to generate an
   # object there is a risk of a thread pile up. In order to prevent this you can enable grace. This
   # allows varnish to serve an expired version of the object while a fresh object is being generated
   # by the backend.
   # This keep objects 1 hour in cache past their expiry time. it tells varnish that if the backend
   # is healthy, only accept objects that are 60 seconds old, but if the backend is sick, accept objects
   # that are up to an hour old.

   if (req.backend.healthy) {
      set req.grace = 60s;
   }
   else {
      set req.grace = 1h;
   }

   ## Comienza la logica de decidir que se busca en cache y que no
   #pipe directo al backend con todo lo que no sea GET/HEAD

   if (req.request != "GET" && req.request != "HEAD") {
      return(pipe);
   }

   #Voy a cache con cualquier cosa que sea estatica las extensiones que dice ahi

   if (req.url ~ "\.(png|gif|jpg|css|js|ico|swf)$") {
      unset req.http.cookie;
      return (lookup);
   }

   if ((req.url ~ "^/wp-admin" ) || !(req.http.Cookie ~ "(wp-postpass|wordpress_logged_in|comment_author_)")){
      return(pipe);
   }

   if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~ "(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php)") {
      return (pass);
   }
   #cualquier otra cosa, no se cachea. ej: usuarios logueados y cualquier cosa que no cumpla las
   #condiciones de arriba. Si el comportamiento default es cachear, hay que cambiar algunos de
   #los ifs y returns de arriba
   return (pass);
}

#Esta funcion corre cuando ya se tiene el objeto del backend. aca se pueden procesar los ESI
sub vcl_fetch {
   #grace de 1hora
   set beresp.grace = 1h;
   #aca empieza la segunda parte de cache. donde decido que cosas se cachea y por cuanto tiempo
   #esto debe ser consistente con lo que esta en el vcl_fetch que decide que se va a buscar a cache
   if (req.url ~ "\.(png|gif|jpg|css|js|ico|swf)$") {
   unset beresp.http.set-cookie;
   set beresp.ttl = 7200s;
}
else{
   #Lo que no se cachea
   if ((req.url ~ "^/user" ) || (req.url ~ "^/wp-admin" ) || (req.http.Cookie ~ "(wp-postpass|wordpress_logged_in|comment_author_)"))       {
         return (hit_for_pass);
   }
   if (req.http.cookie ~ "logd"){
      return (hit_for_pass);
   }
   #llegado aca deberia ser un html de un usuario no logueado. cualquier otra cosa deberia haber caido arriba

   #cache=90segundos
   unset beresp.http.set-cookie;
   set beresp.ttl = 600s;
}
return(deliver);
}
#para hacer llegar a los wp la ip del cliente.
sub vcl_miss {
   #Forward de la ip del cliente.
   if (req.http.x-forwarded-for) {
      set bereq.http.X-Forwarded-For = bereq.http.X-Forwarded-For + ", " + client.ip;
   } 
   else {
      set bereq.http.X-Forwarded-For = client.ip;
   }
}
#Esto es mas que nada para debug y ver en la respuesta que se cachea y que no.
sub vcl_deliver {
   if (obj.hits > 0) {
      set resp.http.X-Cache = "HIT";
   } else {
      set resp.http.X-Cache = "MISS";
   }
}

 Configuración del Apache para funcionar EN EL MISMO SERVIDOR QUE ELVarnish:

El primer paso es modificar el puerto en el cual escucha por defecto el Apache, se cambia del 80 (puerto tcp estandar en el cual funciona el servicio, al 81).  Las líneas modificadas en azul.

# README.Debian.gz
NameVirtualHost *:81 Listen 81 <IfModule mod_ssl.c>
 # If you add NameVirtualHost *:443 here, you will also have to change
 # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
 # to <VirtualHost *:443>
 # Server Name Indication for SSL named virtual hosts is currently not
 # supported by MSIE on Windows XP.
 Listen 443
</IfModule>
<IfModule mod_gnutls.c>
 Listen 443
</IfModule>

A continuación se deben modificar todos los hosts virtuales que estén definidos para funcionar en el puerto 80.

Para saber que archivos hay que modificar se debe hacer:

< cd /etc/apache2/sites-enabled/
< grep 80 *
> www.sismonda.com:<VirtualHost *:80>
> nagios.sismonda.com:<VirtualHost *:80>

En el caso de ejemplo el servidor tiene dos hosts virtuales, se deben modificar los dos archivos de configuración reemplazando la configuración del puerto 80 por puerto 81.

Se debe cambiar la configuración del varnish para que busque el contenido en el puerto 81 y no en el 80 como está en el ejemplo.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.