매일 업데이트
2022-10-24 13:31 27 min

예제가 포함된 Ansible Ad-hoc 명령 가이드

Ansible Ad-hoc 명령의 활용

Ansible에서 임시 명령은 즉각적인 작업 수행에 사용되며, 추후 사용을 위한 저장 과정이 필요하지 않습니다. 이 문서에서는 Ansible Ad-hoc 명령에 대한 모든 정보를 제공합니다.

Ansible은 별도의 플레이북 작성 없이도 다양한 작업을 수행할 수 있게 해줍니다. 이러한 작업들은 임시 명령을 통해 간편하게 처리할 수 있습니다. 임시 명령은 대상 호스트에서 단일 작업을 실행하기 위한 한 줄 명령으로, 일반적으로 /usr/bin/ansible 경로에 위치합니다.

Ansible Ad-hoc 명령을 통해 모든 호스트의 활성 상태를 확인하는 ping 테스트, 파일 복사, 서버 재부팅, 패키지 설치 등 다양한 작업을 손쉽게 처리할 수 있습니다. 다음은 반드시 알아두어야 할 기본적인 Ansible Ad-hoc 명령 목록입니다.

기본 명령

아래의 임시 명령은 인벤토리 파일에 정의된 모든 호스트에서 ping 모듈을 실행합니다. 여기서 -m은 사용할 모듈을 지정하는 옵션입니다.

          [email protected]:/home/koreantech.org# 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/koreantech.org# 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/koreantech.org# ansible Client -m ping --ask-pass
          SSH password: 
          node1 | SUCCESS => {
              "ansible_facts": {
                  "discovered_interpreter_python": "/usr/bin/python"
              }, 
              "changed": false, 
              "ping": "pong"
          }
        

루트 권한이 필요한 작업을 실행할 때는 --become-K 옵션을 사용하여 비루트 사용자가 루트 권한으로 임시 명령을 실행할 수 있습니다. -K 옵션은 암호를 묻습니다.

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

시스템 재부팅 시에는 -f 옵션을 사용하여 포크 수를 정의할 수 있습니다.

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

파일 전송

아래의 임시 명령은 인벤토리 파일에 정의된 'Client' 그룹의 호스트에 파일을 복사하는 데 사용됩니다. 파일 복사가 완료되면 'change' 매개변수 값이 'true'로 변경됩니다.

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

          nginx.yml
        

다음으로 fetch 모듈을 사용하여 파일을 다운로드할 디렉토리를 생성합니다.

          [email protected]:/home/koreantech.org# mkdir example

          [email protected]:/home/koreantech.org# ls

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

fetch 모듈을 사용한 다음 임시 명령은 호스트에서 로컬 대상으로 파일을 다운로드합니다. 이 예에서는 'node1' 서버에서 '/etc/sudoers.d/nginx.yml' 파일을 로컬의 'example' 디렉토리로 다운로드합니다.

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

          node1 | SUCCESS => {

            "changed": false,

            "checksum": "5631822866afd5f19b928edb3ba018385df22dd3",

            "dest": "/home/koreantech.org/example/nginx.yml",

            "file": "/etc/sudoers.d/nginx.yml",

            "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634"

          }
        

다운로드한 파일이 지정된 대상 디렉토리에 있는지 확인합니다.

          [email protected]:/home/koreantech.org# ls example

          nginx.yml
        

패키지 관리

아래 명령은 apt 모듈을 사용하여 'Client' 호스트 그룹에 nginx를 설치합니다.

          [email protected]:/home/koreantech.org# 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/koreantech.org# 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) ..."

            ]

          }
        

서비스 관리

아래 임시 명령은 service 모듈을 사용하여 호스트에서 nginx 서비스를 시작합니다. 서비스 상태 값이 'started'로 변경됩니다.

          [email protected]:/home/koreantech.org# 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]",

            }

          }
        

다음 명령은 호스트에서 nginx 서비스를 중지합니다. 서비스 상태 값이 'stopped'로 변경됩니다.

          [email protected]:/home/koreantech.org# 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",

            }

          }
        

시스템 확인

아래 임시 명령은 shell 모듈을 사용하여 루트 파티션에서 사용 가능한 디스크 공간을 확인합니다.

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

수집 사실

아래의 임시 명령은 시스템의 모든 변수를 포함하여 시스템의 모든 정보를 제공합니다.

          [email protected]:/home/koreantech.org# 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
저자
Korea

기술 트렌드와 실용적인 팁을 전하는 लेखक입니다.