les développeurs aussi maitrisent le systèmd - devoxx 2015
TRANSCRIPT
@Jean_Eudes#DevoxxSystemD
Les développeurs aussi maîtrisent le systemd
@Jean_EudesXebia DeveloperDevops fan
@Jean_Eudes#DevoxxSystemD
Calendrier
• Système d'init ?
• SystemD : Une solution à quelles problématiques ?
• Décortiquons un peu systemD
• Les « scripts » SystemD
@Jean_Eudes#DevoxxSystemD
Responsabilité de l'init
• Initialisation des processus
• Gestion du cycle de vie des processus
• Resté en vie
@Jean_Eudes#DevoxxSystemD
System V
. /lib/lsb/init-functionsNAME=cocktailEXEC=$CATALINA_HOME/bin/startup.shPIDFILE=$CATALINA_BASE/logs/cocktail.pidexport CATALINA_PID=$PIDFILEdo_start(){start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $EXEC -c tomcat}do_stop(){start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILErm -f $PIDFILE}do_status(){status_of_proc -p $PIDFILE $EXEC $NAME && exit 0 || exit $?}
@Jean_Eudes#DevoxxSystemD
Les problématiques avec SystemV
• Les dépendances entre services
• Gestion des daemons
• Gestion des processus zombie
• Duplication du code
@Jean_Eudes#DevoxxSystemD
Fiche signalétique
• Projet commence en 2010
• Écrit en C
• maintenu par Lennart Poettering
@Jean_Eudes#DevoxxSystemD
Adoption
• Fedora / Red Hat / Centos
• Archlinux
• Debian / Ubuntu (en cours)
@Jean_Eudes#DevoxxSystemD
Améliorer la vitesse de démarrage
• Paralléliser le démarrage des services
• Démarrer moins de services
@Jean_Eudes#DevoxxSystemD
Une autre alternative
• Supprimer la dépendance au service
• Dépendre uniquement de la socket
@Jean_Eudes#DevoxxSystemD
Comment suivre les processus : cgroup
• Regrouper des processus
• Contrôler l'usage des ressources matériels
• Comptabiliser les ressources utilisées
@Jean_Eudes#DevoxxSystemD
Gestion des logs
• Un nouvel outil : journald
• Récupérer facilement les logs des services
• Requêter plus facilement les logs
• zip, rotation, ...
@Jean_Eudes#DevoxxSystemD
All is Unit
• Un service : unit
• Monter un système de fichier : unit
• Créer une socket : unit
• Créer un cron : unit
• ...
@Jean_Eudes#DevoxxSystemD
Connaître la liste de tous les services
$ systemctl list-units -t service --all
@Jean_Eudes#DevoxxSystemD
Gestion des unités
$ systemctl start <unit>$ systemctl stop <unit>$ systemctl restart <unit>$ systemctl reload <unit>
@Jean_Eudes#DevoxxSystemD
activer une unité au démarrage
$ systemctl enable <unit>$ systemctl disable <unit>
@Jean_Eudes#DevoxxSystemD
Lire les logs de la dernière heure
$ journalctl --since="2015-04-10 13:30:00"
@Jean_Eudes#DevoxxSystemD
Lire les logs de l'avant dernière heure
journalctl --since="2015-04-10 12:30:00" -until="2015-04-10 13:30:00"
@Jean_Eudes#DevoxxSystemD
De très nombreux critères de recherches
• service
• date
• utilisateur, groupe
• ...
@Jean_Eudes#DevoxxSystemD
Version SystemV
. /lib/lsb/init-functionsNAME=cocktailEXEC=$CATALINA_HOME/bin/startup.shPIDFILE=$CATALINA_BASE/logs/cocktail.pidexport CATALINA_PID=$PIDFILEdo_start(){start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $EXEC -c tomcat}do_stop(){start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILErm -f $PIDFILE}do_status(){status_of_proc -p $PIDFILE $EXEC $NAME && exit 0 || exit $?}
@Jean_Eudes#DevoxxSystemD
Un exemple Simple
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.js
$ systemctl start monAppli.service
@Jean_Eudes#DevoxxSystemD
Activation en service
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.js
[Install]WantedBy=multi-user.target
$ systemctl enable monAppli
@Jean_Eudes#DevoxxSystemD
Redémarrage automatique
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.jsRestart=Always
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Redémarrage automatique
• Les autres options :
• no (par défaut)
• always
• on-success
• on-abort
• on-abnormal
@Jean_Eudes#DevoxxSystemD
Redémarrage automatique
• Définir un laps de temps : RestartSec
• 100 ms par défaut
@Jean_Eudes#DevoxxSystemD
Passons en mode production
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.jsRestart=AlwaysEnvironnement=NODE_ENV=production
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Récupérons les logs
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.jsRestart=AlwaysStandardOutput=journalEnvironnement=NODE_ENV=production
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Récupérons les logs
• Les autres options :
• null
• tty
• journal
• Syslog
• journal+console, syslog+console
• inherit
@Jean_Eudes#DevoxxSystemD
Récupérons les logs
• On a la même option pour la sortie d'erreur : StandardError
@Jean_Eudes#DevoxxSystemD
Utilisation d'un user non root
[Unit]Description=Ma super application en node
[Service]ExecStart=/opt/nodejs/bin/node /var/www/myApp/main.jsRestart=AlwaysStandardOutput=journalUser=nobodyGroup=nobodyEnvironnement=NODE_ENV=production
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Utilisons chroot[Unit]Description=Ma super application en node
[Service]ExecStart=/nodejs/bin/node /www/myApp/main.jsRestart=AlwaysStandardOutput=journalUser=nobodyGroup=nobodyRootDirectory=/opt/myApp/Environnement=NODE_ENV=production
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Comment arrêter mon service
• Définir une commande ExecStop
• Sinon kill par défaut
• Tue l'ensemble des processus généré par le processus parent
@Jean_Eudes#DevoxxSystemD
Essayons avec un tomcat
[Unit]Description=Ma super application en Java
[Service]Type=forkingPIDFile=/var/run/tomcat.pidEnvironnement=CATALINA_PID=/var/run/tomcat.pidExecStart=/usr/bin/tomcat start
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Les autres valeurs de Type
• simple (valeur par défaut)
• forking
• oneshot
• dbus, notify, idle
@Jean_Eudes#DevoxxSystemD
Essayons avec un docker
[Unit]Description=Ma super application sous docker
[Service]ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Essayons avec un docker
[Unit]Description=Ma super application sous dockerAfter=docker.socketRequires=docker.socket
[Service]ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
[Install]WantedBy=multi-user.target
Dépendance vers docker
@Jean_Eudes#DevoxxSystemD
Gestion des dépendances
• Requires, Wants
• Before, After
$ systemctl list-dependencies busybox1
@Jean_Eudes#DevoxxSystemD
Des listeners ?[Unit]Description=Ma super application sous dockerAfter=docker.serviceRequires=docker.service
[Service]ExecStartPre=/usr/bin/docker kill busybox1ExecStartPre=/usr/bin/docker rm busybox1ExecStartPre=/usr/bin/docker pull busyboxExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
[Install]WantedBy=multi-user.target
@Jean_Eudes#DevoxxSystemD
Mais encore,
• Démarrer une socket (System.inheritedChannel())
• Monter un système de fichier
• Démarrer des cron
• Lancer des containers (machinectl)
@Jean_Eudes#DevoxxSystemD
Pour aller plus loin
• man
• http://0pointer.de/blog/projects/systemd.html (lennart)
• http://www.freedesktop.org/wiki/Software/systemd/