Systemd

Systemd es un administrador del sistema y servicios de GNU/Linux. Se ha diseñado para mantener la compatibilidad con los scripts SysV. Systemd sustituye a Upstart en CentOS 7, un sistema anterior, promovido por Canonical LTD (Ubuntu).

Systemd introduce el concepto de unidades systemd. Estas unidades están configuradas en archivos localizados en las siguiente ubicaciones:

  • /usr/lib/systemd/system/: unidades distribuidas con paquetes RPM instalados.

  • /run/systemd/system/: unidades creadas en tiempo de ejecución. Tiene precedencia sobre el directorio anterior.
  • /etc/systemd/system/: unidades creadas y administradas por el administrador del sistema. Este directorio tiene precedencia sobre el directorio anterior.

Systemd proporciona diferentes tipos de unidades. Dichos tipos de unidad se distinguen según la extensión de archivo correspondiente.

systemctl list-units --all

El coamndo anterior mostrará cualquier unidad cargada o que se haya intentado cargar, independientemente de su estado en el sistema. Algunas unidades pasan a estar inactivas después haberse ejecutado, mientras que otras pueden no haber sido encontradas en disco. Se pueden utilizar otras opciones en el comando para filtrar las unidades mostradas, como por ejemplo --state= para indicar el estado o --type para indicar el tipo de unidad.

El comando list-units solo muestra las unidades que systemd ha intentado cargar (directa o indirectamente a través de dependencias). Systemd solo intenta cargar las unidades que necesita en su árbol de dependencias, pero existen otras unidades. Para conocerlas, ejecutamos:

systemctl list-unit-files

El estado que se muestra con este comando puede ser enabled, disabled, static, o masked. En este contexto, static significa que la unidad no contiene una sección install, lo que quiere decir que no está destinada a ser ejecutada directamente (puede serlo via dependencia). Las unidades masked han sido administrativamente bloqueadas, de forma que no pueden ser iniciadas. El resto de estados lo iremos viendo a continuación

systemctl show nombre_unidad

El comando anterior permite mostrar los detalles de una cierta unidad.

Actividad 1. De entre todas las unidades que hay en el sistema, muestra los detalles de una unidad de tu elección.

Entrega la captura con el nombre act1-systemd.png.

Administrando servicios del sistema

Upstart (la versión anterior de CentOS) utiliza para gestionar servicios los scripts ubicados en /etc/rc.d/init.d/. Estos scripts están escritos en Bash, y permiten tener control sobre el estado de los servicios y demonios en sus sistemas. En CentOS 7, estos scripts han sido reemplazados con unidades de servicio (service units)

Las unidades de servicio tienen la extensión .service y tienen el mismo propósito que los scritps init. Para iniciar, detener, reiniciar, activar o desactivar un cierto servicio, se utiliza el comando systemctl

Los comandos service y chkconfig siguen siendo válidos, pero sólamente están incluidos con propósitos de compatibilidad con sistemas antiguos, y deben ser evitados.

Listado de servicios activos

Para comprobar todos las unidades de servicio cargadas, ejecutamos el comando:

systemctl list-units --type service

Para cada unidad de servicio, este comando muestra su nombre completo (UNIT) seguido de una anotación indicando si la unidad se ha cargado (LOAD), su estado activación (ACTIVE ó SUB) y una breve descripción (DESCRIPTION).

Por defecto, systemctl list-units muestra solamente las unidades activas. Si deseamos mostrar todas las unidades independientemente de su estado, utilizamos el parámetro --all.

systemctl list-units --type service --all

También se pueden listar las unidades de servicio disponibles, y comprobar así si están activadas:

systemctl list-unit-files --type service

Para comprobar los detalles sobre una cierta unidad de servicio:

systemctl status nombre-del-servicio.service

La información que proporciona este comando es:

  • Loaded - Información sobre si la unidad servicio ha sido cargada, la ruta absoluta la unidad de servicio y si la unidad está activa.
  • Active - Información sobre si la unidad de servicio está ejecutándose, con timestamp incluido.
  • Main PID - El PID del servicio seguido de su nombre.
  • Status - Información adicional sobre el servicio.
  • Process - Información adicional sobre procesos relacionados.
  • CGroup - Información adicional.

