Init script di varnish per ubuntu
Semplice init script di varrnish per ubuntu, che gestisce lo status tramite il comando stats di varnishadm ed il reload per non perdere la cache
Premessa
Il presente script è stato sviluppato per ubuntu e nello specifico per la versione 10.04 e 10.10 utilizzando varnish alla versione 2.1.x.
Installazione di varnish 2.1
Si consiglia l'installazione dai sorgenti in modo tale da poter scegliere liberamente le funzionalità che si desiderano ed anche per non avere problemi di aggiornamento con la propria distribuzione.
Per poter compilare ed installare su ubuntu si possono seguire questi semplici passi:
$ wget http://www.varnish-software.com/sites/default/files/varnish-2.1.4.tar.gz $ tar -xzvf varnish-2.1.4.tar.gz $ cd varnish-2.1.4 $ ./autogen.sh $ ./configure --prefix=/usr/local/varnish $ make $ sudo make install
Dopo queste operazioni avremo varnish installato nella directory /usr/local/varnish. Qui potete trovare una guida più esaustiva sull'installazione di varnish dai sorgenti.
Configurazioni iniziali
A questo punto iniziamo a configurare la nostra linux box.
Creazione dell'utente varnish
Creiamo l'utente varnish assegnandogli la shell /bin/false
$ sudo useradd -s /bin/false varnish
Impostazione dei limiti per l'utente varnish
Ora bisogna incrementare i limiti di default per l'utente varnish appena creato, questi possono essere scelti arbitrariamente; ad esempio si potrà innalzare il numero di file apribili da 1024 a 8192 ed il memlock da 64 2048 inserendo le seguenti linee nel file /etc/security/limits.conf
varnish soft memlock 1024 varnish hard memlock 2048 varnish soft nofile 4096 varnish hard nofile 8192
Creazione del secret file
Per potersi collegare via terminale e poter amministrare varnish in real time senza doverlo riavviare è consigliabile creare il secret file per l'autenticazione, immettendoci il testo che vogliamo. Qui di seguito lo creeremo nella directory /etc/varnish/secret
$ sudo mkdir /etc/varnish $ sudo touch /etc/varnish/secret $ sudo chown -R varnish:varnish /etc/varnish $ sudo chmod -R go-rwx /etc/varnish
Adesso bisognerà aprire il file /etc/varnish/secret con il proprio editor di testi preferito come ad esempio vim ed immettere del testo all'interno.
File di configurazione
Ora iniziamo a configurare il file /etc/default/varnish con i parametri che più si confanno ai nostri bisogni. Di seguito il contenuto di default:
#
# Configuration file for varnish service
#
# user (optional)
VARNISH_USER=varnish
# home
VARNISH_HOME=/usr/local/varnish
# daemon executable
VARNISHD=${VARNISH_HOME}/sbin/varnishd
# vcl script
VARNISH_VCL=${VARNISH_HOME}/etc/varnish/default.vcl
# pidfile
VARNISH_PID=${VARNISH_HOME}/var/varnish/varnish.pid
# listen addr (optional)
#LISTEN_ADDR=192.168.100.100
# listen port
LISTEN_PORT=8080
# secret file
SECRET=/etc/varnish/secret
# backend storage option (-s) (optional) --> default = malloc,32M
VARNISH_STORAGE="malloc,100M"
# telnet addr (optional)
TELNET_ADDR=127.0.0.1
# telnet port (optional)
TELNET_PORT=3000
Di seguito una piccola spiegazione dei parametri principali presenti:
- VARNISH_USER: utenza creata precedentemente ed utilizzata per startare il servizio;
- VARNISH_VCL: file VCL utilizzato da varnish; per il dettaglio fate riferimento a questo indirizzo;
- VARNISH_PID: pid file utilizzato dal gestore dei servizi di ubuntu;
- LISTEN_ADDR: ip che verrà utilizzato per rispondere alle richieste. Il parametro è opzionale e se non settato verrà utilizzato l'indirizzo 0.0.0.0 ovvero varnish si porrà in ascolto su tutti gli indirizzi di rete presenti al momento dell'avvio;
- LISTEN_PORT: porta tcp sulla quale varnish risponderà alle richieste dei client;
- VARNISH_STORAGE: parametro di storage di varnish (-s), se non impostato verrà passato al demone "-s malloc,32M";
- TELNET_ADDR e TELNET_PORT: indirizzo ip e porta sulla quale verrà abilitata l'interfaccia di gestione, risultano essere opzionali ma mutualmente esclusivi, ovvero se si vuole abilitare l'interfaccia di gestione dovranno essere impostate tutte e due le variabili.
Script di init
Una volta che si sono settati tutti i parametri non ci resta che creare il file /etc/init.d/varnish dandogli il permesso di esecuzione con il comando:
$ sudo chmod a+x /etc/init.d/varnish
Di seguito il contenuto dello script:
#! /bin/sh
### BEGIN INIT INFO
# Provides: varnish
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start varnish HTTP accelerator
# Description: This script provides a server-side cache
# to be run in front of a web server.
### END INIT INFO
# Author: Amedeo Salvati <amedeo.salvati@gmail.com>
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="varnish HTTP accelerator"
NAME=varnish
DAEMON=
DAEMON_ARGS=""
#PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# varnishd exe
DAEMON=${VARNISHD}
# pidfile construct
PIDFILE=${VARNISH_PID}
# pidfile directory
VARNISH_PIDDIR=`dirname $VARNISH_PID `
if [ ! -d "$VARNISH_PIDDIR" ]; then
echo "Error: Directory $VARNISH_PIDDIR doesn't exist! exit"
exit 0
fi
# vcl file
VCL_FILE=$VARNISH_VCL
if [ ! -r "$VCL_FILE" ]; then
echo "Error: VCL file $VCL_FILE doesn't exist! exit"
exit
fi
# port addr
PORT=$LISTEN_PORT
if [ ! "$PORT" != "" ]; then
echo "Error: No LISTEN_PORT defined in '/etc/default/$NAME'. Exit"
exit
fi
# secret file
if [ ! "$SECRET" != "" ]; then
echo "Error: No secret file supplied. Exit"
exit
else
if [ ! -r "$SECRET" ]; then
echo "Error: Secret file $SECRET doesn't exist! exit"
exit
# TODO: verify len(secret) > 0
fi
fi
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
cli_telnet() {
# check parameters number
if [ ! "$#" -eq 1 ]; then
echo "Error when calling cli_telnet function. Exit"
exit 1
fi
local varname=$1
local var0=
# TODO: Add more checks and options
if [ "$TELNET_ADDR" != "" ]; then
if [ "$TELNET_PORT" ]; then
var0="-T $TELNET_ADDR:$TELNET_PORT"
fi
fi
eval $varname='$(echo $var0)'
}
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
log_daemon_msg "Starting $NAME"
# build args
DAEMON_ARGS="-f $VARNISH_VCL -P $PIDFILE -S $SECRET"
# /* TODO: Check ipv4 valid address */
if [ "$LISTEN_ADDR" != "" ]; then
DAEMON_ARGS="$DAEMON_ARGS -a $LISTEN_ADDR"
else
DAEMON_ARGS="$DAEMON_ARGS -a 0.0.0.0"
fi
DAEMON_ARGS="$DAEMON_ARGS:$PORT"
if [ "$VARNISH_STORAGE" != "" ]; then
DAEMON_ARGS="$DAEMON_ARGS -s $VARNISH_STORAGE"
else
DAEMON_ARGS="$DAEMON_ARGS -s malloc,32M"
fi
# telnet option
cli_telnet CLI
DAEMON_ARGS="$DAEMON_ARGS $CLI"
# user
if [ "$VARNISH_USER" != "" ]; then
DAEMON_ARGS="$DAEMON_ARGS -u $VARNISH_USER"
fi
#echo $DAEMON_ARGS
start-stop-daemon --start --quiet --exec $DAEMON -- $DAEMON_ARGS > /dev/null 2>&1
RETVAL=$?
#echo $RETVAL
if [ $RETVAL -eq 0 ]; then
log_end_msg 0
elif [ $RETVAL -eq 1 ]; then
echo -n " "
echo -n "Service $NAME is already running"
log_end_msg 1
else
log_end_msg 2
fi
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
# /* TODO: fix hardcoded name -> varnishd */
log_daemon_msg "Stopping $NAME"
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name varnishd
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
log_end_msg 0
elif [ $RETVAL -eq 1 ]; then
echo -n " "
echo -n "Service $NAME is NOT running"
log_end_msg 1
else
log_end_msg 2
return 2
fi
rm -f $PIDFILE
return $RETVAL
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
cli_telnet CLI
if [ "$CLI" != "" ]; then
VARNISHADM=${VARNISH_HOME}/bin/varnishadm
if [ -x $VARNISHADM ]; then
if [ "$SECRET" != "" ]; then
DAEMON_ARGS="$CLI -S $SECRET"
else
DAEMON_ARGS="$CLI"
fi
NOW=`date +%Y%m%d_%H%M%S_%N`
$VARNISHADM $DAEMON_ARGS vcl.load reload_${NOW} $VCL_FILE > /dev/null 2>&1
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
return $RETVAL
fi
$VARNISHADM $DAEMON_ARGS vcl.use reload_${NOW} > /dev/null 2>&1
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
return $RETVAL
fi
fi
fi
return 0
}
do_status() {
status_of_proc "$DAEMON" "$NAME"
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
cli_telnet CLI
if [ "$CLI" != "" ]; then
VARNISHADM=${VARNISH_HOME}/bin/varnishadm
if [ -x $VARNISHADM ]; then
echo ""
if [ "$SECRET" != "" ]; then
DAEMON_ARGS="$CLI -S $SECRET"
else
DAEMON_ARGS="$CLI"
fi
$VARNISHADM $DAEMON_ARGS stats
fi
fi
else
exit $RETVAL
fi
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
do_status
;;
reload)
# TODO: implement reload
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
log_daemon_msg "Reloading $DESC"
do_reload
log_end_msg $?
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|reload|restart|force-reload}" >&2
exit 3
;;
esac
:
Impostazione dell'avvio automatico
Dopo aver testato il corretto funzionamento del servizio eseguendone lo start, stop, restart, reload e status non resta che impostarne l'avvio automatico. Niente di più semplice:
$ sudo update-rc.d varnish defaults
Sorgenti
E' possibile reperire i sorgenti illustrati in questo howto, comprensivi dei futuri aggiornamenti e patch su github.
