Ad-hoc-Befehle sind ein Kernelement von Ansible und ermöglichen die sofortige Ausführung von Aufgaben, ohne dass diese für die spätere Verwendung gespeichert werden müssen. Dieser Artikel befasst sich im Detail mit den Ansible Ad-hoc-Befehlen.
Viele Aufgaben in Ansible erfordern kein separates Playbook. Stattdessen können Sie diese Aufgaben bequem mit einem Ansible Ad-hoc-Befehl erledigen. Es handelt sich um einzeilige Anweisungen zur Ausführung einer bestimmten Aktion auf einem Zielhost. Diese Befehle sind über den Pfad `/usr/bin/ansible` zugänglich.
Typische Aufgaben, die sich gut für Ad-hoc-Befehle eignen, sind das Überprüfen der Erreichbarkeit von Hosts mit einem Ping, das Kopieren von Dateien, das Neustarten von Servern oder die Installation von Softwarepaketen. Im Folgenden finden Sie eine Liste grundlegender Ansible Ad-hoc-Befehle, die Sie kennen sollten.
Grundlegende Befehle
Der nachfolgende Ad-hoc-Befehl verwendet das Ping-Modul, um alle in der Inventardatei aufgeführten Hosts zu überprüfen. Die Option `-m` kennzeichnet das zu verwendende Modul.
[email protected]:/home/wdzwdz# ansible all -m ping node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
Dieser Befehl verwendet das Setup-Modul, um Details zu einer Hostgruppe (hier „Client“) abzurufen, die in der Inventardatei `/etc/ansible/hosts` definiert ist.
[email protected]:/home/wdzwdz# ansible Client -m setup -a "filter=ansible_distribution*" node1 | SUCCESS => { "ansible_facts": { "ansible_distribution": "Ubuntu", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/os-release", "ansible_distribution_file_variety": "Debian", "ansible_distribution_major_version": "18", "ansible_distribution_release": "cosmic", "ansible_distribution_version": "18.10", "discovered_interpreter_python": "/usr/bin/python" }, "changed": false }
Um sich per SSH mit einem Passwort zu authentifizieren, verwenden Sie die Option `–ask-pass`. Nach der Befehlseingabe werden Sie zur Passworteingabe aufgefordert.
[email protected]:/home/wdzwdz# ansible Client -m ping --ask-pass SSH password: node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
Mit dieser Befehlszeile können Sie einen Ad-hoc-Befehl als Nicht-Root-Benutzer mit Root-Rechten ausführen. Die Option `–become` ermöglicht Root-Rechte und `-K` fordert das Passwort an.
[email protected]:/home/wdzwdz# ansible Client -m shell -a 'fdisk -l' -u wdzwdz --become -K BECOME password: node1 | CHANGED | rc=0 >> Disk /dev/loop0: 14.5 MiB, 15208448 bytes, 29704 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/loop2: 42.1 MiB, 44183552 bytes, 86296 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/loop3: 149.9 MiB, 157184000 bytes, 307000 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/loop5: 140.7 MiB, 147501056 bytes, 288088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/loop6: 151.2 MiB, 158584832 bytes, 309736 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/loop7: 14.8 MiB, 15458304 bytes, 30192 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/sda: 500 GiB, 536870912000 bytes, 1048576000 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xcef957f5 Device Boot Start End Sectors Size Id Type /dev/sda1 2048 462639103 462637056 220.6G 83 Linux /dev/sda2 * 462639104 464592895 1953792 954M 83 Linux /dev/sda3 464592896 482168831 17575936 8.4G 82 Linux swap / Solaris /dev/sda4 482168832 1048573951 566405120 270.1G 83 Linux
Mit der Option `-f` können Sie die Anzahl der gleichzeitig ausgeführten Prozesse (Forks) beim Neustart eines Systems festlegen.
[email protected]:/home/wdzwdz# ansible Client -a "/sbin/reboot" -f 1
Datei Übertragung
Mit dem folgenden Ansible Ad-hoc-Befehl wird eine Datei von einer Quelle zu einem Ziel auf einer in der Inventardatei definierten Gruppe von Hosts (Client) kopiert. Nach Eingabe des Passworts zeigt der Parameter „change“ den Wert „true“ an, was bedeutet, dass die Datei erfolgreich kopiert wurde.
[email protected]:/home/wdzwdz# ansible Client -m copy -a 'src=/home/wdzwdz/nginx.yml dest=/home/wdzwdz/Desktop/ owner=root mode=0644' -u root --become -K BECOME password: node1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "5631822866afd5f19b928edb3ba018385df22dd3", "dest": "/home/wdzwdz/Desktop/nginx.yml", "gid": 0, "group": "root", "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634", "mode": "0644", "owner": "root", "size": 280, "src": "/root/.ansible/tmp/ansible-tmp-1562253463.3-214622150088155/source", "state": "file", "uid": 0 }
Verifizieren Sie die erfolgreiche Übertragung durch Überprüfung des Dateisystems. Die kopierte Datei sollte sich nun am angegebenen Zielpfad befinden.
[email protected]:/home/wdzwdz# ls Desktop/ nginx.yml
Erstellen Sie ein neues Verzeichnis, um im folgenden Befehl das Fetch-Modul zu verwenden.
[email protected]:/home/wdzwdz# mkdir example [email protected]:/home/wdzwdz# ls Desktop Documents example examples.desktop nginx_new.yml nginx.yml
Der folgende Ansible Ad-hoc-Befehl verwendet das `fetch`-Modul, um eine Datei von einem entfernten Host (hier `node1`) auf ein lokales Verzeichnis des Ansible-Knotens herunterzuladen.
[email protected]:/home/wdzwdz# ansible node1 -m fetch -a 'src=/etc/sudoers.d/nginx.yml dest=/home/wdzwdz/example/ flat=yes' node1 | SUCCESS => { "changed": false, "checksum": "5631822866afd5f19b928edb3ba018385df22dd3", "dest": "/home/wdzwdz/example/nginx.yml", "file": "/etc/sudoers.d/nginx.yml", "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634" }
Überprüfen Sie erneut die Existenz der Datei am angegebenen Zielort.
[email protected]:/home/wdzwdz# ls example nginx.yml
Pakete verwalten
Der nachfolgende Befehl installiert das Nginx-Paket auf einer Gruppe von Hosts (Client) mit Hilfe des `apt`-Moduls.
[email protected]:/home/wdzwdz# ansible Client -m apt -a 'name=nginx state=latest' --become node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "cache_update_time": 1562411227, "cache_updated": false, "changed": false }
Der nächste Befehl entfernt das Nginx-Paket von einer Hostgruppe (Client) unter Verwendung des `apt`-Moduls und löscht zudem alle zugehörigen Konfigurationen.
[email protected]:/home/wdzwdz# ansible Client -m apt -a 'name=nginx state=absent purge=yes' --become node1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "stderr": "", "stderr_lines": [], "stdout": "Reading package lists...nBuilding dependency tree...nReading state information...nThe following packages were automatically installed and are no longer required:n libnginx-mod-http-geoip libnginx-mod-http-image-filtern libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-streamn nginx-common nginx-corenUse 'sudo apt autoremove' to remove them.nThe following packages will be REMOVED:n nginx*n0 upgraded, 0 newly installed, 1 to remove and 241 not upgraded.nAfter this operation, 44.0 kB disk space will be freed.n(Reading database ... r(Reading database ... 5%r(Reading database ... 10%r(Reading database ... 15%r(Reading database ... 20%r(Reading database ... 25%r(Reading database ... 30%r(Reading database ... 35%r(Reading database ... 40%r(Reading database ... 45%r(Reading database ... 50%r(Reading database ... 55%r(Reading database ... 60%r(Reading database ... 65%r(Reading database ... 70%r(Reading database ... 75%r(Reading database ... 80%r(Reading database ... 85%r(Reading database ... 90%r(Reading database ... 95%r(Reading database ... 100%r(Reading database ... 180191 files and directories currently installed.)rnRemoving nginx (1.15.5-0ubuntu2.1) ...rn", "stdout_lines": [ "Reading package lists...", "Building dependency tree...", "Reading state information...", "The following packages were automatically installed and are no longer required:", " libnginx-mod-http-geoip libnginx-mod-http-image-filter", " libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream", " nginx-common nginx-core", "Use 'sudo apt autoremove' to remove them.", "The following packages will be REMOVED:", " nginx*", "0 upgraded, 0 newly installed, 1 to remove and 241 not upgraded.", "After this operation, 44.0 kB disk space will be freed.", "(Reading database ... ", "(Reading database ... 5%", "(Reading database ... 10%", "(Reading database ... 15%", "(Reading database ... 20%", "(Reading database ... 25%", "(Reading database ... 30%", "(Reading database ... 35%", "(Reading database ... 40%", "(Reading database ... 45%", "(Reading database ... 50%", "(Reading database ... 55%", "(Reading database ... 60%", "(Reading database ... 65%", "(Reading database ... 70%", "(Reading database ... 75%", "(Reading database ... 80%", "(Reading database ... 85%", "(Reading database ... 90%", "(Reading database ... 95%", "(Reading database ... 100%", "(Reading database ... 180191 files and directories currently installed.)", "Removing nginx (1.15.5-0ubuntu2.1) ..." ] }
Dienste verwalten
Der folgende Ansible Ad-hoc-Befehl nutzt das `service`-Modul, um den Nginx-Dienst auf dem Host zu starten. Der `state`-Wert sollte dann `started` lauten.
[email protected]:/home/wdzwdz# ansible Client -m service -a 'name=nginx state=started enabled=yes' --become node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "enabled": true, "name": "nginx", "state": "started", "status": { "ActiveEnterTimestamp": "Sat 2019-07-06 08:28:02 EDT", "ActiveEnterTimestampMonotonic": "31411371", "ActiveExitTimestampMonotonic": "0", "ActiveState": "active", "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target", "AllowIsolate": "no", "AmbientCapabilities": "", "AssertResult": "yes", "AssertTimestamp": "Sat 2019-07-06 08:27:59 EDT", "AssertTimestampMonotonic": "27694868", "Before": "multi-user.target shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "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": "yes", "ConditionTimestamp": "Sat 2019-07-06 08:27:59 EDT", "ConditionTimestampMonotonic": "27694867", "ConfigurationDirectoryMode": "0755", "Conflicts": "shutdown.target", "ControlGroup": "/system.slice/nginx.service", "ControlPID": "0", "ExecMainStartTimestamp": "Sat 2019-07-06 08:28:02 EDT", "ExecMainStartTimestampMonotonic": "31411353", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; -s reload ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStartPre": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -t -q -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/sbin/start-stop-daemon ; argv[]=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid ; ignore_errors=yes ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/lib/systemd/system/nginx.service", "GID": "[not set]", "GuessMainPID": "yes", "IOAccounting": "no", "IOSchedulingClass": "0", "IOSchedulingPriority": "0", "IOWeight": "[not set]", } }
Um den Nginx-Dienst zu stoppen, führen Sie den folgenden Befehl aus, wodurch der `state`-Wert sich in `stopped` ändert.
[email protected]:/home/wdzwdz# ansible Client -m service -a 'name=nginx state=stopped' --become node1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "nginx", "state": "stopped", "status": { "ActiveEnterTimestamp": "Sat 2019-07-06 08:28:02 EDT", "ActiveEnterTimestampMonotonic": "31411371", "ActiveExitTimestampMonotonic": "0", "ActiveState": "active", "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target", "AllowIsolate": "no", "AmbientCapabilities": "", "AssertResult": "yes", "AssertTimestamp": "Sat 2019-07-06 08:27:59 EDT", "AssertTimestampMonotonic": "27694868", "Before": "multi-user.target shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CanReload": "yes", "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": "yes", "ConditionTimestamp": "Sat 2019-07-06 08:27:59 EDT", "ConditionTimestampMonotonic": "27694867", "ConfigurationDirectoryMode": "0755", "Conflicts": "shutdown.target", "ControlGroup": "/system.slice/nginx.service", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "A high performance web server and a reverse proxy server", "DevicePolicy": "auto", "Documentation": "man:nginx(8)", "DynamicUser": "no", } }
Überprüfung des Systems
Der folgende Ansible Ad-hoc-Befehl führt ein Shell-Modul aus, um den verfügbaren Festplattenspeicher auf der Root-Partition zu prüfen.
[email protected]:/home/wdzwdz# ansible Client -m shell -a 'df -h /dev/sda2' --become node1 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on /dev/sda2 923M 113M 748M 14% /boot
Dieser Befehl verwendet das Shell-Modul, um die verfügbare Speicherkapazität (RAM) auf dem Host zu ermitteln.
[email protected]:/home/wdzwdz# ansible Client -m shell -a 'free -m' --become node1 | CHANGED | rc=0 >> total used free shared buff/cache available Mem: 5101 854 2760 27 1487 3947 Swap: 8581 0 8581
Dieser Befehl gibt die Betriebszeit jedes laufenden Servers aus.
[email protected]:/home/wdzwdz# ansible Client -a "uptime" node1 | CHANGED | rc=0 >> 11:31:17 up 1 day, 2:40, 2 users, load average: 0.23, 0.05, 0.02
Fakten sammeln
Der folgende Ansible Ad-hoc-Befehl gibt alle Systeminformationen und -variablen aus, die von Ansible gesammelt wurden.
[email protected]:/home/wdzwdz# ansible all -m setup node1 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.17.0.1", "10.0.2.15" ], "ansible_all_ipv6_addresses": [ "fe80::763e:c0b4:14df:b273" ], "ansible_apparmor": { "status": "enabled" }, "ansible_architecture": "x86_64", "ansible_bios_date": "12/01/2006", "ansible_bios_version": "VirtualBox", "ansible_cmdline": { "BOOT_IMAGE": "/vmlinuz-4.18.0-25-generic", "quiet": true, "ro": true, "root": "UUID=5f85d8b7-0ab2-48c9-9e6e-4ecfbcbdaa83", "splash": true }, "ansible_date_time": { "date": "2019-07-07", "day": "07", "epoch": "1562525628", "hour": "14", "iso8601": "2019-07-07T18:53:48Z", "iso8601_basic": "20190707T145348850596", "iso8601_basic_short": "20190707T145348", "iso8601_micro": "2019-07-07T18:53:48.850697Z", "minute": "53", "month": "07", "second": "48", "time": "14:53:48", "tz": "EDT", "tz_offset": "-0400", "weekday": "Sunday", "weekday_number": "0", "weeknumber": "26", "year": "2019" }, "ansible_default_ipv4": { "address": "10.0.2.15", "alias": "enp0s3", "broadcast": "10.0.2.255", "gateway": "10.0.2.2", "interface": "enp0s3", "macaddress": "08:00:27:68:64:9a", "mtu": 1500, "netmask": "255.255.255.0", "network": "10.0.2.0", "type": "ether" }, "ansible_default_ipv6": {}, "ansible_device_links": { "ids": { "sda": [ "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5" ], "sda1": [ "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part1" ], "sda2": [ "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part2" ], "sda3": [ "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part3" ], "sda4": [ "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part4" ], "sr0": [ "ata-VBOX_CD-ROM_VB2-01700376" ] }, "labels": { "sr0": [ "VBox_GAs_6.0.2" ] }, "masters": {}, "uuids": { "sda1": [ "5f85d8b7-0ab2-48c9-9e6e-4ecfbcbdaa83" ], "sda2": [ "b8b7f87b-c3bf-48ed-a44c-f9b3ce0afbe5" ], "sda3": [ "a6c77fa6-e292-4a0d-b21f-8804f1949bbd" ], "sda4": [ "8207f970-4d9a-47db-a5d5-f620e5b17b7b" ], "sr0": [ "2019-01-14-14-57-19-65" ] } }, "ansible_devices": { "loop0": { "holders": [], "host": "", "links": { "ids": [], "labels": [], "masters": [], "uuids": [] }, "model": null, "partitions": {}, "removable": "0", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "none", "sectors": "29704", "sectorsize": "512", "size": "14.50 MB", "support_discard": "4096", "vendor": null, "virtual": 1 }, "loop1": { "holders": [], "host": "", "links": { "ids": [], "labels": [], "masters": [], "uuids": [] }, "model": null, "partitions": {}, "removable": "0", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "none", "sectors": "0", "sectorsize": "512", "size": "0.00 Bytes", "support_discard": "4096", "vendor": null, "virtual": 1 }, }
Das war eine umfassende Einführung in die Verwendung von Ansible Ad-hoc-Befehlen. Nutzen Sie diese Befehle in Ihrer Ansible-Umgebung, um Module auszuführen, ohne vollständige Playbooks zu erstellen. Zögern Sie nicht, bei Fragen oder Problemen einen Kommentar zu hinterlassen.