Para comprobar simplemente si una unidad de servicio está ejecutándose:

systemctl is-active nombre-del-servicio.service

Del mismo modo, para comprobar si una unidad de servicio está activada (configurada para iniciar cuando el sistema arranca):

systemctl is-enabled nombre-del-servicio.service

Una unidad de servicio puede tener los siguientes estados:

  • enabled: configurada para ejecutarse durante el inicio del sistema.
  • disabled: configurada para no ejecutarse durante el inicio del sistema.
  • active: unidad que se está ejecutando actualmente.
  • inactive: unidad que no se está ejecutando actualmente.
  • failed: unidad que ha fallado durante su inicio.

Una unidad que no está activada puede estar activa si ha sido arrancada durante la sesión. Del mismo modo, una unidad puede estár inactiva, a pesar de estar activada.

Iniciar un servicio

Para iniciar un servicio:

systemctl start nombre-del-servicio.service

Este comando incia el servicio en esta sesión solamente, de modo que en el siguiente reinicio el servicio solo se ejecutará si la unidad de servicio está activa.

Para detener un servicio:

systemctl stop nombre-del-servicio.service

Detener un servicio es diferente a desactivarlo, ya que si simplemente lo detenemos, el servicio volverá a iniciarse automáticamente durante el próximo inicio.

Para reiniciar un servicio:

systemctl restart nombre-del-servicio.service

Si todo va bien, no mostrará nada por pantalla. Este comando solamente tiene sentido en caso de que el servicio correndiente ya está ejecutándose.

Si queremos que un servicio únicamente se reinicie en caso de estar ejecutándose:

systemctl try-restart nombre-del-servicio.service

Algunos servicios permiten que solamente se recarge su configuración sin interrumpir su ejecución. Esto es interesante en el caso de ciertos servicios que no se pueden o deben parar, pero cuya configuración hay que modificar. Para ello:

systemctl reload nombre-del-servicio.service

Activando un servicio

Para configurar una unidad de servicio para que se inicie durante el arranque del sistema:

systemctl enable nombre-del-servicio

Este comando crea un enlace simbólico en /etc/systemd/system apuntando a /usr/lib/systemd/nombre-del-servicio.service, pero no lo recrea en caso de existir. Si deseamos asegurarnos de que el enlace sea efectivamente creado:

systemctl reenable nombre-del-servicio.service

Con reenable el enlace simbólico es eliminado y se crea de nuevo.

Desactivando un servicio

Para evitar que un servicio se inicie durante el arranque del sistema:

systemctl disable nombre-del-servicio.service

Este comando borra el enlace simbólico de /etc/systemd/system a la unicad de servicio, ubicada en /usr/lib/systemd/system/nombre-del-servicio.service.

Para que un servicio no pueda ser iniciado manualmente o bien por otro servicio:

systemctl mask nombre-del-servicio.service

Este comando reemplaza el enlace de /etc/systemd/system a la unidad de servicio, por un enlace a /dev/null. Para invertir el proceso:

systemctl unask nombre-del-servicio.service

Actividad 2. Comprueba si tienes instalado el servidor web Apache (httpd). En caso contrario, instálalo. Una vez que se instale, comprueba si está activado.

Toma una captura y guárdala como Act2-systemd.png

Actividad 3. Desactiva el servidor Apache (si no está desactivado ya). Reinicia CentOS y comprueba si está iniciado.

Toma una captura y guárdala como Act3-systemd.png

Actividad 4. Con el servicio Apache desactivado, ejecútalo y comprueba que está activo.

Toma una captura y guárdala como Act4-systemd.png

Actividad 5. Finalmente, activa el servicio Apache. Después reinicia y comprueba que está activo.

Toma una captura y guárdala como Act5-systemd.png

Targets

En CentOS 7, el concepto de runlevel ha sido sustituido por objetivos (target). Los target, se representan mediante archivos con extensión .target, y su propósito es agrupar otras unidades de systemd a través de una cadena de dependencias. Por ejemplo, la unidad graphical.target se usa para iniciar la sesión gráfica, inicia servicios como GNOME Display Manager (gdm.service) o el servicio Accounts (accounts-daemon.service). Además activa la unidad multi-user.target. Del mismo modo, la unidad multi-user-target inicia otros servicios necesarios, como NetworkManager (NetworkManager.service) además de activar otra unidad llamada basic.target.

