Ansible Ad-hoc 命令指南及示例

在 Ansible 中,可以使用 Ad-hoc 命令来立即执行各项任务,而无需预先保存它们以供后续使用。本文将深入探讨 Ansible 的 Ad-hoc 命令。

在 Ansible 中,许多任务并不需要为此编写单独的 Ansible playbook。 您可以直接使用 Ansible ad-hoc 命令来执行这些任务。 这些命令是在目标主机上执行单个任务的单行命令,它们位于 `/usr/bin/ansible` 路径下。

诸如 ping 检查所有主机是否在线、复制文件、重启服务器、安装软件包等操作,都可以通过 Ansible Ad-hoc 命令轻松完成。 以下是一些您应该了解的基本 Ansible Ad-hoc 命令列表。

基本命令

以下 ad-hoc 命令将在清单文件中的所有主机上运行 ping 模块。其中,`-m` 参数用于指定模块。

    
      [email protected]:/home/techblik.com# ansible all -m ping
      node1 | SUCCESS => {
          "ansible_facts": {
              "discovered_interpreter_python": "/usr/bin/python"
          }, 
          "changed": false, 
          "ping": "pong"
      }
    
  

以下命令将在清单文件 `/etc/ansible/hosts` 中定义的 “Client” 主机组上运行 setup 模块。

    
      [email protected]:/home/techblik.com# 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
      }
    
  

以下命令演示了如何提示输入 SSH 密码进行身份验证。您需要在命令末尾添加 `–ask-pass` 选项。 运行此命令后,系统会要求您输入 SSH 密码。

    
      [email protected]:/home/techblik.com# ansible Client -m ping --ask-pass
      SSH password: 
      node1 | SUCCESS => {
          "ansible_facts": {
              "discovered_interpreter_python": "/usr/bin/python"
          }, 
          "changed": false, 
          "ping": "pong"
      }
    
  

以下命令展示了如何以具有 root 权限的非 root 用户身份运行 ad-hoc 命令。 `–become` 选项提供 root 权限,而 `-K` 选项则提示输入密码。

    
      [email protected]:/home/techblik.com# ansible Client -m shell -a 'fdisk -l' -u techblik.com --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


      Disk /dev/loop8: 4 MiB, 4218880 bytes, 8240 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
    
  

此 ad-hoc 命令使用 `-f` 选项重启系统,该选项用于定义 fork 的数量。

    
    [email protected]:/home/techblik.com# ansible Client -a "/sbin/reboot" -f 1
    
  

文件传输

以下 Ansible ad-hoc 命令用于将文件从源路径复制到清单文件中定义的目标主机组 (Client)。在输入密码后,如果文件成功复制到目标位置,输出结果中 `changed` 参数的值将为 `true`。

    
      [email protected]:/home/techblik.com# ansible Client -m copy -a 'src=/home/techblik.com/nginx.yml dest=/home/techblik.com/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/techblik.com/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
      }
    
  

运行以下命令以验证复制模块是否按预期工作。 复制的文件应该位于上一个命令中指定的目标路径下。

    
      [email protected]:/home/techblik.com# ls Desktop/

      nginx.yml
    
  

接下来,我将创建一个新目录来演示 fetch 模块。

    
      [email protected]:/home/techblik.com# mkdir example

      [email protected]:/home/techblik.com# ls

      Desktop Documents example examples.desktop nginx_new.yml nginx.yml
    
  

以下 Ansible ad-hoc 命令用于从命令中定义的主机下载文件。 在这个命令中,我们使用 fetch 模块将文件从 node1 服务器下载到 Ansible 控制节点上的本地目标路径。

    
      [email protected]:/home/techblik.com# ansible node1 -m fetch -a 'src=/etc/sudoers.d/nginx.yml dest=/home/techblik.com/example/ flat=yes'

      node1 | SUCCESS => {
        "changed": false,
        "checksum": "5631822866afd5f19b928edb3ba018385df22dd3",
        "dest": "/home/techblik.com/example/nginx.yml",
        "file": "/etc/sudoers.d/nginx.yml",
        "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634"
      }
    
  

检查文件是否已成功下载到命令中指定的目标路径。

    
      [email protected]:/home/techblik.com# ls example

      nginx.yml
    
  

管理软件包

以下命令展示了如何使用 apt 模块在一组主机 (Client) 上安装 nginx。

    
      [email protected]:/home/techblik.com# 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
      }
    
  

以下命令使用 apt 模块在一组主机 (Client) 上卸载 nginx,并清除所有相关配置。

    
      [email protected]:/home/techblik.com# 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) ..."
        ]
      }
    
  

管理服务

以下 Ansible ad-hoc 命令使用 service 模块在主机上启动 nginx 服务。 状态值应为 “started”。

    
      [email protected]:/home/techblik.com# 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]"
        }
      }
    
  

以下命令使用 service 模块来停止主机上的 nginx 服务。状态值更改为 “stopped”。

    
      [email protected]:/home/techblik.com# 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"
        }
      }
    
  

检查系统

以下 Ansible ad-hoc 命令运行 shell 模块,用于检查根分区的可用磁盘空间。

    
      [email protected]:/home/techblik.com# 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
    
  

以下命令运行 shell 模块来检查主机上的可用内存(RAM)。

    
      [email protected]:/home/techblik.com# 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
    
  

此命令检查每个正在运行的服务器的正常运行时间。

    
      [email protected]:/home/techblik.com# 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
    
  

收集信息

以下 Ansible ad-hoc 命令会为您提供系统的所有临时信息,包括系统中存在的所有变量。

    
      [email protected]:/home/techblik.com# 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
                  }
              }
          }
      }
    
  

以上就是关于 Ansible Ad-hoc 命令的全部内容。 请在您的 Ansible 环境中尝试这些命令。 使用这些命令来运行 Ansible 模块,而无需编写任何 Ansible playbook 即可执行这些任务。 如果您在运行这些命令时遇到任何问题,请随时发表评论。