Différences
Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
remplacer_cron_par_systemd [Le 27/10/2019 à 14:39] minzord effacée |
— (Version actuelle) | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ======== Remplacer cron par systemd ======== | ||
- | Les versions récentes de [[http://www.freedesktop.org/wiki/Software/systemd/|systemd]] améliorent le lancement d'évènements selon des critères temporels. Ce tutoriel montre, pour un cas simple, comment remplacer **cron** par **systemd**. | ||
- | |||
- | Pour apporter plus de précisions, ce tutoriel contient de nombreux liens vers [[http://www.freedesktop.org/software/systemd/man/|le manuel]] de **systemd**. N'hésitez pas à cliquer ! ;-) | ||
- | |||
- | * [[https://linuxfr.org/news/%C3%A9volutions-techniques-de-systemd|En savoir plus sur systemd]] | ||
- | * [[https://linuxfr.org/news/archlinux-utilise-desormais-systemd-par-defaut-pour-les-nouvelles-installations#toc_3|Listes (non exhaustive) des distributions utilisant systemd]] | ||
- | |||
- | ===== Situation initiale ===== | ||
- | |||
- | Chez moi, le répertoire **/etc/cron.d/** ne contient qu'un seul et unique fichier, nommé **0hourly** dont voici le contenu : | ||
- | <code bash>$ cat /etc/cron.d/0hourly</code> | ||
- | <code bash>SHELL=/bin/bash | ||
- | PATH=/sbin:/bin:/usr/sbin:/usr/bin | ||
- | MAILTO=root | ||
- | 00 * * * * root run-parts /etc/cron.hourly</code> | ||
- | |||
- | La dernière ligne nous informe que **cron** exécute la commande | ||
- | $ run-parts /etc/cron.hourly | ||
- | toutes les heures, et en tant que root((Pour information : la commande **run-parts /etc/cron.hourly** lance tous les scripts contenus dans le répertoire /etc/cron.hourly/. Il n'y a qu'un seul script dans ce répertoire, qui se charge de lancer anacron. Celui-ci est configuré (via son fichier de configuration /etc/anacrontab) pour lancer des programmes de façon quotidienne, hebdomadaire ou mensuelle.)). | ||
- | |||
- | Il n'y a pas d'autre fichier que **0hourly** dans le répertoire **/etc/cron.d/** ; nous en déduisons que, sur ma machine, **cron** ne sert qu'à une chose : lancer une commande toutes les heures. Pour ce cas simple, voyons comment remplacer **cron** par **systemd**. | ||
- | |||
- | |||
- | ===== Stopper et désactiver cron ===== | ||
- | |||
- | Pour commencer, nous [[http://www.freedesktop.org/software/systemd/man/systemctl.html#stop%20NAME...|stoppons]] **cron** : | ||
- | $ systemctl stop cronie.service | ||
- | et nous [[http://www.freedesktop.org/software/systemd/man/systemctl.html#disable%20NAME...|désactivons]] le lancement automatique de **cron** au démarrage de l'ordinateur : | ||
- | $ systemctl disable cronie.service | ||
- | //Remarque : parler de « démarrage de l'ordinateur » est un abus de langage. En fait, nous stoppons le lancement automatique de **cron** dans les cibles (les « target ») où il est lancé automatiquement. Les cibles sont, sous **systemd**, l'équivalent des niveaux d'exécution de **SysVinit**. La principale différence est que __plusieurs__ cibles de **systemd** peuvent être actives simultanément.// | ||
- | |||
- | ===== Créer une première unité systemd : un fichier .service ===== | ||
- | |||
- | Le paramétrage de systemd se fait par l'intermédiaire de fichiers textes : [[http://www.freedesktop.org/software/systemd/man/systemd.unit.html|les unités systemd]]. | ||
- | |||
- | Le gestionnaire de paquets installe ces unités dans le répertoire **/lib/systemd/system/** Comme les fichiers de ce répertoire sont susceptibles d'être modifiés ou effacés lors des mises-à-jour, il nous faut créer nos unités systemd dans un autre répertoire, réservé à l'administrateur et protégé des mises-à-jour. Ainsi, c'est le répertoire **/etc/systemd/system/** qui est notre terrain de jeu. :-D | ||
- | |||
- | Dans un premier temps, nous créons un fichier **[[http://www.freedesktop.org/software/systemd/man/systemd.service.html|.service]]** qui décrit la commande que l'on souhaite lancer. Appelons ce fichier **taches-horaires.service** voici son contenu : | ||
- | <code bash>$ cat /etc/systemd/system/taches-horaires.service</code> | ||
- | <code bash>[Unit] | ||
- | Description=Exécution des tâches horaires | ||
- | |||
- | [Service] | ||
- | ExecStart=/usr/bin/run-parts /etc/cron.hourly | ||
- | User=root | ||
- | Type=forking</code> | ||
- | |||
- | La [[http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=|ligne ExecStart=]] indique la commande à lancer. Il est nécessaire de préciser le chemin complet du programme, avec le « /usr/bin/ » devant. La [[http://www.freedesktop.org/software/systemd/man/systemd.exec.html#User=|ligne User=]] précise sous quel utilisateur lancer la commande, et la ligne [[http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=|Type=]] décrit le type de processus. | ||
- | |||
- | //Il existe de très nombreux paramètres pour configurer les unités systemd. Les principales sont expliquées dans les pages de manuel [[http://www.freedesktop.org/software/systemd/man/systemd.unit.html|systemd.unit]], [[http://www.freedesktop.org/software/systemd/man/systemd.service.html|systemd.service]] et [[http://www.freedesktop.org/software/systemd/man/systemd.exec.html|systemd.exec]].// | ||
- | |||
- | Notre unité **.service** décrit parfaitement la commande que l'on souhaite lancer, mais elle ne contient pas le critère temporel « toutes les heures ». Pour cela, nous créons une seconde unité systemd : un « fichier horloge » **[[http://www.freedesktop.org/software/systemd/man/systemd.timer.html|.timer]]** | ||
- | |||
- | ===== Créer une seconde unité systemd : un fichier .timer ===== | ||
- | |||
- | Toujours dans le répertoire **/etc/systemd/system/**, nous créons le fichier **horloge-taches-horaires.timer** Il s'agit d'un « fichier horloge » **.timer** qui précise le caractère « toutes les heures » du lancement de l'unité **.service** créée précédemment. Le contenu de ce fichier **.timer** est : | ||
- | |||
- | <code bash>$ cat /etc/systemd/system/horloge-taches-horaires.timer</code> | ||
- | <code bash>[Unit] | ||
- | Description=Horloge pour lancer "taches-horaires.service" toutes les heures | ||
- | |||
- | [Timer] | ||
- | Unit=taches-horaires.service | ||
- | OnCalendar=*-*-* *:00:00 | ||
- | |||
- | [Install] | ||
- | WantedBy=multi-user.target</code> | ||
- | |||
- | Le paramètre [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#Unit=|Unit=]] indique quelle unité systemd doit être lancée((Le paramètre Unit= de notre unité **.timer** indique quelle unité **.service** doit lancer notre unité **.timer**. Si ce paramètre n'est pas renseigné, l'unité **.timer** lancera l'unité **.service** de même préfixe. Par exemple, //tartempion//**.timer** lancera //tartempion//**.service** (si //tartempion//**.service** existe, évidemment.) )). Le paramètre [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#OnCalendar=|OnCalendar=]] précise les critères temporels du lancement. Sa syntaxe est **AAAA-MM-JJ hh:mm:ss** (il est également possible d'utiliser les jours de la semaine, des précisions [[http://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events|sur ce lien]]). | ||
- | |||
- | Grâce à notre unité **.timer**, notre première unité **.service** sera lancée tous les jours et toutes les heures, à zéro minute et zéro seconde. | ||
- | |||
- | Le paramètre [[http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy=|WantedBy=multi-user.target]] sera abordé plus bas. | ||
- | |||
- | ===== Mettre à jour systemd ===== | ||
- | |||
- | Pour que systemd tienne compte des deux nouvelles unités que nous venons de créer, on [[http://www.freedesktop.org/software/systemd/man/systemctl.html#daemon-reload|recharge]] la configuration de systemd : | ||
- | $ systemctl daemon-reload | ||
- | |||
- | |||
- | ===== Lancer et activer notre unité .timer ===== | ||
- | |||
- | Ouvrons un autre terminal, et utilisons-le pour suivre [[http://www.freedesktop.org/software/systemd/man/journalctl.html|le journal des évènements]] de systemd : | ||
- | $ journalctl -f | ||
- | En cas de problème, les messages fournis par le journal des évènements sont intéressants (pour quitter : touches **Control+C**). | ||
- | |||
- | À présent, [[http://www.freedesktop.org/software/systemd/man/systemctl.html#start%20NAME...|lançons]] notre unité **.timer** : | ||
- | $ systemctl start horloge-taches-horaires.timer | ||
- | |||
- | Nous n'avons pas besoin de lancer l'unité **.service** : c'est l'unité **.timer** qui se chargera de la démarrer toutes les heures. | ||
- | |||
- | Activons [[http://www.freedesktop.org/software/systemd/man/systemctl.html#enable%20NAME...|le lancement automatique]] de notre unité **.timer** : | ||
- | $ systemctl enable horloge-taches-horaires.timer | ||
- | C'est ici qu'entre en jeu le paramètre [[http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy=|WantedBy=multi-user.target]] vu précédemment : notre unité **.timer** sera maintenant lancée automatiquement lorsqu'on activera la cible **multi-user.target**, ce qui est le cas à chaque démarrage //(si la cible **multi-user.target** ne s'active pas au démarrage, c'est que vous avez bidouillé, et que vous savez ce que vous faites ^_^)// | ||
- | |||
- | //Remarque : le lancement automatique de l'unité se traduit par la création d'un lien symbolique dans le répertoire **/etc/systemd/system/multi-user.target.wants/** qui pointe vers notre unité **.timer**// | ||
- | |||
- | ===== Épilogue ===== | ||
- | |||
- | Après plusieurs jours, nous vérifions le bon fonctionnement de nos deux unités en consultant [[http://www.freedesktop.org/software/systemd/man/journalctl.html#-u|le journal des évènements]] de systemd : | ||
- | $ journalctl -u taches-horaires.service | ||
- | $ journalctl -u horloge-taches-horaires.timer | ||
- | (pour quitter : touche **q**) | ||
- | |||
- | ===== Conclusion ===== | ||
- | |||
- | Pour un cas simple, nous avons remplacé **cron** par **systemd**. Nous avons d'abord créé une unité **.service** qui décrit la commande à lancer, puis une seconde unité **.timer** qui précise quand lancer l'unité **.service** | ||
- | |||
- | Cette méthode est-elle généralisable à des cas plus complexes ? La pierre angulaire de cette méthode est le paramètre [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#OnCalendar=|OnCalendar=]] de l'unité **.timer**, qui indique quand agir. [[http://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events|Sa syntaxe]] couvre de nombreux cas, aussi il est certainement possible de généraliser cette méthode, et de remplacer totalement **cron** par **systemd**. | ||
- | |||
- | Systemd permet également de lancer des unités selon des contraintes temporelles plus fines, par exemple : toutes les semaines **et** cinq minutes après le démarrage de l'ordinateur. Plus d'info [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#OnActiveSec=|sur ce lien]]. | ||
- | |||
- | Notons toutefois que **systemd** ne peut pas, à l'heure actuelle, remplacer **anacron**. En effet, **systemd** perd l'information « date de la dernière activation de l'unité machin » lors d'un arrêt de l'ordinateur. Voir [[http://lists.freedesktop.org/archives/systemd-devel/2013-February/008661.html|cette question]] et [[http://lists.freedesktop.org/archives/systemd-devel/2013-February/008697.html|la réponse apportée]]. Cette fonctionnalité arrivera peut-être dans une version future … En attendant, nous devrons nous contenter d'**anacron** pour les tâches | ||
- | planifiées sur des ordinateurs qui ne sont pas allumés en permanence. | ||
- | |||
- | ===== Licence de ce tutoriel ===== | ||
- | Ce tutoriel est publié sous la licence [[http://www.wtfpl.net/|« Do What the Fuck You Want to Public License »]]. | ||
- | |||
- | [[http://www.wtfpl.net|{{ :logo_wtfpl.png | Logo « Do What the Fuck You Want to Public License »}}]] | ||
- | |||
- | |||
- | ===== Ajout de juin 2014 : l'option Persistent= ===== | ||
- | |||
- | > Notons toutefois que systemd ne peut pas, à l'heure actuelle, remplacer anacron. En effet, systemd perd l'information « date de la dernière activation de l'unité machin » lors d'un arrêt de l'ordinateur. | ||
- | |||
- | Cela a changé récemment : depuis [[http://lists.freedesktop.org/archives/systemd-devel/2014-March/018232.html|sa version 212]], systemd offre l'option [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#Persistent=|Persistent=]] qui enregistre sur le disque dur la date de dernière exécution du service associé au **timer**. Ainsi, même lorsque l'ordinateur a été redémarré, systemd connaît la date de la dernière activation de l'unité. | ||
- | |||
- | Pour un service démarré périodiquement (c'est le cas qui nous intéresse ici) : si une occurrence du service n'a pas été démarrée au moment prévu parce que l'ordinateur était éteint à ce moment-là, le service sera lancé au prochain démarrage de l'ordinateur. | ||
- | |||
- | Voici deux exemples d'unité **timer** utilisant l'option [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#Persistent=|Persistent=]] : | ||
- | |||
- | <code bash>$ cat /lib/systemd/system/updatedb.timer</code> | ||
- | <code bash>[Unit] | ||
- | Description=Lancement quotidien de l'unité updatedb.service | ||
- | |||
- | [Timer] | ||
- | Unit=updatedb.service | ||
- | OnCalendar=daily | ||
- | Persistent=true</code> | ||
- | |||
- | |||
- | <code bash>$ cat /etc/systemd/system/mon-ntpd-personnel.timer</code> | ||
- | <code bash>[Unit] | ||
- | Description=Lancement hebdomadaire de l'unité mon-ntpd-personnel.service | ||
- | |||
- | [Timer] | ||
- | Unit=mon-ntpd-personnel.service | ||
- | OnCalendar=weekly | ||
- | Persistent=true | ||
- | AccuracySec=12h | ||
- | |||
- | [Install] | ||
- | WantedBy=multi-user.target</code> | ||
- | |||
- | Remarque : pour en savoir plus sur l'option [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#AccuracySec=|AccuracySec=]]. | ||
- | |||
- | L'option [[http://www.freedesktop.org/software/systemd/man/systemd.timer.html#Persistent=|Persistent=]] permet de déclencher des évènements périodiques, y compris pour des machines qui ne sont pas allumées en permanence. Systemd peut maintenant remplacer anacron. |