Ansible - einfaches Playbook-Beispiel: NTP-Daemon chrony installieren und konfigurieren

Bild: Ansible Logo

Im Eingangskapitel Grundlagen haben wir uns mit der Installation bereits befasst. Auch haben wir uns schon in den beiden Kapiteln Playbooks und YAML - was ist das? eingehend mit den Hintergrundinformationen beschäftigt, so dass wir uns nun mit unsere Playbooks beschäftigen können.

In folgendem Beispiel Nummer fünf wollen wir auf unseren CentOS 8-Hosts den NTP-Deamon chrony installieren und auch entsprechend als Client konfigurieren.

Das Script legen wir wie auch schon bei den anderen Beispielen zuvor im Verzeichnis ~/ansible an

 $ vim 05_chrony.yml
05_chrony.yml
---
- hosts: centos8
  become: true
  vars:
    sudoers: ansible
    config_file: /etc/chrony.conf
    # chronyd client config-options
    chrony_pool: "server time.dmz.nausch.org iburst"
    chrony_stratumweight: "stratumweight 0"
    chrony_makestep: "makestep 10 3"
 
  tasks:
    - name: Install chrony ntp Deamon
      dnf: 
      #https://docs.ansible.com/ansible/latest/modules/dnf_module.html
        name: chrony
        state: latest
 
    - name: Check if /etc/chrony.orig does exists
      stat:
      #https://docs.ansible.com/ansible/latest/modules/stat_module.html
        path: /etc/chrony.conf.orig
      register: stat_result
 
    - name: Make a copy of /etc/chrony.conf as /etc/chrony.conf.orig  
      copy:
      #https://docs.ansible.com/ansible/latest/modules/copy_module.html
        remote_src: yes
        src: /etc/chrony.conf
        dest: /etc/chrony.conf.orig
      when: stat_result.stat.exists == False
 
    - name: Copy template config-file in place
      template:
      #https://docs.ansible.com/ansible/latest/modules/template_module.html        
        src: templates/CentOS8/chrony-client.conf.j2 
        dest: "{{ config_file }}"
 
    - name: Make sure Chrony is started up
      service: 
      #https://docs.ansible.com/ansible/latest/modules/service_module.html
        name: chronyd 
        state: started 
        enabled: yes
...

Die Konfigurationsdatei unseres chrony-Daemon werden wir im Arbeitsbereich unserer ansible-Umgebung auf dem Admin-Rechner/-Server in einem eigenen Verzeichnis vorhalten. Diese Verzeichnis erstellen wir uns nun noch.

 $ mkdir -p ~/ansible/templates/CentOS8/

Ansible nutzt die Jinja2 Template Engine zum abgleich der verwendeten Variablen in einem Playbook. Wir werden also unsere Konfigurationsdatei entsprechend präparieren und dort ablegen. Als Datei-Extension verwenden wir hier .j2, um dies optisch abzutrennen. Wir könnten auch andere Datei-Extension verwenden, da Ansible selbst nur den Inhalt bzw. die Formatierung der Variablen interprätiert.

 $ vim ~/ansible/templates/CentOS8/chrony-client.conf.j2
~/ansible/templates/CentOS8/chrony-client.conf.j2
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
{{ chrony_pool }}
 
# Ignore stratum in source selection
{{ chrony_stratumweight }}
 
# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift
 
# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3
 
# Enable kernel synchronization of the real-time clock (RTC).
rtcsync
 
# In first three updates step the system clock instead of slew
# if the adjustment is larger than 10 seconds.
{{ chrony_makestep }}
 
# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *
 
# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2
 
# Allow NTP client access from local network.
#allow 192.168.0.0/16
 
# Serve time even if not synchronized to a time source.
#local stratum 10
 
# Specify file containing keys for NTP authentication.
keyfile /etc/chrony.keys
 
# Get TAI-UTC offset and leap seconds from the system tz database.
leapsectz right/UTC
 
# Specify directory for log files.
logdir /var/log/chrony
 
# Select which information is logged.
#log measurements statistics tracking

Die drei Konfigurationsoptionen, die wir für unsere chrony-client Konfiguration später setzen und ggf. verändern wollen haben wir hier mit einer Variable belegt:

  • {{ chrony_pool }} : Server von dem bzw. denen wir später die Zeit beziehen wollen.
  • {{ chrony_stratumweight }} : Ignorieren der stratum Bewertung, da wir hier nur einen Zielhost zur Zeit befragen
  • {{ chrony_makestep }} : Definition wie bei den ersten Aktualisierungsschritten zu verfahren ist.

Dieses Beispiel zeigt sehr schlüssig, dass das „Ver-template'n“ einer Konfigirationsdatei nur bedingt geeignet ist, komplexe Daemon zu konfigurieren. Ein Daemon wie chrony wie in diesem Beispiel mit drei Optionen mag noch handelbar sein, aber z.B. einen Postfix-MTA1) so konfigurieren zu wollen, kann dann mit mehreren Hunderten Optionen schnell zu einem nervenaufreibenden Unterfangen ausarten!

