Administrar servicios en Ubuntu 14.04 LTS mediante scripts de inicio
Desde la versión 9.10 de Ubuntu, se implementó un nuevo método de inicio del sistema, llamado Upstart. Éste se ocupa de cargar todos los procesos y servicios necesarios durante el arranque del sistema operativo.
Una de las mayores ventajas de Upstart es que está basado en eventos, lo que le permite, por ejemplo, reaccionar de forma interactiva a procesos de conexión o desconexión de distintos tipos de dispositivos. Sin embargo mantiene la compatibilidad con el método anterior, de modo que ambos pueden convivir y aún hoy, existen servicios que siguen configurando su inicio con el antiguo SysVinit.
Para que aprendas los fundamentos de ambos métodos, hoy nos centraremos en cómo administrar servicios que sean compatibles con SysVinit y dedicaremos el artículo Administrar servicios en Ubuntu 14.04 LTS con Upstart para aprender a conseguirlo con Upstart.
Cómo funciona SysVinit
Cuando se instala un programa que lleva asociado algún servicio (como el servidor de impresión CUPS o el servidor web Apache), el proceso de instalación guarda en el directorio /etc/init.d el script necesario para controlarlo. Esto ocurre también con los servicios propios del sistema operativo.
En otras distribuciones la carpeta puede ser /etc/rc.d/init.d.
En resumidas cuentas, lo que esto significa es que en la carpeta /etc/init.d se encuentran todos los scripts que se utilizan para administrar los servicios que pueden ejecutarse en Ubuntu 14.04 LTS. En SysVinit estos scripts se ejecutarán de forma secuencial, lo que significa que cada servicio deberá esperar para iniciarse hasta que se hayan iniciado todos los anteriores
El número de archivos almacenados dependerá de las funciones para las que esté configurado el sistema y de los dispositivos hardware instalados.
Administrar servicios con SysVinit
Los scripts se programan de modo que establezcan lo que debe hacerse cuando reciban una orden determinada. Por lo tanto, su cuerpo principal puede entenderse como una sencilla orden case como el del ejemplo siguiente:
case "$1" in start) ;; stop) ;; restart) ;; reload) ;; status) ;; *) ;; esac
Como es lógico, detrás de cada opción se incluirán las acciones a realizar cuando se reciba dicho argumento. No obstante, debemos tener en cuenta que algunos scripts no siguen estrictamente el formato anterior y que, incluso, pueden admitir argumentos diferentes.
No obstante, este planteamiento nos indica que podríamos llegar a modificar los scripts de inicio para adecuar su comportamiento a nuestras necesidades. Lógicamente, sólo debes hacerlo cuando estés seguro de sus repercusiones.
En cualquier caso, vamos a repasar el funcionamiento de los argumentos más comunes, para que entiendas su dinámica:
start
Permite iniciar un servicio de forma manual. Por ejemplo, para iniciar el servicio vboxadd escribiremos la siguiente orden:
sudo /etc/init.d/vboxadd start
stop
Permite detener un servicio que se esté ejecutando en estos momentos. Por ejemplo, para detener el servicio anterior, escribiremos lo siguiente:
sudo /etc/init.d/vboxadd stop
restart
Equivale a realizar las dos operaciones anteriores. Primero detiene el servicio y después lo inicia. Para reiniciar el servicio anterior, escribimos esto:
sudo /etc/init.d/vboxadd restart
Como ya imaginabas, volvemos a obtener el mismo error que antes, porque, de nuevo, no ha podido detenerse.
status
Nos permite consultar el estado en el que se encuentra un servicio. Para comprobarlo, sólo tenemos que escribir lo siguiente:
sudo /etc/init.d/vboxadd status
Iniciar o parar servicios durante el arranque del sistema
La mayoría de las veces, conviene que los servicios se inicien de forma automática durante el arranque del sistema, sin esperar a que el administrador los ponga en funcionamiento y sin que ni siquiera sea necesario que haya iniciado una sesión local ninguno de los usuarios.
Esto ocurre, por ejemplo, cuando instalamos un servidor NFS. El servicio que atiende las conexiones de usuarios a través de la red local debe estar disponible, de forma automática, en cuanto el servidor haya terminado de arrancar.
La ejecución automática de servicios se organiza en Linux en base a los niveles de ejecución. Cada nivel de ejecución en particular iniciará o detendrá unos servicios en concreto.
El nivel de ejecución (runlevel) establece qué servicios se inician durante el proceso de carga del sistema operativo, y en qué orden. Por lo tanto, existen diferentes niveles de ejecución según el propósito al que se orienten.
Los scripts de inicio se configuran durante la instalación para que actúen del modo adecuado, pero nosotros podemos cambiar ese comportamiento predeterminado.
En la mayoría de las distribuciones se utilizan los siguientes niveles de ejecución:
En estos casos, cuando realizamos un inicio normal, con interfaz gráfica, estaremos usando el nivel de ejecución 5. Si necesitamos un inicio normal, pero sin interfaz gráfica, usaremos el nivel de ejecución 3.
Los niveles 1 y 2 se utilizan en contadas ocasiones, para tareas de mantenimiento o usos particulares del sistema, y el nivel 4 está en desuso. Podemos utilizarlo para crear un inicio del sistema personalizado.
Por último, los niveles 0 y 6 son especiales porque detienen todos los procesos y servicios del sistema. La diferencia es que, al final , el nivel 6 lanza un script que vuelve a iniciar el sistema.
Cuando usamos este tipo de distribuciones, para cambiar el nivel de ejecución, sólo hay que cambiar una línea en el archivo /etc/inittab, concretamente, la que muestra el siguiente contenido:
id:3:initdefault:
Por su parte, Ubuntu 14.04 LTS utiliza Upstart para iniciarse y no existe el archivo /etc/inittab. Además, también se ha simplificado el uso de los niveles de ejecución, habiendo quedado de esta forma:
Así pues, en Ubuntu 14.04 LTS no podemos cambiar el modo en el que arranca el sistema en el archivo /etc/inittab. En su lugar, el nivel de ejecución se guarda en la variable DEFAULT_RUNLEVEL, dentro del archivo /etc/init/rc-sysinit.conf.
Los servicios que se inician con cada nivel de ejecución se guardan en los directorios /etc/rc*.d (encontraremos directorios desde rc0.d a rc6.d y rcS.d).
Sin embargo, lo cierto es que se trata únicamente de enlaces simbólicos a elementos del directorio /etc/init.d. En realidad, es en este directorio donde se almacenan los scripts que forman parte de la secuencia de arranque de la mayoría de distribuciones de tipo Debian.
Si tomamos como ejemplo el contenido del directorio /etc/rc1.d, podemos observar que, efectivamente se trata de enlaces simbólicos (por ejemplo, K20rsync hace referencia a ../init.d/rsync).
A simple vista, también podemos observar una diferencia entre los nombres de unos scripts y otros: unos comienzan con la letra K y otros con la letra S. El motivo es que, al arrancar el sistema en el nivel de ejecución correspondiente (en este caso, el 1), los scripts que comienzan con la letra K finalizan servicios (Kill) y los que comienzan con la letra S los inician (start). En definitiva, lo que hacen es pasar el argumento stop o start al script adecuado en /etc/init.d.
Si un servicio debe correr únicamente en un nivel de ejecución particular, dispondrá de un script de inicio (cuyo nombre comenzará por la letra S) en la carpeta correspondiente a dicho nivel, mientras que en las carpetas del resto de los niveles de ejecución deberá aparecer un script de finalización (cuyo nombre comenzará por la letra K). De esta forma, cuando cambiemos de nivel de ejecución, se detendrán todos los servicios innecesarios.
El número que sigue a la letra inicial hace que cada script se ejecute en un orden determinado. El número particular no es importante, pero lo que sí importa es la secuencia, para que algunos servicios puedan iniciarse, o pararse, antes que otros.
¿Cómo funcionan los scripts de inicio?
Cuando arranca el sistema, se ejecuta el script /etc/init.d/rcS. Su misión será ejecutar, de forma ordenada, todos los scripts que comiencen por la letra S en el directorio /etc/rcS.d. A cada uno de ellos les pasa, como primer argumento, el valor start. Por el momento, el nivel de ejecución es N (none).
En esta etapa, sólo deben ejecutarse los elementos imprescindibles para llevar al sistema hasta un estado consistente. En este nivel no debe iniciarse ningún servicio a menos que resulte imprescindible.
Después de ejecutar los scripts que hay en /etc/rcS.d, el proceso de inicio cambia al nivel de ejecución predeterminado, que suele ser 2. A partir de ahí, se ejecuta el script /etc/init.d/rc, que irá iniciando, uno a uno, los servicios que encuentre en /etc/rc2.d (es el directorio que corresponde al nivel de ejecución).
En otras distribuciones, el nivel de ejecución predeterminado se guarda en /etc/inittab. Sin embargo, en Ubuntu se guarda dentro del archivo /etc/init/rc-sysinit.conf, en la variable DEFAULT_RUNLEVEL.
Dado que el nivel de ejecución anterior era N, los scripts que comienzan por K no se ejecutan, ya que aún no hay ningún servicio que detener.
Lo comentado hasta ahora es válido de forma general para todos los niveles de ejecución, pero existen algunas cuestiones particulares:
-
El nivel de ejecución Monousuario: Llegamos a él cambiando al nivel de ejecución 1. Esto detendrá todos los servicios del sistema (como si todos tuviesen un script K en el directorio /etc/rc1.d). Después, se producirá un cambio al nivel de ejecución S, que no suele tener scripts, y se genera una shell para mantenimiento directamente en /dev/console.
-
Cuando paramos o reiniciamos el sistema (cambiando a los niveles de ejecución 0 o 6, respectivamente), se ejecutarán en orden todos los scripts K contenidos en el directorio correspondiente (/etc/rc0.d o /etc/rc6.d). A continuación, si existe algún script S, también se ejecuta de forma ordenada, pero enviando un argumento stop.
Y esto es todo por el momento. Espero que te haya resultado útil.