Learn › RHCSA (EX200) › Deploy, Configure, Maintain
chronyc - a hands-on Linux lab on a real virtual machine.
Keep a RHEL 10 machine's clock locked to real time and prove it. Read the overview and set the zone with timedatectl, point chrony at a time source with server/pool lines in /etc/chrony.conf, apply the edit with systemctl restart chronyd, then verify with chronyc sources (the current-sync and + acceptable markers, plus stratum) and chronyc tracking (reference server, stratum, offset from true time). Serves EX200 deploy-configure: configure time service clients.
A monitoring alert fires at 02:14. You open the log to see what happened, and the timestamps make no sense: entries from the future, gaps that never existed, a login that appears to happen before the request that triggered it. Nothing is corrupted. The machine's clock has simply drifted, and every log line, every certificate check, every scheduled job is now stamped with the wrong time. On a network of servers, one clock that wanders quietly poisons the whole story.
Keeping the clock right is not optional housekeeping. Kerberos authentication rejects a login if the client and server clocks disagree by more than a few minutes. TLS certificates look expired or not-yet-valid. Scheduled jobs fire at the wrong moment. This lesson is the set of commands that keep a RHEL 10 machine's clock locked to real time, and that prove it is locked. It is a named RHCSA objective, and the fix is almost always four commands you can run in under a minute.
The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches. The outputs are from a real RHEL 10 machine (AlmaLinux 10.2) reached live. What is stable everywhere is the SHAPE of each command's output. timedatectl prints a four-line clock overview. chronyc sources prints one row per time server with a two-character marker up front. chronyc tracking prints a labelled block. The exact NTP servers, offsets, stratum numbers, and timestamps depend on the machine and the moment, so treat those specific values as illustrative.
Every computer has a small hardware clock that ticks on its own, and small clocks drift. Left alone, a server can gain or lose several seconds a day. NTP, the Network Time Protocol, is the internet's answer: your machine asks a set of accurate time servers what time it really is, then nudges its own clock to match, gently and continuously.
On RHEL 10, the program that speaks NTP is chrony. It runs as a background service called chronyd (the d is for daemon, a program that runs quietly in the background). You almost never talk to the daemon directly. Instead you use chronyc, the chrony client, to ask it questions: which servers are we using, how far off are we, is the clock in sync. Think of chronyd as the technician always adjusting the clock, and chronyc as the clipboard you use to read the current status.
You reach for these commands in two situations. The first is a check: something time-related is misbehaving (a failed login, a cron job that ran late, a certificate error) and you need to know whether the clock is the culprit. The second is a setup task: the exam or the job hands you a specific time server to point at, and you must configure the machine to use it and prove that it did.
Both come down to the same short loop. Look at the overview with timedatectl. If time is not syncing, point chrony at the right server in its config file, restart the service, then confirm with chronyc sources and chronyc tracking. Four commands, one clear before-and-after.
Start every time investigation with timedatectl. Run with no arguments, it prints a compact overview of the system clock. Four things: what time the machine thinks it is, which time zone it is set to, whether the clock is synchronized to a time source, and whether the NTP service is running. It is the single fastest way to answer is this machine's time healthy.
Before you run it, know the two lines that matter most: System clock synchronized should read yes, and NTP service should read active. Check the clock:
timedatectl
prompt: [root@servera ~]# answer: timedatectl output: Local time: Sun 2026-07-05 21:16:42 UTC Time zone: UTC (UTC, +0000) System clock synchronized: yes NTP service: active hint: The overview command is one word: timedatectl, with no arguments.
Four lines, and you read them top to bottom. Local time is what the machine currently believes the time and date are. Time zone is the region it is set to, here UTC, with its offset from UTC in parentheses. System clock synchronized: yes is the one you care about most: it means the clock has locked onto a time source and is being kept accurate. NTP service: active means the chrony daemon is running and doing that work. If those bottom two ever read no and inactive, the clock is adrift and nothing is correcting it.
Your Local time will of course show a different moment than the one captured here, and your Time zone may not be UTC. Those two lines are expected to differ per machine and per run. The lines to read as pass or fail are the bottom two: System clock synchronized and NTP service.
timedatectl does more than report. It also sets the time zone, which is a common exam ask: put this machine on a named region's clock. The form is timedatectl set-timezone <Zone>, where the zone is a name like America/New_York or Europe/London from the standard time-zone database. You do not edit a file for this; the one command does it.
A useful companion is timedatectl list-timezones, which prints every valid zone name so you can find the exact spelling. Setting a zone produces no output, which is success. Run the overview again afterward and the Time zone line reflects the change.
timedatectl set-timezone America/New_York
prompt: [root@servera ~]# answer: timedatectl set-timezone America/New_York output: hint: The subcommand is set-timezone, then a Zone/City name: timedatectl set-timezone America/New_York
No output means it worked; timedatectl set-timezone is silent on success. The zone name must be an exact match from the time-zone database, in Region/City form with the capitalization shown, or the command errors with Failed to set time zone. When you are unsure of the spelling, run timedatectl list-timezones and search that list. After setting, timedatectl with no arguments will show the new zone on the Time zone line, and the Local time will jump to reflect it.
Chrony learns which time servers to use from one config file: /etc/chrony.conf. Inside it, two directive words matter. A server line names one specific time server to use. A pool line names a group that resolves to several servers at once, so chrony can pick healthy ones and drop bad ones. A fresh RHEL 10 install ships with a pool line pointing at a default set.
When a task says use this time server, you add or edit a server line in /etc/chrony.conf. A typical line looks like server time.example.com iburst, where iburst is an option that tells chrony to sync quickly on startup instead of waiting minutes for the first measurement. You edit the file with any editor; the change does nothing until you restart the service in the next step.
Both server and pool lines can carry the iburst option, and on the exam you almost always want it. Without iburst, chrony spaces its first few time measurements minutes apart, so a freshly restarted daemon can take a long while to report as synchronized. With iburst, it fires a quick burst of requests at startup and locks on in seconds. When you add a server line, server host iburst is the shape to reach for.
Editing /etc/chrony.conf changes the file on disk, but the running daemon still holds the old settings in memory. To make it read the new file, you restart the service with systemctl restart chronyd. That is the service name: chronyd, the daemon, not chrony. After the restart, the daemon reconnects using whatever server and pool lines the file now contains.
Restart is silent on success, like most systemctl actions. Restart the chrony service so it picks up the edited config:
systemctl restart chronyd
prompt: [root@servera ~]# answer: systemctl restart chronyd output: hint: The service is named chronyd (with the d). Restart it: systemctl restart chronyd
Silence again means success. The daemon stopped, re-read /etc/chrony.conf, and started fresh against the servers you configured. One habit worth building: after any change that must survive a reboot, confirm the service is set to start at boot with systemctl is-enabled chronyd. On RHEL 10 chronyd is enabled by default, but the exam rewards the engineer who verifies rather than assumes. With the service restarted, you are ready to prove it is actually talking to a time source.
A frequent exam trap: you edit /etc/chrony.conf, save it, and move on without restarting chronyd. The file is correct on disk, but the running daemon never re-read it, so chronyc sources still lists the old servers and the task fails its check. The rule is simple and absolute: any time you touch /etc/chrony.conf, restart the service. Edit, then systemctl restart chronyd, then verify. Skipping the middle step is the most common way to lose this objective.
Now the payoff. chronyc sources asks the running daemon which time servers it is talking to and how each one is behaving. It prints one row per source, and the two characters at the very start of each row are the whole story. That marker is a pair: the first character describes what the source is, and the second describes its current state.
Two states you must recognize. A * in the second position marks the current synchronization source: the server your clock is actually being steered by right now. A + marks an acceptable source: a good server that chrony is combining or holding in reserve. Look at the sources:
chronyc sources
prompt: [root@servera ~]# answer: chronyc sources output: MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^+ chi2.us.ntp.li 2 6 377 18 -1408us[-1408us] +/- 27ms ^* ip74-208-14-149.pbiaas.c> 1 6 377 18 +1162us[+1172us] +/- 29ms hint: The client is chronyc and the subcommand is sources: chronyc sources
Read the leading marker first. On the second row, ^* means this is the current sync source. The ^ says it is a server (as opposed to a peer), and the * says the clock is being steered by it right now. On the first row, ^+ means an acceptable server, one chrony trusts and keeps as a combined or backup source. The Stratum column tells you how many hops that server is from a reference clock. The ^* source shows Stratum 1, meaning it sits directly on a reference clock, while the ^+ source is Stratum 2, one hop further out. Lower stratum is closer to true time. Reach shown as 377 (octal for eight successful polls in a row) means the source has answered every recent request. The Last sample column is the measured offset between your clock and that source.
The server names, the stratum numbers, the offsets, and the Reach values all depend on which time servers your machine reaches and the moment you run the command. So your rows will look different from these. What does NOT change is how you read them: find the row whose second marker character is *, and that is the source steering your clock. If no row shows a *, the machine is not yet synchronized to anything.
chronyc sources shows the servers; chronyc tracking shows the result: how well your clock is actually doing against real time. It prints a labelled block, and three lines carry the verdict. Reference ID names the exact server your clock is currently locked to. Stratum is your machine's own distance from a reference clock, always one more than your source's stratum. System time is the headline number: how far your clock is from true NTP time, and in which direction.
chronyc tracking
prompt: [root@servera ~]# answer: chronyc tracking output: Reference ID : 4AD00E95 (ip74-208-14-149.pbiaas.com) Stratum : 2 System time : 0.000983743 seconds slow of NTP time hint: Same client, different subcommand: chronyc tracking
This is the health report in three numbers. Reference ID names the server steering the clock, here ip74-208-14-149.pbiaas.com, the same host that showed ^* in chronyc sources. Stratum : 2 is your machine's own stratum: your ^* source was Stratum 1, so you sit one hop further out at 2. System time : 0.000983743 seconds slow of NTP time is the payoff line: your clock is off by under a thousandth of a second, and the word slow tells you the direction. A sub-second, and especially a sub-millisecond, offset means chrony is doing its job. A large or growing offset, or a Reference ID of 00000000, means the clock is not locked to anything.
The Reference ID, the Stratum, and the exact System time offset all vary per machine and per moment, so yours will read different numbers. The pattern to trust is this. Reference ID should name a real host, not 00000000. Stratum should be a small number like 2 or 3. System time should be a small fraction of a second. Those three together are the passing report card.
Scaffolding off. No command is printed this time. You have every piece you need.
You have just pointed a machine at a new time server in /etc/chrony.conf and restarted the service. A task now tells you to prove the clock is actually locked to that source and to read back how far off it currently is. You do not want the list of every server (that is sources); you want the single verdict: which server is steering the clock, this machine's stratum, and the current offset from real time. Which chrony client subcommand prints that labelled block?
prompt: [root@servera ~]# answer: chronyc tracking output: Reference ID : 4AD00E95 (ip74-208-14-149.pbiaas.com) Stratum : 2 System time : 0.000983743 seconds slow of NTP time hint: It is the chrony client, and the subcommand for the verdict is tracking, not sources: chronyc tracking
chronyc tracking prints the verdict block: Reference ID names the steering server, Stratum is this machine's distance from a reference clock, and System time is the current offset from true time. That is the confirm step for every time-sync task. chronyc sources would have listed every server and their markers, but only tracking gives you the one-line answer to is my clock locked and how far off is it. When a task says configure a time server and verify, this is the command that earns the verify.
You earned this cheat sheet. Every row is a command you just ran or a form you built:
The one thing to burn in for the exam: after you edit /etc/chrony.conf, you MUST systemctl restart chronyd. Then verify with chronyc sources and chronyc tracking. Edit, restart, verify. The marker to find in sources is the *; the report card is tracking.
The full exam pattern for a time-client task is always the same five moves. First timedatectl to see the starting state. Second, add or edit a server host iburst line in /etc/chrony.conf. Third, systemctl restart chronyd to apply it. Fourth, chronyc sources and look for the ^* row on your server. Fifth, chronyc tracking and confirm a small System time offset and a real Reference ID. If a zone was also asked for, timedatectl set-timezone handles that in one line.
The practice terminal has walked you through the whole loop. You used timedatectl to read the clock overview and set the zone. You used the server and pool lines in /etc/chrony.conf to choose a time source. You used systemctl restart chronyd to apply an edit. You used chronyc sources and chronyc tracking to prove the clock is locked and measure how close it is. Every one of those you typed yourself.
The deploy-configure module mission, Operation Rollout, is where you run these against a real RHEL 10 machine. A full VM boots for you, with a live chrony daemon and a real clock to steer. The mission hands you objectives that use exactly what you practiced here: set the machine's time zone, point chrony at a named server, restart the service, and prove the clock is synchronized. One difference from this lesson: the mission shows no commands. You read the objective, recall the timedatectl and chronyc forms, and type them. That recall is what makes it stick on exam day.
Finish the other deploy-configure lessons, then go lock a real machine's clock to true time.
Practice chrony: Time Synchronization in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.