Im Playbook greifen wir auf folgende Ansible-Module zurück:

  • dnf zum Installieren des Paketes
  • stat und copy zum Sichern der originalen Konfigurationsdatei.
  • template zur Konfiguration unseres Daemon
  • service zum (automatischen) Starten (beim Systemstart des Hosts)).

In unserem Playbook werden am Anfang den entsprechenden Variablen ihre werte zugewiesen. Im Anschluss daran werden fünft tasks definiert:

  1. Aufgabe: Installation des chrony NTP-Daemon
  2. Aufgabe: Überprüfen ob von der Konfigurationsdatei, die das RPM-Paket mitbrachte schon eine Sicherungskopie erstellt wurde.
  3. Aufgabe: Sofern bei der Prüfung in Aufgabe 2 noch keine Sicherungskopie erstellt wurde, wird eine Sicherungsopie erstellt.
  4. Aufgabe: Konfigurieren unseres chrony-Daemon
  5. Aufgabe: Starten des chrony-Daemon und aktivieren des automatischen Starts beim Starten des Hosts

Zum Kopieren der unterschiedlichen Dateien rufen wir nun unser Playbook wie folgt auf:

 $ ansible-playbook -v 05_chrony.yml 

Using /etc/ansible/ansible.cfg as config file
BECOME password: 

