NTP cluster configuration using chrony
- Jinja 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .woodpecker | ||
| defaults | ||
| handlers | ||
| meta | ||
| roles | ||
| tasks | ||
| templates | ||
| .ansible-lint | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .markdownlint-cli2.jsonc | ||
| .sops.yaml | ||
| .yamllint | ||
| ansible.cfg | ||
| playbook.yaml | ||
| readme.md | ||
| renovate.json | ||
Ansible Role: NTP Cluster
Installs and configures a Chrony NTP cluster on Alpine Linux. Each node syncs with the upstream servers, peers with the other cluster members, serves time to the allowed subnets and falls back to orphan mode when it is not synced.
Requirements
| Operating System | Version | Notes |
|---|---|---|
| Alpine Linux | 3.x | Uses apk and the service module (OpenRC), root required |
Dependencies
None (dependencies: []). The playbook installs this role (ntp_cluster) from roles/requirements.yml.
Variables
| Variable | Required | Default | Description |
|---|---|---|---|
ntp_upstream_servers |
No | time1.ams-ix.net, time2.ams-ix.net, time.cloudflare.com |
Upstream NTP servers |
ntp_cluster_peers |
No | [] |
All cluster members (hostname and ip), including the host itself |
ntp_allowed_subnets |
No | [] |
Subnets allowed to query this server |
ntp_local_stratum |
No | "10" |
Stratum served when not synced (orphan mode) |
ntp_driftfile_path |
No | "/var/lib/chrony/drift" |
Path of the chrony driftfile |
ntp_config_path |
No | "/etc/chrony/chrony.conf" |
Path of the chrony configuration file |
ntp_makestep_threshold |
No | "1" |
Makestep threshold in seconds |
ntp_makestep_limit |
No | "3" |
Number of clock updates in which makestep may be used |
ntp_maxupdateskew |
No | "100" |
Maximum update skew (ppm) for faster syncing |
Example
ntp_upstream_servers:
- "time1.ams-ix.net"
- "time2.ams-ix.net"
- "time.cloudflare.com"
ntp_cluster_peers:
- hostname: "ntp01.example.internal"
ip: "10.0.0.1"
- hostname: "ntp02.example.internal"
ip: "10.0.0.2"
- hostname: "ntp03.example.internal"
ip: "10.0.0.3"
ntp_allowed_subnets:
- "10.0.0.0/24"
- "192.168.1.0/24"
ntp_local_stratum: "10"
Usage
Run playbook.yaml via Semaphore. The playbook first runs ansible-galaxy install -f -r roles/requirements.yml on
the controller and then includes the ntp_cluster role on all hosts, one host at a time (serial: 1).
Operational notes
- Installs
chrony, then enables and starts thechronydservice. - The peers are written to a block in
/etc/hosts(existing file only, it is not created) so they resolve without DNS. Inchrony.confevery peer is added as aserverline, except the host itself (matched on inventory name, hostname, FQDN or one of its IPv4 addresses). - Upstream servers and peers use
iburst maxpoll 6.local stratumis set withorphan, andrtcsyncis enabled. - After a configuration change chronyd is restarted and the role runs
chronyc waitsync 30 0.01. A failed wait does not fail the play.