*

Systemd timer pour les Cro(o)ners


29/01/2018 cron crontab systemd timer unit

Cron et Crontab sont dans un bateau…

Il fut un temps où pour programmer le lancement des actions, notre meilleur ami était “cron” et la “crontab”. Outre la syntaxe et l’organisation de la crontab peu mémorisable, les tâches cron restaient complexes à déployer et à monitorer dans leur exécution. Si le fait d’avoir des répertoires plus génériques comme /etc/cron.{d,hourly,daily,weekly,monthly} ont un peu amélioré la partie exploitabilité/déployabilité, ils offraient assez peu de souplesses pour une plannification fine des tâches. De nombreux serveurs ont donc eu un mix de crontab classique et de ce format pendant des années.

Debian 9.0 (mais d’autres aussi comme Archlinux par ex) a fait le choix dans le cadre de son adoption de systemd de ne plus proposer un logiciel de type cron mais de s’appuyer sur l’implémentation interne à systemd, à savoir les “timers”. C’est une unité (unit) spéciale de systemd qui est controllée et supervisée par systemd et qui s’exécute selon une configuration temporelle donnée.

Voyons comment passer de cette crontab :

0 4 * * * /path/to/scripts/backup.sh >> /var/log/backup.log 2>&1

… ou de /etc/cron.daily/mybackup.sh appelant le même script à son équivalent sous un timer systemd.

Implémentation d’un timer systemd.

Si vous gérez déjà vos services via systemd, vous avez déjà utilisé des “unit” systemd de type “service”. Ces “unit” permettent de définir un process et son mode d’éxécution.

Pour implémenter un “timer” sous systemd, il va nous falloir un fichier “service”.

Pour notre tâche à planifier, nous allons avoir au final 3 fichiers :

  • Le script à exécuter ; c’est votre script /path/to/scripts/backup.sh ; il est inchangé par rapport à précédemment.
  • Le fichier “service” qui va dire quel script exécuter
  • Le fichier “timer” qui va indiquer quand il doit être exécuté.

A noter que par convention, les fichiers service et timer doivent avoir le même nom (foo.service, foo.timer).

Pour le fichier service, une base simple est la suivante :

/etc/systemd/system/mybackup.service :

[Unit]
Description=My Daily Backup

[Service]
Type=simple
ExecStart=/path/to/scripts/backup.sh
StandardError=journal

Je fournis une description à mon service, indique que c’est un process de type simple, le chemin vers mon script et je rajoute que le flux d’erreur est envoyé dans le journal. Pour plus d’information, se reporter à la doc des services et des exécutions.

Attention néanmoins, il ne faut pas de section [Install] car le script va être piloté par le fichier timer.

Ensuite, il nous faut un fichier “timer” :

/etc/systemd/system/mybackup.timer :

[Unit]
Description=My Daily Backup

[Timer]
# Define a calendar event (see `man systemd.time`)
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Au-delà de la description, les lignes importantes sont la section [Timer] et [Install] :

  • OnCalendar permet d’indiquer l’occurrence et la fréquence d’exécution du script. Il y a les abréviations classiques (daily, weekly, etc) mais vous pouvez avoir des choses plus complexes comme "Mon,Tue *-*-01..04 12:00:00" - voir systemd.time
  • Persistent va forcer l’exécution du script si la dernière exécution a été manquée suite à un reboot de serveur ou autre événement.
  • Enfin, la section Install va créer la dépendance pour que votre “timer” soit bien exécuté et pris en compte par systemd.

Il ne reste plus qu’à activer le timer et le démarrer :

systemctl enable mybackup.timer
systemctl start mybackup.timer

Gestion et suivi d’un timer

Pour voir la liste des “timers” actifs sur votre serveur, la date de leur dernière et prochaine exécution :

systemctl list-timers
NEXT                         LEFT          LAST                         PASSED       UNIT                         ACTIVATES
Mon 2018-01-29 17:25:59 CET  2h 27min left Sun 2018-01-28 22:20:35 CET  16h ago      apt-daily.timer              apt-daily.service
Tue 2018-01-30 06:36:33 CET  15h left      Mon 2018-01-29 06:37:35 CET  8h ago       apt-daily-upgrade.timer      apt-daily-upgrade.service
Tue 2018-01-30 09:25:48 CET  18h left      Mon 2018-01-29 09:25:48 CET  5h 33min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

et accéder aux logs de vos “timers” :

journalctl -f -u apt-daily
-- Logs begin at Tue 2018-01-23 13:50:12 CET. --
Jan 28 22:20:35 codb2d9 systemd[1]: Starting Daily apt download activities...
Jan 28 22:20:35 codb2d9 systemd[1]: Started Daily apt download activities.

En cas de modification du .timer ou du .service, ne pas oublier de faire un system daemon-reload pour que la version actualisée de vos fichiers soit prise en compte par systemd.

Passé la petite prise en main de ce nouveau cadre d’exécution, elle me semble plus simple et surtout plus facile à intégrer dans des chaines de déploiements pilotées par Ansible ou autre.

Syndication

