EQVPS
DashboardAan de slag

Taken plannen op een VPS met cron en systemd-timers

Draai back-ups, opruimtaken en scripts volgens schema. Cron in vijf minuten met de drie valkuilen die taken stilletjes breken, daarna systemd-timers voor logs, inhalen na uitval en exacte tijden. Elk gedrag hieronder is getest op een verse Ubuntu 24.04-server.

Een server verdient zich terug door te werken terwijl jij slaapt: back-ups, logrotatie, certificaatvernieuwing, een rapport om negen uur. Linux heeft daar twee planners voor. Cron is veertig jaar oud en past op één regel. Systemd-timers kosten twee kleine bestanden en geven daarvoor logs, inhalen na uitval en exacte tijden. Deze handleiding behandelt beide op Ubuntu 24.04, met elk gedrag gecontroleerd op een verse server van ons image, inclusief de drie fouten waardoor een cron-taak zonder een woord faalt.

Je hebt een gebruiker met sudo nodig; de Ubuntu-installatiehandleiding maakt er een aan.

1. Cron in vijf minuten

Cron is geïnstalleerd en draait op onze Ubuntu- en Debian-images. Elke gebruiker heeft een takentabel; bewerk de jouwe met:

crontab -e

Elke regel bestaat uit vijf tijdvelden en een opdracht:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

Dat is: elke nacht om 03:30, elke 5 minuten, op werkdagen om 09:00 en één keer na elke boot. */5 betekent elke vijfde waarde, 1-5 een bereik, 1,15 een lijst. De tijdzone van de server geldt, UTC op onze images; stel de jouwe één keer in met de handleiding over hostnaam en tijdzone en cron volgt.

Wat er gedraaid heeft zie je met journalctl -u cron. Elke run logt de gebruiker en de opdracht, en daar duiken de drie valkuilen op.

Valkuil 1: de uitvoer verdwijnt. Cron mailt de uitvoer van een taak naar de gebruiker. Ons image heeft geen mailserver, dus in het journal stond (CRON) info (No MTA installed, discarding output) en was de uitvoer weg. Leid hem zelf om, zoals het eerste voorbeeld doet met >> /var/log/backup.log 2>&1.

Valkuil 2: het procentteken. In een crontab beëindigt % de opdracht en wordt de rest standaardinvoer. We planden date +%F > /tmp/today. Het journal toont wat cron echt draaide: CMD (date +). Er werd geen bestand geschreven en er kwam geen foutmelding bij ons aan. Schrijf \%, of zet de opdracht in een script en plan het script.

Valkuil 3: een andere omgeving. Cron draait taken met /bin/sh, niet bash, in je homemap en met een beperkte omgeving. Op Ubuntu 24.04 was het PATH beter dan zijn reputatie: het volledige systeempad inclusief /usr/local/bin en /snap/bin, voor root en voor een gewone gebruiker. Wat nog steeds ontbreekt is alles onder je homemap: ~/.local/bin, de node van nvm, pipx, cargo. Gebruik volledige paden in de taak of begin de regel met . $HOME/.profile;.

Taken die bij het systeem horen in plaats van bij een gebruiker gaan in /etc/cron.d/, als bestand met één extra veld, de gebruiker:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu draait ook alles in /etc/cron.hourly, cron.daily, cron.weekly en cron.monthly, om 17 minuten over elk uur, om 06:25, op zondag om 06:47 en op de 1e om 06:52. Zet daar een uitvoerbaar script neer en het draait met de rest mee.

2. Systemd-timers

Een timer bestaat uit twee units: een service die het werk doet en een timer die zegt wanneer. Maak eerst het script, dan de units.

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

Schakel de timer in, niet de service:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers toont de volgende run, hoe lang het nog duurt en de laatste run. Logs hoeven niet ingesteld te worden: journalctl -u backup.service bevat elke start, elk einde en elke regel uitvoer met tijdstempel. Om de taak meteen te draaien, sudo systemctl start backup.service; zo test je ook het script voordat je op het schema vertrouwt.

Kalendersyntaxis. OnCalendar lees je als weekdag jaar-maand-dag uur:minuut:seconde, met * voor elke waarde. Test een expressie voordat je hem gebruikt:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

Het toont de genormaliseerde vorm en de volgende data. Enkele expressies die we controleerden:

OnCalendarBetekenis
*-*-* 03:30Elke dag om 03:30
Mon..Fri *-*-* 09:00Werkdagen om 09:00
*:0/15Elke 15 minuten
weeklyMaandag om 00:00
*-*-01 04:00De 1e van elke maand om 04:00
*-*-* 03:00 Europe/Kyiv03:00 Kyiv-tijd; liep bij ons om 01:00 UTC