Aunque no hay un orden estricto en que se inician los servicios cuando se arranca un sistema CentOS 7 (con systemd), hay una estructura para el proceso de arranque. Todo depende del archivo default.target ubicado en /etc/systemd/system. Este archivo, es en realidad un enlace simbólico a un target ubicado en /usr/lib/systemd/system, donde se muestra qué targets se iniciarán durante el arranque. Se puede ver el contenido de dicho target en /user/lib/systemd/system/default.target.

Para comprobar el target por defecto:

systemctl get-default

El archivo default.target contiene entre otros los siguientes parámetros:

  • Requires: iniciar la unidad citada. Si el target citado está desactivado, el target también se desactivará
  • Wants: iniciar la unidad citada de una forma menos exigente que "Requires". Si las unidades citadas no se inician, no tiene impacto sobre la operación en su conjunto. Las dependencias de este tipo también se pueden configurar fuera del archivo de configuración de la unidad, mediante la adición de enlaces simbólicos a un directorio .wants que acompaña a la unidad.
  • Before: unidades que se cargarán después que el target.
  • After: unidades que se cargarán antes que el target. Suele incluirse junto con la opción Requires. Si dos unidades no tienen dependencias de orden, se cargarán simultáneamente.
  • Conflicts: detiene la unidad o unidades citadas ya que son incompatibles.

Para máyor información, consultar http://www.freedesktop.org/software/systemd/man/systemd.unit.html

Para comprobar los targets que han sido cargados:

systemctl list-units --type target

Si lo que queremos es mostrar todas las unidades cargadas, independientemente de su estado, añadimos la opción --all al final:

systemctl list-units --type target --all

Cambiar el target

Para cambiar el target por defecto:

systemctl set-default nombre-del-target.target

Para cambiar a un target diferente durante la sesión actual:

systemctl isolate nombre-del-target.target

Actividad 6. Cambia al target multiuser. Después vuelve al target por defecto.

Toma una captura con el nombre Act6-systemd.png una vez cargues el target.

Actividad 7. Redefine el target multiuser como el target por defecto. Después reinicia y comprueba que no se arranca el entorno gráfico.

Toma una captura donde se pueda ver el target por defecto y guárdala como Act7-systemd.png.

Cambiar al modo de recuperación

Podemos desear cambiar al modo de recuperación una vez que hemos iniciado el sistema. Esto puede ser interesante si queremos poner el sistema en un estado básico, desactivando servicios que no son impresicindibles (como red), para iniciar tareas de recuperación.

systemctl rescue

Cambiar al modo de emergencia

El modo de emergencia provee el entorno mínimo para recuperar el sistema en situaciones en que no se puede acceder al modo de recuperación. En este modo el sistema de archivos se monta el punto de montaje raíz en modo de solo lectura, no se montan otros puntos de montaje ni el servicio de red, y solamente unos cuantos servicios son iniciados. Para cambiar al modo de emergencia:

systemctl emergency

Gestión de apagado/encendido

Algunos comandos útiles son:

  • systemctl halt: Apaga abruptamente el sistema
  • systemctl poweroff: Apaga el sistema
  • systemctl reboot: Reinicia el sistema
  • systemctl suspend: Suspende el sistema
  • systemctl hibernate: Hiberna el sistema
  • systemctl hybrid-sleep: Hiberna y suspende el sistema

Controlar Systemd en una máquina remota

Para controlar Systemd en otra máquina:

systemctl --host nombre_usuario@nombre_maquina comando

O bien, también se puede utilizar SSH.

Crear un script que se ejecute durante el proceso de arranque

