CérénIT

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.

Le Blog

Nous partageons ici notre veille et nos réflexions

Nuage de tags

docker kubernetes elasticsearch postgres kafka ansible grafana traefik python aws influxdb tick mysql sécurité cloud redis chronograf swarm test cassandra hashicorp microservice ovh serverless spark terraform angularjs cncf confluent container graphql javascript log opensource rancher stream timescaledb windows api architecture arm csp devops dns docker-compose documentation elastic hpkp iac ingress java kapacitor kibana lambda lean licence microsoft nginx npm orientdb rest rethinkdb reverse-proxy service-mesh sql ssh timeseries agile apm azure bash big-data bilan certificat cli cluster continous-delivery cookie cérénit fluxlang gcp gdpr git grav hsts https hypriot istio json ksql kubedb lets-encrypt linux load-balancer machine-learning mobile monitoring perspective php pip prometheus redhat replication rook rsyslog s3 scale scaleway solr systemd telegraf vault virtualenv vue.js wagtail yarn accessibilité akka alerte alibaba amazon-emr anonymisation ara automatisation bastion beam beat bounded-context branche brigade browser buildkit cdc cert-manager certificats checklist chrome cloud-init cloud-native cloud-storage clusterip cockroachdb code codeurs-en-seine confluence consul containerd continous-integration coreos cors cqrs crash cron crontab csrf css curl d3.js daemonset dashboard data-pipelining dataviz date ddd debezium debian deployment desktop devoxx distributed-systems dive docker-app docker-registry documentdb dokcer draft drop-in ebs ec2 edge elassandra electron elk engineering etcd event-sourcing facebook falcor feature-policy feed filebeat firebase firefox fish flash flask fleet flink fluentd flux foundation framework frontend fsync fullstack github glacier glowroot google google-cloud-next gpu grid géospatial hacker hadoop hdfs header helm html html5 http http/3 hue ia iaac ibm immutable incident index influxace influxcloud influxdata influxdays infrastructure-as-code ingénierie inspec jq jquery jwt k3d k3s k8s k9s kubeadm kubecon laravel liste-de-diffusion loadbalancer logstash logstatsh loi mailing-list management mariadb message metallb micro-service molecule mongodb mot-de-passe multi-cloud médecine newsletter nodeport nomad nosql null openebs openmetrics openshit openssh openweb operator over-engineering packaging pandas password performance persistent-volume-claim pipenv portainer publicité push pyenv queue quic raml react reaper recaptcha recherche reindex reinvent responsive revocation revue-de-code rkt rolespec root rpi rpo rto runc rwd search secrets select serverless-architecture service-worker sha1 sharding shell shipyard société spinnaker sre sri ssh-agent ssl statistique superset sympa syslog-ng test-unitaire tidb tiers timer timezone tls training travail ubuntu unikernel unit ux vie-privée virtualbox vitess vm vnc volume voxxeddays vpc vscode

Syndication

Atom