PLAY [centos8] *************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************
ok: [www7.dmz.nausch.org]
ok: [www8.dmz.nausch.org]
TASK [Install chrony ntp Deamon] ******************************************************************************************************* changed: [www8.dmz.nausch.org] => {"changed": true, "msg": "", "rc": 0, "results": ["Installed: chrony", "Installed: chrony-3.3-3.el8.x86_64"]}
TASK [Check if /etc/chrony.orig does exists] ******************************************************************************************* ok: [www8.dmz.nausch.org] => {"changed": false, "stat": {"exists": false}}
TASK [Make a copy of /etc/chrony.conf as /etc/chrony.conf.orig] ************************************************************************ changed: [www8.dmz.nausch.org] => {"changed": true, "checksum": "89175e7c294dedf12bd473a952014e2cefd5766d", "dest": "/etc/chrony.conf.orig", "gid": 0, "group": "root", "md5sum": "97078948a9e2c1b99ab3e38d26a3311d", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 1085, "src": "/etc/chrony.conf", "state": "file", "uid": 0}
TASK [Copy template config-file in place] ********************************************************************************************** changed: [www8.dmz.nausch.org] => {"changed": true, "checksum": "37539ecdd11393937e5596894db41a02c6121c5f", "dest": "/etc/chrony.conf", "gid": 0, "group": "root", "md5sum": "adde7eeb1766f7f83bd3fba6cc30ec23", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 1265, "src": "/home/ansible/.ansible/tmp/ansible-tmp-1578323551.4891849-132640554634531/source", "state": "file", "uid": 0}
TASK [Make sure Chrony is started up] ************************************************************************************************** changed: [www8.dmz.nausch.org] => {"changed": true, "enabled": true, "name": "chronyd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "sysinit.target system.slice -.mount systemd-tmpfiles-setup.service sntp.service ntpdate.service tmp.mount systemd-journald.socket ntpd.service basic.target", "AllowIsolate": "no", "AmbientCapabilities": "", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "multi-user.target shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "[not set]", "CPUUsageNSec": "[not set]", "CPUWeight": "[not set]", "CacheDirectoryMode": "0755", "CanIsolate": "no", "CanReload": "no", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend", "CollectMode": "inactive", "ConditionResult": "no", "ConditionTimestampMonotonic": "0", "ConfigurationDirectoryMode": "0755", "Conflicts": "systemd-timesyncd.service shutdown.target ntpd.service", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "NTP client/server", "DevicePolicy": "auto", "Documentation": "man:chronyd(8) man:chrony.conf(5)", "DynamicUser": "no", "EnvironmentFiles": "/etc/sysconfig/chronyd (ignore_errors=yes)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecStart": "{ path=/usr/sbin/chronyd ; argv[]=/usr/sbin/chronyd $OPTIONS ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStartPost": "{ path=/usr/libexec/chrony-helper ; argv[]=/usr/libexec/chrony-helper update-daemon ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/chronyd.service", "GID": "[not set]", "GuessMainPID": "yes", "IOAccounting": "no", "IOSchedulingClass": "0", "IOSchedulingPriority": "0", "IOWeight": "[not set]", "IPAccounting": "no", "IPEgressBytes": "18446744073709551615", "IPEgressPackets": "18446744073709551615", "IPIngressBytes": "18446744073709551615", "IPIngressPackets": "18446744073709551615", "Id": "chronyd.service", "IgnoreOnIsolate": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobRunningTimeoutUSec": "infinity", "JobTimeoutAction": "none", "JobTimeoutUSec": "infinity", "KeyringMode": "private", "KillMode": "control-group", "KillSignal": "15", "LimitAS": "infinity", "LimitASSoft": "infinity", "LimitCORE": "infinity", "LimitCORESoft": "infinity", "LimitCPU": "infinity", "LimitCPUSoft": "infinity", "LimitDATA": "infinity", "LimitDATASoft": "infinity", "LimitFSIZE": "infinity", "LimitFSIZESoft": "infinity", "LimitLOCKS": "infinity", "LimitLOCKSSoft": "infinity", "LimitMEMLOCK": "16777216", "LimitMEMLOCKSoft": "16777216", "LimitMSGQUEUE": "819200", "LimitMSGQUEUESoft": "819200", "LimitNICE": "0", "LimitNICESoft": "0", "LimitNOFILE": "4096", "LimitNOFILESoft": "1024", "LimitNPROC": "31132", "LimitNPROCSoft": "31132", "LimitRSS": "infinity", "LimitRSSSoft": "infinity", "LimitRTPRIO": "0", "LimitRTPRIOSoft": "0", "LimitRTTIME": "infinity", "LimitRTTIMESoft": "infinity", "LimitSIGPENDING": "31132", "LimitSIGPENDINGSoft": "31132", "LimitSTACK": "infinity", "LimitSTACKSoft": "8388608", "LoadState": "loaded", "LockPersonality": "no", "LogLevelMax": "-1", "LogsDirectoryMode": "0755", "MainPID": "0", "MemoryAccounting": "yes", "MemoryCurrent": "[not set]", "MemoryDenyWriteExecute": "no", "MemoryHigh": "infinity", "MemoryLimit": "infinity", "MemoryLow": "0", "MemoryMax": "infinity", "MemorySwapMax": "infinity", "MountAPIVFS": "no", "MountFlags": "", "NFileDescriptorStore": "0", "NRestarts": "0", "Names": "chronyd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "none", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PIDFile": "/var/run/chrony/chronyd.pid", "PermissionsStartOnly": "no", "Perpetual": "no", "PrivateDevices": "no", "PrivateMounts": "no", "PrivateNetwork": "no", "PrivateTmp": "yes", "PrivateUsers": "no", "ProtectControlGroups": "no", "ProtectHome": "yes", "ProtectKernelModules": "no", "ProtectKernelTunables": "no", "ProtectSystem": "full", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "RemoveIPC": "no", "Requires": "sysinit.target -.mount system.slice", "RequiresMountsFor": "/var/tmp", "Restart": "no", "RestartUSec": "100ms", "RestrictNamespaces": "no", "RestrictRealtime": "no", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "RuntimeDirectoryPreserve": "no", "RuntimeMaxUSec": "infinity", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardInputData": "", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitIntervalUSec": "10s", "StartupBlockIOWeight": "[not set]", "StartupCPUShares": "[not set]", "StartupCPUWeight": "[not set]", "StartupIOWeight": "[not set]", "StateChangeTimestampMonotonic": "0", "StateDirectoryMode": "0755", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SuccessAction": "none", "SyslogFacility": "3", "SyslogLevel": "6", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "yes", "TasksCurrent": "[not set]", "TasksMax": "26213", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "forking", "UID": "[not set]", "UMask": "0022", "UnitFilePreset": "enabled", "UnitFileState": "enabled", "UtmpMode": "init", "WantedBy": "multi-user.target", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
PLAY RECAP *************************************************************************************************************************************** www8.dmz.nausch.org : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Auf dem Zielhost finden wir nun die Sicherungskopie der originalen chrony.conf aus dem RPM-Paket.

 # ll /etc/chrony.conf*
-rw-r--r--. 1 root root 1265 Jan  6 16:12 /etc/chrony.conf
-rw-r--r--. 1 root root 1085 Apr  4  2018 /etc/chrony.conf.orig

Der Dienst chrony.conf wurde entsprechend gestartet und läuft:

 # systemctl status chronyd.service

chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-01-06 16:12:34 CET; 47s ago
     Docs: man:chronyd(8)
           man:chrony.conf(5)
  Process: 10697 ExecStartPost=/usr/libexec/chrony-helper update-daemon (code=exited, status=0/SUCCESS)
  Process: 10693 ExecStart=/usr/sbin/chronyd $OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 10695 (chronyd)
    Tasks: 1 (limit: 26213)
   Memory: 1.1M
   CGroup: /system.slice/chronyd.service
           └─10695 /usr/sbin/chronyd

Jan 06 16:12:34 vml000090.dmz.nausch.org systemd[1]: Starting NTP client/server...
Jan 06 16:12:34 vml000090.dmz.nausch.org chronyd[10695]: chronyd version 3.3 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
Jan 06 16:12:34 vml000090.dmz.nausch.org chronyd[10695]: Initial frequency 10.454 ppm
Jan 06 16:12:34 vml000090.dmz.nausch.org chronyd[10695]: Using right/UTC timezone to obtain leap second data

Beim Starten des Servers/Hosts wird der chronyd-Daemon auch automatisch gestartet. Dies können wir wie folgt überprüfen:

 # systemctl is-enabled chronyd.service
enabled

Links


1)
MailTransportAgent
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • linux/ansible/playbook_example_05.txt
  • Zuletzt geändert: 14.09.2022 14:31.
  • von django