Supongamos que contamos con un script llamado mi-script.sh, que queremos que se ejecute durante el arranque. Entonces es preciso realizar el siguiente procedimiento:

  1. Crear un nuevo archivo llamado mi_script.service /etc/systemd/system.
  2. NOTA: El script mi-script.sh debe tener permisos de ejecución.

  3. Comprobar el target por defecto:
  4. systemctl get-default
  5. Supongamos que el target por defecto es graphical.target. Entonces deberemos añadir el siguiente contenido al archivo mi_script.service:
  6. [Unit] Description=My script [Service] ExecStart=/usr/bin/mi-script.sh [Install] WantedBy=multi-user.target
  7. Finalmente, debemos habilitar el servicio mi_script.service:
  8. systemctl enable mi_script.service

    Actividad 8. Crea un script llamado test.sh que cree un archivo llamado test.txt en el directorio /root. Después configura systemd para que lo ejecute durante el inicio del sistema.

    Toma una captura donde se pueda ver la unidad que has configurado, y guárdala con el nombre Act8-systemd.png

    Mounts

    Tradicionalmente en GNU/Linux, el montaje automático de unidades se venía haciendo mediante el archivo /etc/fstab. Pero esto ha cambiado con la llegada de Systemd. Systemd maneja el automontaje de las unidades. El archivo /etc/fstab es utilizado por Systemd para generar unidades mount. En primer lugar vamos a ver cómo funciona fstab.

    fstab

    El archivo /etc/fstab es usado para definir cómo las particiones, distintos dispositivos de bloques o sistemas de archivos remotos deben ser montados e integrados en el sistema. El posible contenido de un archivo fstab podría ser:

    # UUID=24f28fc6-717e-4bcd-a5f7-32b959024e26 / ext4 defaults,noatime 0 1 UUID=03ec5dd3-45c0-4f95-a363-61ff321a09ff /home ext4 defaults,noatime 0 2 UUID=4209c845-f495-4c43-8a03-5363dd433153 none swap defaults 0 0

    Cada línea incluye la siguiente información:

    • UUID - Define el dispositivo que va a ser montado. Es preferible usar la UUID a "/dev/x" puesto que la UUID es independiente del nombre que el sistema otorga al dispositivo.
    • directorio - Indica el punto de montaje de la partición.
    • tipo de partición - indica el sistema de archivos de la partición. Algunos ejemplos pueden ser ext2, ext3, ext4, xfs, vfat o auto. el valor auto permite al comando mount (que es en última instancia quien monta el dispositivo) determine el tipo de partición.
    • opciones - Indica las opciones de montaje que mount empleará. Algunas opciones son:
      • auto - El sistema de archivos será montado automáticamente durante el arranque, o cuando la orden mount -a se invoque.
      • noauto - El sistema de archivos no será montado automáticamente, solo cuando se le ordene manualmente.
      • exec - Permite la ejecución de binarios residentes en el sistema de archivos.
      • noexec - No permite la ejecución de binarios que se encuentren en el sistema de archivos.
      • ro - Monta el sistema de archivos en modo sólo lectura.
      • rw - Monta el sistema de archivos en modo lectura-escritura.
      • user - Permite a cualquier usuario montar el sistema de archivos. Esta opción incluye noexec, nosuid, nodev, a menos que se indique lo contrario.
      • users - Permite que cualquier usuario perteneciente al grupo users montar el sistema de archivos.
      • nouser - Solo el usuario root puede montar el sistema de archivos.
      • owner - Permite al propietario del dispositivo montarlo.
      • sync - Todo el I/O se debe hacer de forma sincrónica.
      • async - Todo el I/O se debe hacer de forma asíncrona.
      • dev - Intérprete de los dispositivos especiales o de bloque del sistema de archivos.
      • nodev - Impide la interpretación de los dispositivos especiales o de bloques del sistema de archivos.
      • suid - Permite las operaciones de suid, y sgid bits. Se utiliza principalmente para permitir a los usuarios comunes ejecutar binarios con privilegios concedidos temporalmente con el fin de realizar una tarea específica.
      • nosuid - Bloquea el funcionamiento de suid, y sgid bits
      • noatime - No actualiza el inode con el tiempo de acceso al filesystem. Puede aumentar las prestaciones (véase opciones atime).
      • nodiratime - No actualiza el inode de los directorios con el tiempo de acceso al filesystem. Puede aumentar las prestaciones (véase opciones atime).
      • relatime - Actualiza en el inode solo los tiempos relativos a modificaciones o cambios de los archivos. Los tiempos de acceso vienen actualizados solo si el último acceso es anterior respecto al de la última modificación. (Similar a noatime, pero no interfiere con programas como mutt u otras aplicaciones que deben conocer si un archivo ha sido leido después de la última modificación). Puede aumentar las prestaciones (véase opciones atime).
      • discard - Emite las órdenes TRIM para dispositivos de bloques subyacentes cuando se liberan los bloques. Recomendado para usar si el sistema de archivos se encuentra en un SSD.
      • flush - La opción vfat permite eliminar datos con más frecuencia, de modo que los cuadros de diálogo de copia o las barras de progreso se mantenga hasta que se hayan escrito todos los datos.
      • nofail - Monta el dispositivo cuando está presente, pero ignora su ausencia. Esto evita que se cometan errores durante el arranque para los medios extraíbles.
      • defaults - Asigna las opciones de montaje predeterminadas que serán utilizadas para el sistema de archivos. Las opciones predeterminadas son: rw, suid, dev, exec, auto, nouser y async
    • dump - Es utilizado por el programa dump para hacer una copia de seguridad. Dump comprueba la entrada en el archivo fstab y el número de la misma le indica si un sistema de archivos debe ser respaldado o no. La entradas posibles son 0 y 1. Si es 0, dump ignorará el sistema de archivos, mientras que si el valor es 1, dump hará una copia de seguridad.
    • pass - Utilizado por fsck para decidir el orden en el que los sistemas de archivos serán comprobados. Las entradas posibles son 0, 1 y 2. El sistema de archivos raíz (/) debe tener la más alta prioridad (1), y todos los demás sistemas de archivos que desea comprobar deben tener un 2. La utilidad fsck no comprobará los sistemas de archivos que vengan ajustados con un valor 0

    Actividad 9. Comprueba el archivo fstab de tu sistema y analiza cada una de las líneas. Escribe en un documento de texto que significa cada una de ellas.

    Guarda la respuesta en un documento llamado Act9-systemd.txt.

    Para conocer el UUID de un dispositivo, podemos utilizar el comando blkid.

    blkid /dev/sda1

    Actividad 10. Añade a la máquina virtual un nuevo disco. Después modifica el archivo fstab para que se monte automáticamente en el siguiente reinicio.

    Muestra el contenido del archivo fstab. Además, ejecuta el comando mount y toma una captura con el nombre Act10-systemd.png

    Para el ejemplo anterior debes tener disponible una partición que montar. En primer lugar es preciso particionar el disco. Para hacer esto, podemos usar la herramienta fdisk del siguiente modo:

    fdisk /dev/sdb

    Para añadir una nueva partición, usamos la opción n. A partir de aquí, podemos ir definiendo el números de partición, tipo de partición (primaria o extendida/lógica), y su tamaño. Finalmente, la opción w guardará los cambios en el disco.

    Finalmente, debemos formatear la unidad, con el comando mkfs. Por ejemplo, para formatear en xfs:

    mkfs.xfs /dev/sdb1

    Hecho esto, ya tenemos una partición (/dev/sdb1) disponible para ser montada.

    Unidades .mount

    Systemd utiliza unidades con extensión .mount para el montaje de unidades de almacenamiento. Para conocer qué unidades de este tipo hay disponibles, podemos ejecutar:

    find / -name "*.mount"
    Comprueba el contenido del archivo tmp.mount

    Un archivo .mount incluye varias secciones. La sección [Mount], es la más importante. En ella se indica qué montar, dónde hacerlo y que tipo usar. El archivo también especifica en qué target se carga la unidad.

    Vamos a crear una nueva unidad de montaje. Creamos un archivo test.mount en la ruta /usr/lib/systemd/system con el siguiente contenido:

    [Unit] Description = test mount [Mount] What = /dev/sdb1 Where = /test Type = xfs [Install] WantedBy = multi-user.target

    Si deseamos cargar inmediatamente la unidad, podemos hacer lo siguiente:

    systemctl start test.mount

    También podemos activar permanentemente la unidad para que se carge durante el arranque mediante systemd enable.

    Actividad 11. Elimina la entrada añadida anteriormente a fstab, y crea una unidad .mount que haga la misma tarea.

    Toma una captura donde se pueda ver el contenido de la unidad, así como el resultado de ejecutar el comando mount y guárdala con el nombre Act11-systemd.png.