De drie instellingen die je moet kennen. Persistent=true slaat de laatste run op schijf op en haalt een run in die gemist is terwijl de server uit stond of de timer gestopt was. We stopten onze timer van elke twee minuten, wachtten tot een geplande run voorbij was en startten hem weer: de gemiste run vertrok in dezelfde seconde. Zonder Persistent wacht hij gewoon op het volgende moment.

AccuracySec is de verrassing. Systemd groepeert timers standaard binnen een venster van een minuut om wekmomenten te sparen, dus onze eerste run kwam om 07:42:18, niet om 07:42:00. Met AccuracySec=1s vielen de volgende runs op de seconde op 07:46:00 en 07:48:00. Zet het als de minuut telt; laat de standaard staan voor een nachtelijke back-up.

RandomizedDelaySec=10m doet bewust het omgekeerde: het spreidt de start over een venster zodat tien servers niet in dezelfde seconde dezelfde back-upopslag raken.

Voor een eenmalige taak zijn geen bestanden nodig:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

Dit maakt een tijdelijke timer die één keer afgaat en verdwijnt; tot dan toont systemctl list-timers hem.

3. Welke kies je

CronSystemd-timer
Instellen1 regel2 bestanden
LogsAlleen als je uitvoer omleidtjournalctl -u name.service
Gemiste run terwijl de server uit stondVerlorenDraait bij het opstarten met Persistent=true
Taak loopt nog bij de volgende tikEen tweede kopie startOvergeslagen tot de eerste klaar is
Exacte tijdOp de minuutOp de seconde met AccuracySec=1s
StatusGeenlist-timers, systemctl status

Gebruik cron voor een snelle regel die je over een jaar nog herkent. Gebruik een timer voor alles waarvan je het falen moet zien, dat niet mag overlappen of dat na een gemiste herstart toch moet draaien: back-ups, certificaatvernieuwing, database-opruiming. Kan een cron-taak overlappen, wikkel hem dan in: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, en de tweede kopie stopt meteen.

Beide planners starten een taak en houden dan op. Voor een programma dat dag en nacht moet draaien en na een crash terug moet komen, heb je een service nodig, geen schema; zie hoe je een systemd-service maakt en voor Windows hoe je een script 24/7 op Windows Server draait. Een goede eerste timer is die uit onze handleiding voor back-ups met restic; automatische beveiligingsupdates zijn een timer die Ubuntu al meelevert, apt-daily-upgrade.timer, een van de 17 op een verse server.

FAQ

Waarom werkt mijn taak in de terminal maar niet in cron?

Drie gebruikelijke redenen. Cron draait de taak met sh, niet bash, dus bash-only syntaxis faalt. Tools in je homemap, zoals nvm, pipx of cargo, staan niet in het PATH van cron, dus gebruik volledige paden. En elke % in de opdrachtregel beëindigt de opdracht: date +%F werd op onze server date +. Schrijf het als \% of zet de opdracht in een script.

Waar gaat de uitvoer van cron heen?

Standaard naar e-mail. Ons image heeft geen mailserver, dus cron logt 'No MTA installed, discarding output' en de uitvoer is weg. Voeg >> /var/log/myjob.log 2>&1 aan de taak toe, of stap over op een systemd-timer, waarvan de uitvoer vanzelf in het journal belandt.

Wat is het voordeel van een systemd-timer boven cron?

Logs in journalctl, geen tweede kopie van een taak die nog loopt, inhalen met Persistent=true van runs die gemist zijn terwijl de server uit stond, en een statusregel met de volgende en laatste run. Cron wint op beknoptheid: één regel in plaats van twee bestanden.

Mijn timer ging 18 seconden te laat af. Waarom?

Standaard groepeert systemd timers binnen een venster van een minuut om wekmomenten te sparen; dat is de instelling AccuracySec. Onze timer van elke twee minuten ging om 07:42:18 af in plaats van 07:42:00. Met AccuracySec=1s liep hij precies om 07:46:00. Zet hem als de exacte minuut telt.

Welke tijdzone gebruiken cron en timers?

Die van de server, UTC op onze images. Stel hem één keer in met timedatectl, zie onze handleiding over hostnaam en tijdzone, en cron en timers volgen. Een timer kan ook een eigen zone hebben: OnCalendar=*-*-* 03:00 Europe/Kyiv liep in onze test om 01:00 UTC.

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.