Restez informé(s) de notre actualité en vous abonnant au flux du blog (Atom)

Nuage de tags

kubernetes docker timeseries influxdb warp10 traefik grafana ansible elasticsearch kafka postgres python aws sécurité terraform mysql redis telegraf ovh tick cassandra chronograf cloud dashboard docker-compose git hashicorp helm timescaledb flux ptsm swarm vector kapacitor podman rancher résilience test gcp gitlab influxdata log machine-learning monitoring prometheus s3 spark timescale vscode architecture arm comptabilité confluent devops gitlab-ci iac java ksql microservice nomad optimisation postgresql raspberrypi serverless service-mesh sql angularjs api bilan cert-manager cncf consul container cérénit dns flows gke graphql ingress javascript npm opensource operator performance perspective pipeline rook scaleway ssh stream vault warpscript windows cli containerd csp discovery documentation elastic forecast geospatial golang hpkp influxace iot jenkins kafka-streams kibana kubedb lambda lean licence maesh maintenance mariadb microsoft mobile nginx orientdb quasardb redhat registry rest rethinkdb reverse-proxy sauvegarde warpstudio agile anomalie apm arima audit automatisation azure bash big-data bigdatahebdo ceph certificat challenge ci/cd cluster continous-delivery continous-integration cookie data datatask dataviz dbt deployment diff facebook fec fluxlang framework gdpr grav hsts http/3 https hypriot hébergement ia influxdays istio jq json k3s lets-encrypt linux load-balancer longhorn meetup metabase molecule mongodb nosql nvidia openebs openssh ovhcloud percona php pip questdb reaper replication rootless rpi rsyslog runc scale secrets société solr sre systemd tempo timezone tls virtualenv vitess vue.js wagtail warpfleet yarn accessibilité acme adoptopenjdk agpl akka alerte alertes alerting alibaba amazon-emr amqp anonymisation anthos apache-pulsar ara arrow artefact automation automl banque bastion beam beat bi bme680 bootstrap bounded-context branche brigade browser buildah buildkit cahier-des-charges calico cassandra-reaper cd cdc cdk centos centralisation-de-logs certificats cgroups chart check checklist chrome ci cilium circuitpython clever-cloud clickhouse cloud-init cloud-native cloud-storage cloudflare clusterip cnab cni co2 cockroachdb code codeurs-en-seine commit confluence conftest consul-connect context continous-deployment conventional-commit coreos cors covid19 cqrs crash cri cron crontab csi csrf css curl d3.js daemonset data-engineer data-pipelining data.gouv.fr databricks datacenter date date-scientist ddd debezium debian delta deprek8 desktop devoxx dig distributed-systems dive docker-app docker-hub docker-registry docker-swarm dockershim documentdb dog dokcer données-personnelles draft drop-in duration déploiement développement-du-site e-commerce ebs ec2 edge elassandra electron elk engineering entreprise ergonomie etcd euclidia event-sourcing faas faisabilité falco falcor feature-policy fedora feed filebeat firebase firefox fish flash flask fleet flink fluentd formation foundation frenchtech frontend fsync fullstack git-filter-repo github gitignore glacier glowroot go google google-cloud-next gpg gpu grid géospatial hacker hadoop haproxy harbor hdfs header holt-winters html html5 http hue iaac ibm immutable incident index indluxdata influxcloud infrastructure-as-code ingénierie inspec jquery jvm jwt k3d k6 k8s k9s kaniko katz kotlin kubeadm kubecon kubectl label laravel leap-second lens letsencrypt libssh linky linter liste-de-diffusion lmap loadbalancer logstash logstatsh loi loki lstm mailing-list management maturité mesh mesos message metallb micro-service minio mot-de-passe mqtt multi-cloud médecine métrique n8n network newsletter nodejs nodeport notebook notifications nrtsearch null object-storage observability observabilité opa opendata openhab openmetrics openshit openstack openweb opnsense over-engineering packaging pandas parquet partiql password persistent-volume-claim pico pipenv pivot pod portainer portworx prediction prescience production promql prophet prévision psp ptyhon publicité pubsub pulsar push pyenv pérénnité qualité quay queue quic ram rambleed raml react readme recaptcha recherche redistimeseries reindex reinvent reliability remote-execution repository responsive retention-policy revocation revue-de-code rexec rgpd rhel rkt rolespec root rpo rto rust rwd résultat safe-harbor sarima scalabilité scanner schema scp sdk search select serverless-architecture service service-account service-worker setuptools sftp sha1 shard shard-duration shard-group sharding shell shipyard sidecar singer souveraineté-numérique spectre spinnaker spécifications sqlite sri ssh-agent ssl stabilité stash statistique storage sudo superset suse sympa sysdig syslog-ng sérénité task template terracost terrascan test-unitaire tidb tiers time timecale timer timestream tinygo training transformation travail trésorerie tsfr tsl ubuntu unikernel unit ux velero vendredi victoria-metrics vie-privée virtualbox virtualisation vm vnc volume voxxeddays vpc wasm web wireguard workflow yaml yield yq yubikey