Différences

Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.

Lien vers cette vue

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. 
 
    Haut de page
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki Design by Chirripó